当尝试更新由不同表中的 2 列作为外键引用的主键时,mysql 级联将不起作用

标签 mysql

我在更新数据库时遇到问题。

这是我的结构:

我有 1 个名为“users”的表:

CREATE TABLE `users` (
  `username` varchar(45) NOT NULL,
  PRIMARY KEY (`username`)
)

INSERT INTO `users` VALUES ('alice'),('bob'),('john');

我有 1 个名为:“orders”的表:

CREATE TABLE `orders` (
  `user1` varchar(45) NOT NULL,
  `user2` varchar(45) NOT NULL,
  `date` datetime DEFAULT NULL,
  PRIMARY KEY (`user1`,`user2`),
  KEY `user2_idx` (`user2`),
  CONSTRAINT `user1` FOREIGN KEY (`user1`) REFERENCES `users` (`username`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `user2` FOREIGN KEY (`user2`) REFERENCES `users` (`username`) ON DELETE CASCADE ON UPDATE CASCADE
)

INSERT INTO `orders` VALUES ('alice','bob',NULL),('alice','john',NULL),('bob','bob',NULL);

这意味着一个订单由 2 个用户组成,即“orders”表的一条记录由引用“users”表的 2 个外键组合而成。

我遇到的问题是我现在需要更改用户的用户名。

如上面的代码所示,我有: 3 个用户:“alice”、“bob”和“john” 3 个订单:('alice','bob'), ('alice','john'), ('bob','bob')

如果我尝试编辑“alice”或“john”用户名,则操作将成功,并且级联将相应地更改所有订单。

但是如果我尝试将“bob”用户名更改为其他用户名,我会收到此可怕的错误消息,我只是不明白为什么:

Operation failed: There was an error while applying the SQL script to the database.
Executing:
UPDATE `test`.`users` SET `username`='bobd' WHERE `username`='bob';

ERROR 1452: 1452: Cannot add or update a child row: a foreign key constraint fails (`test`.`orders`, CONSTRAINT `user2` FOREIGN KEY (`user2`) REFERENCES `users` (`username`) ON DELETE CASCADE ON UPDATE CASCADE)
SQL Statement:
UPDATE `test`.`users` SET `username`='bobd' WHERE `username`='bob'

最佳答案

我认为这个条款已经让你痛不欲生了:

Using FOREIGN KEY Constraints :

Between two tables, do not define several ON UPDATE CASCADE clauses that act on the same column in the parent table or in the child table.

如您所见,服务器为级联更新的每个约束发出单独的 UPDATE 语句。但是,如果有两列受到影响,则这两个语句都无法自行生成有效行!

这里的一个可能的解决方案是使用用户 ID 作为他们的唯一身份,该身份永远不会改变,而不是任何辅助信息。
事实上,在任何事情都会随时间发生变化的情况下,这是耗时证明的最佳实践:Do natural keys provide higher or lower performance in SQL Server than surrogate integer keys?概述了优点和缺点。

关于当尝试更新由不同表中的 2 列作为外键引用的主键时,mysql 级联将不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28653262/

相关文章:

php - 从 MySQL 数据库提取数据到下拉菜单时出错

php - MySQLi 不从 JOIN 准备语句返回结果

mysql - 如何查找一个表中确实存在于另一个表中但基于日期的记录?

mysql大表查询优化group by

mysql - 如何在 MySQL 中返回数据透视表输出?

Java MySQL 如何在结果集中选择行?

mysql - 如何动态选择列? mysql

mysql - 删除mysql中重复数据(大数据场景下)

MYSQL查询查找具有指定列分组的所有重复记录

MySQL 服务器已经消失 - 尝试了所有方法