mysql - 外键在 MySQL 中偶尔起作用

标签 mysql foreign-keys

我对 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/

相关文章:

MySQL 从多行中选择第一个非空值

php - 如何将秒表结果(数组)推送到第一个表结果(数组)

php - 关于删除级联主义

数据库:大量的外键

sql - 外键 null - 性能下降

mysql - 我尝试使用游标在 mysql 8 上的某些表上运行相同的查询。我不明白我的代码有什么问题

mysql - 在 MySQL 中存储 0.5

mysql - 具有黑名单和收藏夹的用户注册系统的数据模型?

mysql - 我有一个子表,它依赖于两个不相关的父表。我想将行插入子表中

android - 如何在 Room Android 的外键中使用 set_default