Mysql

列定義上的外鍵引用被忽略。功能,而不是錯誤——為什麼?

  • April 2, 2020

良好的舊參考限制。當在表級別定義時,它們就像一個魅力。

create table foo (id int primary key);

create table bar (id int, foreign key(id) references foo(id));
insert into bar values (1);
-- ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (...)

但是,如果您來自另一個生態系統並且習慣於偶爾在列級別定義外鍵約束,則會發生以下情況:

create table baz (id int references foo(id));
insert into baz values (1); -- happily takes a value that isn't there in foo
select id from baz;
-- 1

發生的情況是references已被辨識,但被忽略。

事實證明,這不是一個錯誤。MySQL 文件說他們這樣做了,這就是您需要知道的全部內容:

MySQL 解析但忽略“內聯 REFERENCES 規範”(如 SQL 標準中所定義),其中引用被定義為列規範的一部分。MySQL 僅在指定為單獨的 FOREIGN KEY 規範的一部分時才接受 REFERENCES 子句。

MariaDB 文件的基本原理稍微詳細一些:

MariaDB 接受 ALTER TABLE 和 CREATE TABLE 語句中的 REFERENCES 子句,但該語法什麼也不做。MariaDB 只是簡單地解析它而不返回任何錯誤或警告,以便與其他 DBMS 兼容。但是,只有下面描述的語法會創建外鍵。

現在,通過默默地破壞引用的真正目的,幫助與其他 DBMS 和標準“兼容性”的“功能”有什麼用,同時,正確實現它看起來並不像一個很大的努力因為在表級別聲明時確實強制執行外鍵約束?並且不要告訴我這無法修復,因為人們依賴於在列級別聲明時可以破壞外部約束的事實。

請幫助我理解這一點。

編輯:我剛剛意識到,通過“與其他 DBMS 的兼容性”,MariaDB 文件實際上可能指的是 MySQL。這可能是 MariaDB 堅持 MySQL(無動機)行為的一個很好的動機,也可能是錯過了改進其分支的機會。

按照設計,MySQL 與其他開源數據庫(即 PostgreSQL)相比,對 SQL 標準的兼容程度較低:我認為這在這兩種情況下都是有意的設計選擇,我認為對於 MySQL 來說,即使有所有 Oracle Corp. 和 MariaDB 的成就,這條路仍然很長在過去的十年裡。

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