primary / foreign keys - SQL/NoSQL - Programmation
Marsh Posté le 03-07-2006 à 11:45:20
Juste petit exemple pour illustrer ce que je viens de dire et expliciter mon PB :
Soit 2 tables :
Livre(livreId, resumeid)
resume(resumeid, resumeTxt)
resumeid dans livre est une foreign key, si je supprime mon livre, mon resume n'est pas supprime dans e table resume.
Dois-je le mettre dans la primary key pour pouvoir faire cette action??
Marsh Posté le 03-07-2006 à 11:50:46
si un résumé est propre à un livre, alors il faut que la table Livre contienne un champ pour le résumé. C'est beaucoup plus logique.
Livre(LivreId, resumeTxt)
Si par contre (et la j'en doute un peu), un résumé peut appartenir à plusieurs livres (bizzare comme truc), alors il te faut une table supplémentaire.
Livre (livreId, resumeId)
Resume(resumeid, resumeTxt)
ou livreId est une PK dans livre
ou resumeid est une PK dans Resume
dans ce cas, livre possède une FK qui est donc resumeId...
Si tu veux que le résumé se supprime dés que tu supprimes le livre (à prendre avec des pincettes) alors il faut faire un cascade constraint dans la foreign key du résumé... Mais bon c'est dangereux, surtout dans le cas ou tu as deux livres qui référencie le même résumé. Tu risque d'avoir une erreur à la suppression.
Mais bon je reste convaincu que mettre le résumé directement dans le livre est la meilleure solution... Mais tout dépend le contexte
Marsh Posté le 03-07-2006 à 12:02:13
J'ai sans doute mal compris le fonctionnenement des delete on cascade alors. Car je pensais que déclarer resumeId en foreign key dans la table livre, avec un delete on cascade impliquait que la suppression d'un resume engendrait la suppression du livre, ce qui n'est pas l'effet recherché.
Marsh Posté le 03-07-2006 à 12:21:58
non c'est le contraire que tu veux
si tu supprimes un livre, tu veux supprimer le résumé? c'est bien ça? Met alors un DELETE cascade sur la FK de la table livre qui pointe vers resumes.
Marsh Posté le 03-07-2006 à 12:26:44
non non, c'est bien le contraire qui se passe :
si tu essayes le code ci-dessous tu veras:
create table c (idc int primary key, val varchar(20));
insert into c values (1, 'premier');
insert into c values (2, 'second');
select * from c;
create table d (idd int primary key, idc int references c on delete cascade);
insert into d values (10,1);
insert into d values (11,2);
select * from c;
-- on supprime dans d comme d'habitude
delete from d where idd = 10;
select * from c;
select * from d;
-- mais quand on supprime dans c, les enregistrements liés dans d sont
-- supprimés
insert into d values (10,1);
delete from c where idc = 1;
select * from c;
select * from d;
Marsh Posté le 03-07-2006 à 11:20:32
Si j'ai bien compris. Quand on déclare une clé primaire, les modifications apportés aux objets référencés dans les autres tables n'ont aucune influence sur la table qui contiet la clé primaire.
Si je me trouves dans le cas où le lien est bidirectionnel, dois-je déclarer 2 clé primaires et 2 clé étrangères??