Mysql
Mysql 中“ON-DELETE-CASCADE”和“ON-DELETE-RESTRICT”約束混合的標準行為
在mysql 5.6中,考慮這兩個創建 A、B、C 和 D 之間關係的範例。
範例 1
CREATE TABLE `a` ( id INT UNSIGNED NOT NULL, PRIMARY KEY (id) ) ENGINE = INNODB; CREATE TABLE `b` ( id INT UNSIGNED NOT NULL, a INT UNSIGNED NOT NULL, PRIMARY KEY (id), FOREIGN KEY (a) REFERENCES a (id) ON DELETE CASCADE ) ENGINE = INNODB; CREATE TABLE `c` ( id INT UNSIGNED NOT NULL, a INT UNSIGNED NOT NULL, PRIMARY KEY (id), FOREIGN KEY (a) REFERENCES a (id) ON DELETE CASCADE ) ENGINE = INNODB; CREATE TABLE `d` ( id INT UNSIGNED NOT NULL, b INT UNSIGNED NOT NULL, c INT UNSIGNED NOT NULL, PRIMARY KEY (id), FOREIGN KEY (id) REFERENCES b (id) ON DELETE CASCADE, FOREIGN KEY (id) REFERENCES c (id) ON DELETE RESTRICT ) ENGINE = INNODB; INSERT INTO a VALUES (1); INSERT INTO b VALUES (1, 1); INSERT INTO c VALUES (1, 1); INSERT INTO d VALUES (1, 1, 1); DELETE FROM a;
結果是所有行都被刪除。
範例 2
CREATE TABLE `a` ( id INT UNSIGNED NOT NULL, PRIMARY KEY (id) ) ENGINE = INNODB; CREATE TABLE `b` ( id INT UNSIGNED NOT NULL, a INT UNSIGNED NOT NULL, PRIMARY KEY (id), FOREIGN KEY (a) REFERENCES a (id) ON DELETE CASCADE ) ENGINE = INNODB; CREATE TABLE `c` ( id INT UNSIGNED NOT NULL, a INT UNSIGNED NOT NULL, PRIMARY KEY (id), FOREIGN KEY (a) REFERENCES a (id) ON DELETE CASCADE ) ENGINE = INNODB; CREATE TABLE `d` ( id INT UNSIGNED NOT NULL, b INT UNSIGNED NOT NULL, c INT UNSIGNED NOT NULL, PRIMARY KEY (id), FOREIGN KEY (id) REFERENCES b (id) ON DELETE RESTRICT, FOREIGN KEY (id) REFERENCES c (id) ON DELETE CASCADE ) ENGINE = INNODB; INSERT INTO a VALUES (1); INSERT INTO b VALUES (1, 1); INSERT INTO c VALUES (1, 1); INSERT INTO d VALUES (1, 1, 1); DELETE FROM a;
請注意,唯一的區別是外鍵RESTRICT從d的變化。然而,這個例子失敗了
錯誤程式碼:1451 無法刪除或更新父行:外鍵約束失敗(
hello
.d
, CONSTRAINTd_ibfk_1
FOREIGN KEY (id
) REFERENCESb
(id
))雖然從邏輯上講,它與範例 1相同。在沒有查看MySQL的原始碼的情況下,我強烈懷疑外鍵是根據它們的名稱按詞法順序“應用”的。在這種情況下,標準行為 (ANSI-SQL) 是什麼?
我修改了範例 1,以便我嘗試過的所有供應商都接受該語法。事實證明,唯一拒絕該場景的測試 DBMS 是 Db2 DB<>Fiddle:
MariaDB 10.2, 10.3 Yes MySQL 5.6, 5.7, 8.0 Yes Postgres 11 Yes Oracle 11g release 2, 18 Yes SQLServer 2017 Yes Db2 V11 No
請注意,對於 Oracle 和 SQLServer,必須稍微修改外鍵。請參閱Dinesh Kumar提供的連結
Db2 拋出如下異常:
SQL20255N FOREIGN KEY .. 無效,因為它會導致後代表 … 被刪除連接到其祖先表 … 通過具有衝突刪除規則的多個關係。衝突發生在後代表上的約束…和…的刪除規則之間。原因程式碼 = “3”。SQLSTATE=42915 SQLCODE=-20255
我瀏覽了 7IWD2-02-Foundation-2011-12.pdf,可以從以下位置下載:
http://www.wiscorp.com/sql20nn.zip
但我沒有發現任何關於此的內容。
對我來說,似乎 Db2 在這方面表現得很好,但這只是我的看法。