Mysql

Mysql 中“ON-DELETE-CASCADE”和“ON-DELETE-RESTRICT”約束混合的標準行為

  • May 12, 2019

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;

請注意,唯一的區別是外鍵RESTRICTd的變化。然而,這個例子失敗了

錯誤程式碼:1451 無法刪除或更新父行:外鍵約束失敗(hello. d, CONSTRAINT d_ibfk_1FOREIGN KEY ( id) REFERENCES b( 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提供的連結

甲骨文 SQL伺服器

Db2 拋出如下異常:

SQL20255N FOREIGN KEY .. 無效,因為它會導致後代表 … 被刪除連接到其祖先表 … 通過具有衝突刪除規則的多個關係。衝突發生在後代表上的約束…和…的刪除規則之間。原因程式碼 = “3”。SQLSTATE=42915 SQLCODE=-20255

我瀏覽了 7IWD2-02-Foundation-2011-12.pdf,可以從以下位置下載:

http://www.wiscorp.com/sql20nn.zip

但我沒有發現任何關於此的內容。

對我來說,似乎 Db2 在這方面表現得很好,但這只是我的看法。

引用自:https://dba.stackexchange.com/questions/236911