2016-07-10 25 views
1

我有3個表:一個外鍵引用多個唯一鍵

class_a

 CREATE TABLE class_a (
     id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, 
     std_id INT NOT NULL UNIQUE, 
     name varchar(225) NOT NULL) 

class_b

 CREATE TABLE class_b (
     id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, 
     std_id INT NOT NULL UNIQUE, 
     name varchar(225) NOT NULL) 

sn_number

 CREATE TABLE sn_number (
     id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, 
     pin INT NOT NULL UNIQUE, 
     serial VARCHAR(255) NOT NULL UNIQUE, 
     std_id INT NULL DEFAULT NULL, 
     FOREIGN KEY(std_id) REFERENCES class_a(std_id) 
     ) 

我如何引用獨特std_idclass_aclass_b表中作爲外鍵在sn_number表中。

我想實現像ALTER TABLE sn_number ADD FOREIGN KEY(std_id) REFERENCES class_a(std_id), class_b(std_id)

我試圖這樣做ALTER TABLE sn_number ADD FOREIGN KEY(std_id) REFERENCES class_a(std_id)

其次

ALTER TABLE sn_number ADD FOREIGN KEY(std_id) REFERENCES class_b(std_id)sn_number表,但會繼續互相覆蓋。

我已閱讀這些: Foreign Key Referencing Multiple Tables

Composite key as foreign key (sql) 但我不能找到解決問題的辦法時遇到。

+0

有這個問題是提示你,你有一個數據庫設計的錯誤。一個班不是學生。所以你通常不會引用類表的std_id,而是引用學生表。你應該考慮爲什麼你有兩個類表,因爲當你想要連接時,你可能會遇到同樣的問題。老師或房間上課。基本上:存在類。有學生。存在sn_numbers。每個表都有一個表格,並鏈接它們(如果你願意,你可以從字面上繪製它們並用線條連接它們)。如果您需要專業化,您可以稍後添加它們。 – Solarflare

+0

謝謝。這真的幫了我很多。 – Abk

+0

@ Abk與@Solarflare&另一個答案的評論相反,您需要來自同一個表和列列表的兩個外鍵不是不良設計的症狀。 (雖然你的設計很差)。對於你的代碼的問題,請參閱我的答案。 – philipxy

回答

1

外鍵只能引用一個父表。這是SQL語法和關係理論的基礎。

你可以做什麼,是添加另一個表classesstudents包含所有std_id,那麼就引用FK它。

+0

不,你可以聲明任意數量的約束,但每個約束名稱只能有一個 – philipxy

0

由於您的FOREIGN KEY聲明中沒有明確給出約束條件名稱,因此DBMS將使用表名稱sn_number。您的問題是,您因此每次隱式聲明相同的約束名稱,因此名稱的舊信息丟失。僅對錶&列列表REFERENCES列表&列列表的不同情況使用不同的顯式約束名稱。

CONSTRAINT fk_sn_number_a FOREIGN KEY(std_id) REFERENCES class_a(std_id) 
CONSTRAINT fk_sn_number_b FOREIGN KEY(std_id) REFERENCES class_b(std_id) 

只要瞭解Using FOREIGN KEY Constraints的基礎知識。

PS正如在評論中指出的那樣,這是一個糟糕的設計。但與&的評論相反,另一個答案是,您需要來自同一個表&列表的兩個外鍵不是設計不佳的症狀。但是請注意,人們通常在可疑設計中使用「外鍵引用多表」時遇到的問題是,他們認爲他們的表格在設計時需要從一個地方到另外兩個地方的外鍵,而不是這樣。這樣的設計甚至不涉及外鍵,它只是涉及讓人想起外鍵

+0

你或我拿不到他的桌子 - 我理解如下:一些學生在課堂a,一些在課堂b,大多數在sn_number,所以他試圖創建一個完整的學生列表作爲類表的聯合的參考。這不是SQL的工作原理,你不能用這種外鍵來實現這一點。因此,最基本的想法是:學生證是指一張學生表(可能是間接的關鍵人選)。有理由使用你的構造(因此「提示」而不是「這總是錯誤的」),但對於初學者來說沒有。你在技術上可以做到這並不意味着它是有道理的。 – Solarflare

+0

我剛剛爲Abk可能意味着的各種事情添加了一條評論。 Re「大部分都在sn_number中」你是不是指所有*他們?重新「學生ID是指學生表」我同意可能是他們想要的,使用sn_number作爲「學生表」,但然後FKs走另一條路,sn_number必須不是NULL。 Re「沒有意義」如果nr_number id確定班級中的學生可用的儲物櫃,它會這樣做。 – philipxy

+0

我的評論主要是針對他作爲補充說明。我120%確定你知道外鍵是如何工作的,我可能在前8個單詞後停下來,你會知道我想說什麼。除了「全部」 - 我實際上是指「最多」,以防萬一這個引用是按照他所描述的方向(因爲sn_number可能或可能不是缺少的學生表)。我的意思是,使用所有技術可能的方法「沒有意義」。在未來3年他不需要雙重外鍵,如果他這樣做,我很確定它可以以另一種方式實施。 – Solarflare