微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

MySQLPercona错误1452:无缘无故无法添加或更新子行

如何解决MySQLPercona错误1452:无缘无故无法添加或更新子行

我有2个数据库表“用户”和“任务”。 任务表包含两个分别引用createdBy_user_id的{​​{1}}和updatedBy_user_id列的外键。如果我尝试在users.id中插入一个条目(在确保存在由外键引用的用户之后),如下所示:

tasks

查询失败,错误1452:

INSERT INTO tasks (createdBy_user_id,updatedBy_user_id,noOfYear,createdAt,updatedAt,status,customer_id)
VALUES (1,1,Now(),"open",1)

我不知道为什么会这样,因为如果删除约束,一切都会很好。对于“ updatedBy_user_id”列,不会发生相同的错误,从而造成这种混乱。

表具有以下DDL:

用户表:

ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`test`.`tasks`,CONSTRAINT `user_id_fk_constr` FOREIGN KEY (`createdBy_user_id`) REFERENCES `users` (`id`))

任务表:

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,`active` tinyint(1) DEFAULT NULL,`email` varchar(255) DEFAULT NULL,`email_confirmed_at` datetime DEFAULT NULL,`username` varchar(50) NOT NULL,`password` varchar(255) NOT NULL,`first_name` varchar(50) DEFAULT NULL,`last_name` varchar(50) DEFAULT NULL,`job` varchar(64) DEFAULT NULL,`position` varchar(64) DEFAULT NULL,`specialKNowledge` text,`tasks` text,PRIMARY KEY (`id`),UNIQUE KEY `username` (`username`),UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

如您所见,数据类型匹配,并且两个表都使用CREATE TABLE `tasks` ( `id` int(11) NOT NULL AUTO_INCREMENT,`createdAt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,`updatedAt` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`noOfYear` int(11) NOT NULL,`year` int(11) GENERATED ALWAYS AS (right(year(`createdAt`),2)) VIRTUAL NOT NULL,`createdBy_user_id` int(11) NOT NULL,`updatedBy_user_id` int(11) NOT NULL,`status` enum('open','closed') NOT NULL,`customer_id` int(11) NOT NULL,`projectDescription` text,UNIQUE KEY `tasks_year_unique_constr` (`year`,`noOfYear`),KEY `user_id_fk_constr` (`createdBy_user_id`),KEY `customer_id_fk_constr` (`customer_id`),KEY `user_up_id_fk_constr` (`updatedBy_user_id`),CONSTRAINT `customer_id_fk_constr` FOREIGN KEY (`customer_id`) REFERENCES `Customer` (`id`),CONSTRAINT `user_id_fk_constr` FOREIGN KEY (`createdBy_user_id`) REFERENCES `users` (`id`),CONSTRAINT `user_up_id_fk_constr` FOREIGN KEY (`updatedBy_user_id`) REFERENCES `users` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 。 users表包含一个条目:

InnoDB Engine
select id,username from users;

因此,没有明显的原因,为什么插入失败。你知道我的桌子怎么了吗?看起来像是软件错误

解决方法

这是一个错误。 MySQL 5.7在生成的列和外键方面遇到了一些麻烦,我认为这是Bug #79772 Foreign key not allowed when a virtual index exists的一个未修正的变体。

在您的特定情况下,并且可能取决于您的确切版本,以下任何修改似乎都可以防止该错误的发生:

  • 不使用虚拟列,而是使用stored
  • 请勿在虚拟列之后直接为列创建外键,例如将列顺序更改为year,status,createdBy_user_id,updatedBy_user_id
  • 不要在虚拟列上使用unique索引,普通索引应该很好(至少在已修复链接错误的版本中)。您需要一个唯一的约束,因此这不是一个选择,但是可以解决您的问题的事实强调了问题的“错误”性质。

第二个要点似乎是潜在的错误:我假设某个迭代器未正确计算虚拟列,因此应检查createdBy_user_id的外键似乎混淆了列并实际上检查了用户表中year的值(在本例中为“ 20”)。因此,如果您的用户表中有一个ID为“ 20”的用户,则无论您要插入的createdBy_user_id的值是什么,外键实际上都会接受它,请参见MySQL 5.7.29 fiddle。>

除非有特殊原因要使用虚拟列,否则使用stored可能是明智的选择。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。