web-dev-qa-db-ja.com

外部キーは常に別のテーブルの一意のキーを参照しますか?

子テーブルの外部キー(単一列)が、重複する値を持つ親キーを参照することは不可能ですか?

23
ratsy

SQL標準では、外部キーは親テーブルの主キーまたは一意キーを参照する必要があります。主キーに複数の列がある場合、外部キーの列の数と順序は同じでなければなりません。したがって、外部キーは親テーブルの一意の行を参照します。重複はありません。


あなたのコメントを再:

T.Aは主キーなので、重複することはできません。主キーは一意であり、null以外である必要があります。したがって、子テーブルに親の主キーを参照する外部キーがある場合、それはnull以外の一意の値と一致する必要があるため、親テーブルの1つの行を正確に参照します。この場合、複数の親行を参照する子行を作成することはできません。

can外部キー列がNULLである子行を作成します。この場合、親テーブルの行は参照されません。

25
Bill Karwin

いいえ、できません。

テーブルに外部キー制約を定義する場合、外部テーブルには対応するキーが1つしかないことを意味します。外部テーブルに複数が存在する場合、どれが意味されますか?

ウィキペディアには、この定義が Foreign key エントリにあります。

外部キーは、別のテーブルの候補キーと一致するリレーショナルテーブルのフィールドです

候補キーはテーブル内で一意です。

8
Oded

はい、外部キーが重複する値を持つ列を参照する可能性があります。

これは、主キーが一意でないインデックスを使用し、作成時に検証されない場合に発生する可能性があります。 (しかし、私はこのような状況を実際に見たことがありません。@ Bill Karwinが指摘したように、それは非常に混乱するでしょう。したがって、これは本当に心配する必要がある状況ではないかもしれません。)

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