兩個或多個外鍵約束上存在相同的列
導致我的問題的簡單模式如下:
CREATE TABLE A ( AID INT AUTO_INCREMENT PRIMARY KEY ); CREATE TABLE A_COPY ( AID INT, CID INT, PRIMARY KEY (AID, CID), FOREIGN KEY (AID) REFERENCES A(AID) ON DELETE CASCADE ); CREATE TABLE R ( AID INT, CID INT, EXTRANUM INT, PRIMARY KEY (AID, CID, EXTRANUM), FOREIGN KEY (AID) REFERENCES A(AID) ON DELETE NO ACTION, FOREIGN KEY (AID, CID) REFERENCES A_COPY(AID, CID) ON DELETE CASCADE );
此 SQL Fiddle 包含範例數據和查詢以及上面顯示的架構。
在這裡,如您所見,我們
A
通過擴展它來建構表(假設這A_COPY
是實體關係圖中的“弱實體”),然後在某些關係中使用它R
。問題是,在這裡(表R
)我們使用兩個不同的外鍵約束,其中一列在兩個約束中是相同的。這可能有意義,也可能沒有意義。所以,一件事是這是否有意義。我相信它會,因為我可能(出於某種原因)想在從表中刪除時選擇不同的外鍵引用操作,
A
或者A_COPY
分別,如此處所示。第二個問題是如何在 MySQL 中使用 InnoDB 表實現這些語句。通常,問題是:對於具有兩個或多個相同列的同一個表上的外鍵約束的選擇規則是各自外鍵約束的一部分(例如,這裡在同一個表上的兩個外鍵約束中使用相同
AID
)?R
我並不完全清楚該標準對此有何規定,但顯然,兩者之間存在衝突:
a) FOREIGN KEY (AID) REFERENCES A(AID) ON DELETE NO ACTION
和
b) FOREIGN KEY (AID, CID) REFERENCES A_COPY(AID, CID) ON DELETE CASCADE
如果在 b) 之前評估 a) 或相反,最終結果可能會有所不同。在standard-behaviour-for-mix-of-on-delete-cascade-and-on-delete-restrict-const中有一個類似的問題
A
FOREIGN KEY
做這些事情:
- 告訴人們模式設計者希望表如何綁定在一起。
INSERTing
在– 驗證相應行是否存在時進行完整性檢查。CASCADE
在UPDATEing
或時做事DELETEing
。- 提供一個
INDEX
(如果尚不存在)以促進完整性或級聯所需的查找。由於您似乎有兩個相互衝突
CASCADE
的要求,因此可能在文件的深處描述了一條規則。我猜想FK 動作是按照寫的順序執行的。因此ON DELETE NO ACTION
什麼都不做,然後ON DELETE CASCADE
接管。在我看來,FK 的思想非常簡單。期望他們採取的不僅僅是瑣碎的行動是有風險的。這個論壇到處都是問“我可以寫一個 FK 來做廢話嗎”的問題。答案通常是“不”。
您在問一個必然的問題“在這種奇怪的情況下會發生什麼”。我的回答是“不要相信 MySQL,使用應用程式碼做任何你想做的事”。(您可能會在儲存常式中體現“業務邏輯”。)
也不要對觸發器提出太多要求。