web-dev-qa-db-fra.com

la clé étrangère fait-elle toujours référence à une clé unique dans une autre table?

N'est-il pas possible que la clé étrangère (colonne unique) dans une table enfant fasse référence à une clé parent qui a des valeurs en double?

23
ratsy

Selon la norme SQL, une clé étrangère doit faire référence à la clé primaire ou à une clé unique de la table parent. Si la clé primaire a plusieurs colonnes, la clé étrangère doit avoir le même nombre et le même ordre de colonnes. Par conséquent, la clé étrangère fait référence à une ligne unique dans la table parent; il ne peut y avoir de doublons.


Re votre commentaire:

Si T.A est une clé primaire, alors non, vous ne pouvez pas avoir de doublons. Toute clé primaire doit être unique et non nulle. Par conséquent, si la table enfant possède une clé étrangère faisant référence à la clé primaire du parent, elle doit correspondre à une valeur unique non nulle et fait donc référence exactement à une ligne de la table parent. Dans ce cas, vous ne pouvez pas créer une ligne enfant faisant référence à plusieurs lignes parent.

Vous pouvez créez une ligne enfant dont la colonne de clé étrangère est NULL, auquel cas elle ne fait référence à aucune ligne de la table parent.

25
Bill Karwin

Non ce n'est pas possible.

Lorsque vous définissez une contrainte de clé étrangère sur une table, cela signifie qu'il n'y a qu'une seule clé correspondante sur la table étrangère. S'il existait des multiples sur la table étrangère, lequel serait-il?

Wikipédia a cette définition sur l'entrée clé étrangère :

Une clé étrangère est un champ d'une table relationnelle qui correspond à une clé candidate d'une autre table

Les clés candidates sont uniques dans une table.

8
Oded

Oui, il est possible pour une clé étrangère de référencer une colonne avec des valeurs en double.

Cela peut se produire si la clé primaire utilise un index non unique et n'est pas validée lors de sa création. (Mais je n'ai jamais vu une telle situation dans la vraie vie. Comme l'a souligné @Bill Karwin, ce serait très déroutant. Donc, ce n'est peut-être pas une situation dont vous devez vraiment vous inquiéter.)

--Create a table with two duplicate rows
create table test1(a number);
insert into test1 values(1);
insert into test1 values(1);
commit;

--Create a non-unique index
create index test1_index on test1(a);

--Use the non-unique index for the primary key, do not validate
alter table test1 add constraint test1_pk primary key (a)
    using index test1_index novalidate;

--Build another table with a foreign key to TABLE1
create table test2(a number,
    constraint test2_fk foreign key (a) references test1(a));

--Inserting a value that refers to the duplicate value still works.
insert into test2 values(1);
commit;

--The foreign key still works:
--ORA-02291: integrity constraint (TEST2_FK) violated - parent key not found
insert into test2 values(2);

--The primary key works as expected, but only for new values:
--ORA-00001: unique constraint (TEST1_PK) violated
insert into test1 values(1);
7
Jon Heller