我对 StackOverflow 还很陌生,所以如果我做错了什么,请抱歉。对我的英语感到抱歉 - 这不是我的母语。
好吧,长话短说。我正在使用:
Server version: 5.6.31 MySQL Community Server (GPL)
我有两个这样的表:
表格文本
CREATE TABLE `texts` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`body` text,
`source_id` int(11) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `texts_sources_key` (`source_id`),
CONSTRAINT `texts_sources_key` FOREIGN KEY (`source_id`) REFERENCES `texts` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
表格texts_sources
CREATE TABLE `texts_sources` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`short_desc` varchar(255) DEFAULT NULL,
`long_desc` text,
`url` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
正如您所看到的 - 有外键通过 ON DELETE SET NULL ON UPDATE CASCADE 链接这些表。
这是初始数据:
mysql> select * from texts;
+----+------+-----------+
| id | body | source_id |
+----+------+-----------+
| 1 | *** | 1 |
+----+------+-----------+
1 row in set (0.00 sec)
mysql> select * from texts_sources;
+----+------------+-----------+----------------+
| id | short_desc | long_desc | url |
+----+------------+-----------+----------------+
| 1 | * | NULL | http://url.com |
+----+------------+-----------+----------------+
1 row in set (0.00 sec)
现在让我们施展一些魔法。
mysql> update texts_sources set id=5;
Query OK, 1 row affected (0.05 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from texts_sources;
+----+------------+-----------+----------------+
| id | short_desc | long_desc | url |
+----+------------+-----------+----------------+
| 5 | * | NULL | http://url.com |
+----+------------+-----------+----------------+
1 row in set (0.01 sec)
mysql> select * from texts;
+----+------+-----------+
| id | body | source_id |
+----+------+-----------+
| 1 | *** | 1 |
+----+------+-----------+
1 row in set (0.00 sec)
不工作。更多乐趣:
mysql> delete from texts_sources;
Query OK, 1 row affected (0.18 sec)
mysql> select * from texts;
+----+------+-----------+
| id | body | source_id |
+----+------+-----------+
| 1 | *** | 1 |
+----+------+-----------+
1 row in set (0.00 sec)
不工作。好的。也许它根本不起作用。那么我们试试这个方法:
mysql> update texts set source_id=5;
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`serj_by`.`texts`, CONSTRAINT `humor_sources_key` FOREIGN KEY (`source_id`) REFERENCES `texts` (`id`) ON DELETE SET NULL ON UPDATE CASCADE)
mysql> insert into texts (body, source_id) values ("***", 7);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`serj_by`.`texts`, CONSTRAINT `humor_sources_key` FOREIGN KEY (`source_id`) REFERENCES `texts` (`id`) ON DELETE SET NULL ON UPDATE CASCADE)
工作。乐趣。更有趣(texts_sources 是空的,希望你记住):
mysql> insert into texts (body, source_id) values ("***", 1);
Query OK, 1 row affected (0.16 sec)
mysql> select * from texts_sources;
Empty set (0.00 sec)
mysql> select * from texts;
+----+------+-----------+
| id | body | source_id |
+----+------+-----------+
| 1 | *** | 1 |
| 2 | *** | 1 |
+----+------+-----------+
2 rows in set (0.00 sec)
所以我的问题很明显。这是什么?以及如何使其在所有情况下都能按预期工作?非常感谢任何帮助。预先感谢您!
最佳答案
让我们仔细看看:
CONSTRAINT `texts_sources_key`
FOREIGN KEY (`source_id`)
REFERENCES `texts` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
尽管您已将其命名为 texts_sources_key
,但外键实际上引用了同一个表中的列。您可能希望它是
CONSTRAINT `texts_sources_key`
FOREIGN KEY (`source_id`)
REFERENCES `texts_sources` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
此外,在进行该约束之前,您需要先创建 text_sources 表。
关于mysql - 外键在 MySQL 中偶尔起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39637624/