Mysql

如何對 MariaDB 中引用的表進行 CASCADE DROP?

  • May 22, 2018

如果我有一個引用另一個表的表

CREATE TABLE foo ( x int PRIMARY KEY );
CREATE TABLE bar (
 x int,
 CONSTRAINT asdf FOREIGN KEY (x) REFERENCES foo(x)
);

DROP TABLE foo;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails

在 PostgreSQL 中我可以很容易地使用DROP ... CASCADE

CASCADE自動刪除依賴於表的對象(例如視圖),進而刪除依賴於這些對象的所有對象(參見第 5.13 節)。

像這樣,

# CREATE TABLE foo ( x int PRIMARY KEY );
# CREATE TABLE bar ( x int REFERENCES foo );
# DROP TABLE foo CASCADE;
NOTICE:  drop cascades to constraint bar_x_fkey on table bar
DROP TABLE

但是,在 MySQL 中,即使CASCADE出現錯誤,

DROP TABLE foo CASCADE;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails

從 MySQL 文件中,我認為還不可能解決這個問題

如果外鍵引用此表,則不能刪除該表。在這種情況下,需要先刪除外鍵。

事實上,在MariaDBMySQLCASCADE中都明確記錄為 NOOP,

RESTRICT並且CASCADE允許更容易地從其他數據庫系統移植。在 MariaDB 中,他們什麼都不做。

這有一個問題,因為MDEV-6907以“不會修復”的形式關閉,解決了這個問題。

我不認為這就是CASCADEMySQL 衍生產品的工作方式!

表:

CREATE TABLE foo 
( 
 x int PRIMARY KEY 
);

CREATE TABLE bar 
(
 x int,
 CONSTRAINT asdf FOREIGN KEY (x) REFERENCES foo(x) ON DELETE CASCADE
);

一些價值觀:

INSERT INTO foo VALUES (3), (45), (7);
INSERT INTO bar VALUES(3), (3), (45), (7), (7);

然後:

DELETE FROM foo WHERE x = 3;

現在:

SELECT * FROM bar;

x
7
7
45

因此,(對於 MySQL 系列)DRI(聲明性引用完整性)在記錄級別而不是表級別上工作。引用約束存在於表 bar 而不是 foo - 因此刪除 foo 對該約束沒有影響 - 系統不會讓您刪除父,但會允許您刪除父記錄

看看這裡的小提琴,如果你仔細想想,它是相當清楚的(在某種意義上實際上也足夠合乎邏輯)——至少對我來說是這樣!

然而,對邏輯論點的一個重要警告——PostgreSQL 也不允許

刪除表 foo;

但帶有更多資訊的錯誤消息:

ERROR:  cannot drop table foo because other objects depend on it
DETAIL:  constraint asdf on table bar depends on table foo
HINT:  Use DROP ... CASCADE to drop the dependent objects too

然而

DROP TABLE foo CASCADE;

確實成功了

因此,MySQL 在這兩個語句上都失敗了,而 PostgreSQL 的解決方案(恕我直言並且像往常一樣)更優越——它“強制”CASCADE它是否被顯式呼叫。在任何一種情況下,MySQL 都不會讓它刪除。

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