Mysql
如何對 MariaDB 中引用的表進行 CASCADE DROP?
如果我有一個引用另一個表的表
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 文件中,我認為還不可能解決這個問題
如果外鍵引用此表,則不能刪除該表。在這種情況下,需要先刪除外鍵。
事實上,在MariaDB和MySQL
CASCADE
中都明確記錄為 NOOP,
RESTRICT
並且CASCADE
允許更容易地從其他數據庫系統移植。在 MariaDB 中,他們什麼都不做。這有一個問題,因為MDEV-6907以“不會修復”的形式關閉,解決了這個問題。
我不認為這就是
CASCADE
MySQL 衍生產品的工作方式!表:
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 都不會讓它刪除。