всегда ли внешний ключ ссылается на уникальный ключ в другой таблице? - PullRequest
21 голосов
/ 03 января 2012

Возможно ли, что внешний ключ (один столбец) в дочерней таблице ссылается на родительский ключ, имеющий несколько повторяющихся значений?

Ответы [ 3 ]

24 голосов
/ 03 января 2012

По стандарту SQL внешний ключ должен ссылаться либо на первичный ключ, либо на уникальный ключ родительской таблицы. Если первичный ключ имеет несколько столбцов, внешний ключ должен иметь одинаковое количество и порядок столбцов. Поэтому внешний ключ ссылается на уникальную строку в родительской таблице; дубликатов быть не может.


Ваш комментарий:

Если T.A - первичный ключ, то нет, у вас не может быть дубликатов. Любой первичный ключ должен быть уникальным и ненулевым. Поэтому, если дочерняя таблица имеет внешний ключ, ссылающийся на первичный ключ родителя, она должна соответствовать непустому, уникальному значению и поэтому ссылается ровно на одну строку в родительской таблице. В этом случае вы не можете создать дочернюю строку, которая ссылается на несколько родительских строк.

Вы можете создать дочернюю строку, столбец внешнего ключа которой равен NULL, и в этом случае она не ссылается на строку в родительской таблице.

7 голосов
/ 03 января 2012

Да, внешний ключ может ссылаться на столбец с повторяющимися значениями.

Это может произойти, если первичный ключ использует неуникальный индекс и не проверяется при его создании.(Но я никогда не видел подобной ситуации в реальной жизни. Как отметил @ Билл Карвин, это было бы очень запутанно. Поэтому, возможно, это не та ситуация, о которой вам действительно нужно беспокоиться.)

--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 голосов
/ 03 января 2012

Нет, это невозможно.

Когда вы определяете ограничение внешнего ключа для таблицы, это означает, что в внешней таблице имеется только один соответствующий ключ.Если бы во внешней таблице существовали кратные значения, какую из них можно было бы определить?

В Википедии есть это определение для записи Внешний ключ :

Внешний ключ - это полев реляционной таблице, которая соответствует ключу-кандидату другой таблицы

Ключи-кандидаты уникальны в таблице.

...