我正试图将ON DELETE CASCADE
用于我正在研究的数据库。似乎不起作用,所以我在一个简单的例子上进行了测试,没有成功。
CREATE TABLE foo (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
data VARCHAR(10),
PRIMARY KEY (id)
)ENGINE=InnoDB;
CREATE TABLE foo2 (
id INT UNSIGNED NOT NULL,
data2 VARCHAR(10),
PRIMARY KEY (id),
CONSTRAINT fk_foo2_id FOREIGN KEY (id) REFERENCES foo(id) ON DELETE CASCADE
)ENGINE=InnoDB;
INSERT INTO foo (data) VALUE ('hello'),('world'),('mysql');
INSERT INTO foo2 (data2) VALUE ('hello2'),('world2'),('mysql2');
SELECT * FROM foo;
+----+-------+
| id | data |
+----+-------+
| 1 | hello |
| 2 | world |
| 3 | mysql |
+----+-------+
3 rows in set (0.00 sec)
SELECT * FROM foo2;
+----+--------+
| id | data2 |
+----+--------+
| 1 | hello2 |
| 2 | world2 |
| 3 | mysql2 |
+----+--------+
3 rows in set (0.00 sec)
DELETE FROM foo WHERE id=2;
SELECT * FROM foo;
+----+-------+
| id | data |
+----+-------+
| 1 | hello |
| 3 | mysql |
+----+-------+
2 rows in set (0.00 sec)
SELECT * FROM foo2;
+----+--------+
| id | data2 |
+----+--------+
| 1 | hello2 |
| 2 | world2 |
| 3 | mysql2 |
+----+--------+
3 rows in set (0.00 sec)
我怎么也弄不明白为什么这不起作用。我在这里看了类似的问题和答案,我完全按照他们说的做了,但它仍然不起作用。他们中的大多数人只是说要改成ENGINE=InnoDb
,但我试过了,没有成功。
我肯定错过了什么,而且可能很明显…周一早上。
如果有人能给我这个小问题指点指点,我将不胜感激!编辑:从foo2
的id
中删除auto_increment
,因为它不属于那里
首先想到的是检查foreign_key_checks
变量的设置。如果设置为0 (FALSE),则不强制外键约束。
SHOW VARIABLES LIKE 'foreign_key_checks'
要启用外键约束,请将变量设置为1
SET foreign_key_checks = 1;
注意:这只影响当前会话。新的会话将继承GLOBAL设置。
另外,检查你的表是否真的使用了InnoDB引擎,并且外键是否已经定义。最简单的方法是从
获取输出:SHOW CREATE TABLE foo;
SHOW CREATE TABLE foo2;
后续
这是我们期望在MySQL 5.1.61中NOT被打破的。
作为解决方法,尝试将外键约束定义为单独的ALTER TABLE语句。
ALTER TABLE foo2
ADD CONSTRAINT fk_foo2_id FOREIGN KEY (id) REFERENCES foo(id) ON DELETE CASCADE ;
我不认为两个列之间的外键约束都是用"auto_increment"定义的。在您的示例中,您可以轻松地在"foo"表中创建几行(在"foo2"中没有对应的行),并且从那时起,您无法控制两个表中的"id"值是否匹配。
我承认我没有检查文档,但是如果MySQL静默地忽略自动生成列的外键约束,我也不会感到惊讶。
IMNSHO,你的表"foo2"应该使用"id"值,这些值是显式设置的,并引用"foo"中的特定行,因为这样删除这样的"foo"行应该级联到"foo2"。