2010-08-22 66 views
4

我有一個表,其中一列source_id,其值應該是另一個表的主鍵,儘管表中的表會因記錄而異。每條記錄的值必須爲指定源記錄表的source_table,以及指定源表中的行的值source_id指向幾個表之一的外鍵約束

有沒有什麼辦法可以實現這一點,以利用數據庫的外鍵約束和驗證?或者我將不得不將我的驗證邏輯移入應用程序層?或者,是否有另一種設計可以讓我避免這個問題?

回答

4

外鍵約束只能引用一個目標表。 SQL中不提供基於其他字段引用不同目標表的「條件」外鍵。由於@OMG Ponies在下面的註釋中註明,您可以在同一列上引用多個外鍵,引用多個表,但這意味着該列的值必須存在於所有引用的表中。我想這不是你以後的樣子。

對於一些可能的解決辦法,我建議您查看@Bill Karwin's這個問題的答案:

我一般都喜歡的 「超表」 的方式。你可能也想看看這個職位又如:

+0

您可以在列上定義多個外鍵,但這意味着插入到該列中的值必須存在於所有外表中 – 2010-08-22 03:44:21

+0

@OMG:是,是。讓我改述我的答案,以便更準確:) – 2010-08-22 03:45:25

+0

鏈接的問題正是我尋找的答案。不幸的是,這可能意味着我將重做我的模式。 – 2010-08-22 03:49:08

1

我覺得以前的答案不回答這個問題的第一部分好。然而,Daniel推薦的鏈接只提供了一個解決方案,只有當引用的「源」表的數量相當小的情況下。如果您決定增加「源」表的數量,解決方案將無法輕鬆擴展。

爲了推薦一個更好的策略,最好多提供一些關於該任務的細節以及「源」表是否有共同之處,以便將它們組合起來。

在目前的結構(據我可以從問題推斷),我會扭轉的關係:

  1. 我想創建一個表(姑且稱之爲八方),將工作作爲所有可用的資源庫來源與列source_id和source_table。兩者都包含在主鍵中。
  2. 我會從引用AllSources表的每個「源」表中創建外鍵,以便它們只能擁有已在其中註冊的源。
  3. 然後,我會創建你提到的問題中提到的外鍵引用AllSources表(不單獨「源」表)。

缺點:你將不得不管理免責和「源」表一起確保當您創建免責記錄,你也合適的「源」表中創建一個相應的記錄,這在現實中並不難。

+0

這似乎是「超級」解決方案在這個答案中提到:http://stackoverflow.com/questions/2002985/mysql-conditional-foreign-key-constraints/2003042#2003042。 – 2010-08-22 04:24:24

+0

是的。我更喜歡它,因爲添加記錄比添加列更容易。 – spbfox 2010-08-22 06:12:10