2012-01-02 135 views

回答

22

按照SQL標準,外鍵必須引用父表或父表的唯一鍵。如果主鍵具有多列,則外鍵必須具有相同的列號和順序。因此,外鍵引用了父表中的唯一行;不能有重複。


回覆您的評論:

如果T.A是主鍵,然後不,你不能有任何重複。任何主鍵必須是唯一的且非空的。因此,如果子表具有引用父主鍵的外鍵,則它必須匹配非空的唯一值,因此在父表中引用恰好一行。在這種情況下,您不能創建引用多個父行的子行。

可以創建一個子行,其外鍵列是NULL,在這種情況下,它引用父表中沒有行。

+0

謝謝,但是如果我們談論單列外鍵,例如列'a'是在父表T中引用列'A'的子表t中的foriegn鍵,那麼現在在列A可能有任何情況下是不可能的表T中的重複值?這是否意味着外鍵薄霧alays引用另一個表中的主鍵? – ratsy 2012-01-02 22:58:57

+1

@ratsy:外鍵必須始終引用一個或多個聲明爲PRIMARY KEY或UNIQUE的列。 (除非你使用的是MySQL,但是你仍然應該只針對PRIMARY KEY或者UNIQUE列,即使在MySQL中也是如此。 HTML爲「系統沒有強制要求所引用的列是UNIQUE」) – 2012-01-02 23:37:04

+0

@Catcall:是的,但@ratsy標記了這個問題'oracle',所以我沒有提到InnoDB的非標準行爲。即使在使用InnoDB時,我也強烈建議不要引用非唯一的父行,因爲這樣很容易混淆。 – 2012-01-02 23:46:39

6

不,這是不可能的。

當您在表上定義外鍵約束時,意味着外表上只有一個對應的鍵。如果在外表上存在多個,那麼這意味着什麼?

維基百科對Foreign key進入這樣的定義:

外鍵是在符合另一個表的候選鍵關係表中的字段

候選鍵是一個表中是唯一的。

+0

感謝您的幫助.. – ratsy 2012-01-03 21:28:29

7

是的,外鍵可以引用具有重複值的列。

如果主鍵使用非唯一索引並且在創建時未驗證,則會發生這種情況。 (不過,我從來沒有見過像這樣在現實生活中的情況。作爲@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); 
+0

古奇。在「你爲什麼要這樣做?」的範疇下:-)但是,謝謝你的明確例子! – 2012-01-03 00:12:24

+0

感謝Jonearles上面的例子!....在使用數據庫的情況相同,但是爲什麼&how ..? – ratsy 2012-01-03 21:40:40

+0

對主鍵使用非唯一索引有幾個很好的理由;可延遲約束,更多重建選項(特別是並行性),索引在約束之前存在等。在此查看有關唯一索引與非唯一索引的信息:http://richardfoote.wordpress.com/2008/06/04/primary -keys-and-non-unique-indexes-whats-really-occurrence/ NOVALIDATE有點奇怪。據我所知,使用它沒有優勢,除非你只需要有一些「壞」的數據。這些案件真的應該記錄在案。如果沒有記錄,也許這只是一個錯誤? – 2012-01-04 06:49:29

相關問題