insertion donnée dans champs cles etrangère

insertion donnée dans champs cles etrangère - SQL/NoSQL - Programmation

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

Reply

Marsh Posté le 06-08-2007 à 12:29:43   

Reply

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


---------------
The Rom's, à votre service
Reply

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

Reply

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 ...


---------------
The Rom's, à votre service
Reply

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

Reply

Marsh Posté le 06-08-2007 à 21:01:08    

Ben un exemple alors :

table user
user_id    login    password
1          paul     yop
2          marc     yap
 
table contact
contact_id user_id email
1          1       email1@yop.yop
2          1       email2@yop.yop
3          2       email1@yap.yap
 
Tu crée une nouvelle entrée (= tu ajoutes) [jean,yip] à la table user, ça va à priori te retourner comme dernier ID "user_id" la valeur 3 et tu auras cela dans la table user :
user_id    login    password
1          paul     yop
2          marc     yap
3          jean     yip
 
- Là, soit tu crée une nouvelle entrée dans la table contact, par ex [3,email1@yip.yip] et tu auras alors ceci dans la table contact :
contact_id   user_id   email
1            1         email1@yop.yop
2            1         email2@yop.yop
3            2         email1@yap.yap
4            3         email1@yip.yip
 
- Soit tu décide d'updater (= mettre à jour en anglais) une entrée existante dans la table contact, genre attribuer l'email email2@yop.yop à jean pour avoir finalement :
contact_id   user_id   email
1            1         email1@yop.yop
2            3         email2@yop.yop
3            2         email1@yap.yap
 
Mais comme tu t'en doutes, ça parait particulièrement improbable d'avoir ce genre de besoins ; dans cet exemple, c'est même parfaitement stupide ...
 
Le seul cas où tu peux avoir besoin d'un update automatique dans la seconde table c'est lorsque tu changes l'ID dans la première. C'est automatique avec une condition "ON UPDATE CASCADE" quand tu crée ta contrainte de clé étrangère
 
Par ex, si on change l'ID de paul pour la remplacer par 6 tu auras ceci :
user_id    login    password
6          paul     yop
2          marc     yap
3          jean     yip
 
contact_id   user_id   email
1            6         email1@yop.yop
2            6         email2@yop.yop
3            2         email1@yap.yap
4            3         email1@yip.yip
 
Mais c'est à priori inutile car une clé primaire est
- unique donc tu n'as pas besoin de la changer pour la différencier d'une autre.
- uniquement destinée à identifier une entrée, c'est à dire ne pa contenir une information qui doit être affichée ou peut nécessiter une modification

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 ???


---------------
The Rom's, à votre service
Reply

Marsh Posté le 06-08-2007 à 21:38:12    

TheRom_S a écrit :

Ben un exemple alors :

table user
user_id    login    password
1          paul     yop
2          marc     yap
 
table contact
contact_id user_id email
1          1       email1@yop.yop
2          1       email2@yop.yop
3          2       email1@yap.yap
 
Tu crée une nouvelle entrée (= tu ajoutes) [jean,yip] à la table user, ça va à priori te retourner comme dernier ID "user_id" la valeur 3 et tu auras cela dans la table user :
user_id    login    password
1          paul     yop
2          marc     yap
3          jean     yip
 
- Là, soit tu crée une nouvelle entrée dans la table contact, par ex [3,email1@yip.yip] et tu auras alors ceci dans la table contact :
contact_id   user_id   email
1            1         email1@yop.yop
2            1         email2@yop.yop
3            2         email1@yap.yap
4            3         email1@yip.yip
 
- Soit tu décide d'updater (= mettre à jour en anglais) une entrée existante dans la table contact, genre attribuer l'email email2@yop.yop à jean pour avoir finalement :
contact_id   user_id   email
1            1         email1@yop.yop
2            3         email2@yop.yop
3            2         email1@yap.yap
 
Mais comme tu t'en doutes, ça parait particulièrement improbable d'avoir ce genre de besoins ; dans cet exemple, c'est même parfaitement stupide ...
 
Le seul cas où tu peux avoir besoin d'un update automatique dans la seconde table c'est lorsque tu changes l'ID dans la première. C'est automatique avec une condition "ON UPDATE CASCADE" quand tu crée ta contrainte de clé étrangère
 
Par ex, si on change l'ID de paul pour la remplacer par 6 tu auras ceci :
user_id    login    password
6          paul     yop
2          marc     yap
3          jean     yip
 
contact_id   user_id   email
1            6         email1@yop.yop
2            6         email2@yop.yop
3            2         email1@yap.yap
4            3         email1@yip.yip
 
Mais c'est à priori inutile car une clé primaire est
- unique donc tu n'as pas besoin de la changer pour la différencier d'une autre.
- uniquement destinée à identifier une entrée, c'est à dire ne pa contenir une information qui doit être affichée ou peut nécessiter une modification

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 ???


 
 
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  

Reply

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


---------------
The Rom's, à votre service
Reply

Marsh Posté le 06-08-2007 à 22:42:21    

TheRom_S a écrit :

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


 
 
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.
 
 
 
 
 

Reply

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 ...


---------------
The Rom's, à votre service
Reply

Marsh Posté le 06-08-2007 à 23:24:38   

Reply

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 :
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 ...


 
 
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.
 
 
 

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed