insertion donnée dans champs cles etrangère - SQL/NoSQL - Programmation
Marsh Posté le 06-08-2007 à 13:16:07
Ben c'est lors de l'insertion dans la deuxième table que tu devras donner la clé qui référence la première table.
Lors d'un update ou d'un delete dans la première table d'une ligne référencée dans la seconde, tu peux ajouter des contraintes. ("on update" et "on delete" )
La syntaxe MySQL pour une clé étrangère :
[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...)
REFERENCES tbl_name (index_col_name, ...)
[ON DELETE {CASCADE | SET NULL | NO ACTION | RESTRICT}]
[ON UPDATE {CASCADE | SET NULL | NO ACTION | RESTRICT}]
Tu vois d'ailleurs que tu peux avoir une clé étrangère regroupée sur plusieurs champs
Marsh Posté le 06-08-2007 à 13:27:32
je viens enfin de mettre l'option on update, mais je pensais que ma cles etrangère aller pouvoir récupérer automatiquement la valeur de la cles primaire.
Ma cles primaire s'auto incrémente lors d'un insetion dans la base,et j'aimerais recupérer cette valeur dans ma cles étrangère
Marsh Posté le 06-08-2007 à 17:52:28
Généralement tu peux utiliser une fonction spéciale qui retourne l'ID de la dernière clé primaire générée lors d'un insert. Cette fonction n'est pas la même pour chaque sgbd mais si tu utilise un bon wrapper sql, tu pourras utiliser ce genre de fonction.
Après, soit tu crée une nouvelle entrée dans la seconde table avec cette ID comme clé étrangère, soit tu update une entrée existante avec la nouvelle valeur de l'ID bien que je ne vois pas du tout l'intérêt, ça va à l'encontre du principe et de l'utilité des clés étrangères ...
Marsh Posté le 06-08-2007 à 19:08:15
TheRom_S a écrit : soit tu update une entrée existante avec la nouvelle valeur de l'ID bien que je ne vois pas du tout l'intérêt, ça va à l'encontre du principe et de l'utilité des clés étrangères ... |
que veux tu dire par update une entrée existente
Marsh Posté le 06-08-2007 à 21:01:08
Ben un exemple alors :
table user |
Comme dans l'exemple que je viens de donner, une clé étrangère ne sert qu'à faire un lien entre 2 tables, ici pour dire à quel "user" correspond tel "contact" et non pas l'inverse : à quel "contcat" correspond tel "user". Car comme tu peux le voir dans cet exemple particulier, paul a 2 emails dans la base.
Voilà j'espère que c'est plus clair car tu semble d'après ton premier post comprendre les choses à l'envers.
Pour finir, non, quand tu insère l'entrée de jean, le programme va pas deviner tout seul qu'il a un email1@yip.yip si tu lui dit pas toi même et que tu fais pas la relation toi-même, sinon comment pourrait-il savoir que ce nouvel email que tu rentres correspond à jean et n'est pas le troisième compte mail de paul ???
Marsh Posté le 06-08-2007 à 21:38:12
TheRom_S a écrit : Ben un exemple alors :
Comme dans l'exemple que je viens de donner, une clé étrangère ne sert qu'à faire un lien entre 2 tables, ici pour dire à quel "user" correspond tel "contact" et non pas l'inverse : à quel "contcat" correspond tel "user". Car comme tu peux le voir dans cet exemple particulier, paul a 2 emails dans la base. |
disons que c'est un peu la confusion car je travail très rarement sur les BDD.
donc si on tiens pas compte de mon id en auto incrementation.
user_id (pk) nom prenom
1 paul X
2 marc Y
user_id (fk) login password
1 paul yop
2 marc yap
Dans ce cas la l'id_user tu est bien obligé de l' inserrer la première fois dans la première table en tant que pk et la dans la deuxième fois en tant que FK, dans ce cas il y a pas d'update automatique
Marsh Posté le 06-08-2007 à 22:07:15
A la création, il faut créer les 2, toujours.
Par contre je vois que dans ta seconde table, tu n'as qu'une seule clé qui est étrangère. C'est faisable mais pas très propre.
La raison est la suivante : il y a 2 cas possibles
- Soit, pour 1 enregistrement (= une entrée = une ligne) dans ta première table correspond 1 seul enregistrement dans la seconde et inversement. On parle de relation 1:1 et on considère généralement qu'il est plus efficace de concaténer les deux tables en une seule. Dans ton exemple, tu pourrais avoir ceci :
table user
------------
user_id (pk)
nom
prenom
login
password
------------
- Soit la relation n'est pas 1:1 mais 1:N (un sens ou l'autre). Dans ce cas, on utilise dans la seconde table une clé primaire qui est unique pour chaque enregistrement + une clé étrangère qui référence la première table. Si tu regardes mon exemple, c'est le cas dans la table contact car paul a 2 emails qui doivent avoir chacun leur clé primaire dans la table contact et une référence vers le même paul de la table user. Dans ton exemple, si un couple (nom/prénom) peut avoir plusieurs comptes donc correspondre à plusieurs couples (login/password), il faut ajouter une clé primaire différente comme ceci :
table user
------------
user_id (pk)
nom
prenom
------------
table account
------------
account_id (pk)
user_id (fk)
login
password
------------
Un cas supplémentaire, les relation N:N ; il y a plusieurs manières de représenter la relation dans les tables, par exemple tu gardes les 2 tables de bases avec uniquement des clés primaires et tu ajoutes une table qui recense les associations entre les deux avec
- soit 1 clé primaire spécifique à cette table et 2 clés étrangères référençant les 2 premières tables
- soit les 2 clés étrangères en considérant le couple (FK1, FK2) comme clé primaire (à vérifier). On peut utiliser des couples de champs pour créer
- une clé unique (par ex, pour 2 champs, le couple ("a","b" ) sera unique et ne pourra apparaître que dans un seul enregistrement) ;
- une clé étrangère qui référence 2 clés qui sont déja étrangères dans une autre table ;
A vérifier
- une clé étrangère qui référence un couple de deux clé primaires sur deux tables différentes ;
- une clé étrangère qui référence une clé primaire constituée par un couple de champs dans une seule table ;
- une clé primaire constituée par 2 champs
Il n'y a pas que les couples de champs qui peuvent être utilisés comme clés, ça marche avec N champs
Marsh Posté le 06-08-2007 à 22:42:21
TheRom_S a écrit : A la création, il faut créer les 2, toujours. |
en effet dans mon exemple j'ai un peu simplifier et pas mis ma deuxième cles etrangere
user_id (pk) nom prenom login(fk)
1 paul X paul
2 marc Y marc
user_id (fk) login(pk) password
1 paul yop
2 marc yap
il me semblait que dans une relation 1:1 les cles primaire deviennent cles Fk de la table reférencé
en faite j'ai 3 tables de ce type de relation 1:1, au lieu d'une, afin de mettre un peu en pratique certaines chose qui paraissent simple sur papier mais en pratique cela n'est pas toujours le cas.
exemple est ce que si ta pk a une contrainte unique et not null est ce que la cette même cles etrangère de la table référenré à les même conraintes not null et unique.
Marsh Posté le 06-08-2007 à 23:24:38
pour les relations 1:1, tu peux faire comme tu veux mais c'est moins propre, je dis pas que je fais toujours du propre non plus. Faire du propre c'est contraindre la structure de la BD pour que le prog externe qui y accède ne fasse pas de bêtise. Tu peux imaginer que tu ait rempli ta base de travers avec ton prog et arriver à ce résultat :
user_id (pk) nom prenom login(fk)
1 paul X paul
2 marc Y marc
user_id (fk) login(pk) password
2 paul yop
1 marc yap
Du coup tu te retrouve avec une boucle sur les références qui te donne des erreurs.
Sinon, une clé primaire est toujours unique et not null;
Une clé étrangère peut ne pas être unique (cas des 2 mails de paul dans mon exemple)
Une clé étrangère peut être "null" si tu n'as pas besoin de référencer une autre table pendant un temps. D'où la clause "ON [UPDATE/DELETE] SET NULL"
Par ex, une table user avec un user_id en PK et un ban_user_id en FK (en référence à un autre user_id de la même table) pouvant être "null" qui contient une valeur seulement quand le user est banni sur un forum ...
Marsh Posté le 07-08-2007 à 07:45:12
TheRom_S a écrit : pour les relations 1:1, tu peux faire comme tu veux mais c'est moins propre, je dis pas que je fais toujours du propre non plus. Faire du propre c'est contraindre la structure de la BD pour que le prog externe qui y accède ne fasse pas de bêtise. Tu peux imaginer que tu ait rempli ta base de travers avec ton prog et arriver à ce résultat : |
ok!! je vois donc si je comprend bien le user_id(fk) s'il est not null et unique dans la deuxième table il doit être egalement unique t et not null si on veux que ces table soit lié.
moi je voulais faire une 3 tables
user : id_user, nom, prenom etc
profil : profil login password
cotisation : licence , mt payé, date_debut , date _fin
comme dit c'est 3 tables ont des relations de 1:1. mais en pensant ce que tu a s dis je pourrais enventuellement
passer la relation user-profil en 1:n et la garder la relation user-cotisation en 1:1 , la fusionner pour n'avoir qu'une table user et profil.
Marsh Posté le 06-08-2007 à 12:29:43
Bonjour,
j'aimerais avoir une précision je suis en train monté une petite base de donnée pour un site web avec dans une première table une cles primaire qui est cles FOREIGH KEY dans la deuxième table.
Est ce lors de l'insertion du champs cles primaire est ce que la cles etrangère se metra à jour dans la 2ème table ou faut il faire une insertion dans chaque table.
merci