mysql 1452 Cannot add or update a child row: a foreign key constraint fails

1. 出现报错

  • 在进行mysq关系l数据库到neo4j图数据库转换的时候,转换规则涉及到外键,所以需要对之前的mysql数据集添加外键。
    在这里插入图片描述
  • 添加过程中出现以上错误。

2. 解决方案

网上最常见的一种解决方案是:

# 切换到外键有问题的那个表,关闭外键检查约束
alter table_name SET FOREIGN_KEY_CHECKS=0;

# 设置外键(一般是修改时添加外键约束)
ALTER TABLE <数据表名> ADD CONSTRAINT <索引名>
FOREIGN KEY(<列名>) REFERENCES <主表名> (<列名>);

# 然后把这个表的外键检查给设置回1
alter table_name SET FOREIGN_KEY_CHECKS=1;

这种方案其实违背了外键的约束性,直接把检查关掉了,那么你设置的外键是否符合数据库设计规则就无法保证。数据库模式可能就不是很好。

同时,出现这个问题,肯定不是mysql数据库抽风了,故意搞你。肯定是你的表有问题,或者是你设置有问题,找到这个原因才更重要

参考:


3. 追溯原因

造成这个错误的原因很多,我整理了一下。

3.1 简单的原因

1. 同一个数据库中外键名称要唯一
在这里插入图片描述
比如上面,外键名为:poet_ibfk_1
在这里插入图片描述
如果直接使用Navicat这类工具,这个外键名称是自动帮你生成的,ibfk是InnoDB Foreign Key的缩写。外键的一种常用命名方式是表名_fk_序号,“icity”表中的第一个外键就是“icity_fk_1”

当然,如果是自己直接sql语句插入的,那需要注意。


2. 外键设置错了表(我的错误)

搞不清Navicat中参照表,被参照表和外键的关系,概念模糊,所以报错。而且不容易发现!

比如对于下面的数据库来说,设置外键的时候,应该在poet_to_poemverse_to_poem上设置,我一开始就设置在其他三个单表里,所以就报错了!
在这里插入图片描述

3.2 棘手的原因

  • 如果是像上面只是命名有问题,那属于个人代码的失误。这种是比较简单的
  • 但是如果是由于违反了数据库设计中关于外键的限制(也就是数据本身的数据有问题,或者数据之间的引用有问题),那就不好改了。。
  • 上面关闭外键检查,来把这个外键插入,其实是避开了数据库本身存在的问题,其实并不推荐。关于外键的理论,比较长,放在了另一个博客:数据库外键理论及MySQL外键实现规定

1. 取值有问题
在这里插入图片描述
参考:数据库外键理论及MySQL外键实现规定

举例来说,有一个诗人表,还有一个诗人诗歌对应表,后者引用前者的诗人id。如果对后面的表设置外键,报错。那么很有可能是因为诗人诗歌表中的诗人id,有不属于诗人表的(不是引用自诗人表),对于这些诗人id,要么就是删掉整列,要么就是把对应行的诗人id这个属性取空值。

在这里插入图片描述
2. 表有问题

参考:数据库外键理论及MySQL外键实现规定

  • 可能引用(参照)表和目标表,使用的存储引擎不同,一般都要求是InnoDB。
  • 可能引用表上对应的外键列没有建立索引!(MySQL要求建立,这样可以加快外键检查的速度,而不用扫描整张表)

参考:

  • 7
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吨吨不打野

解决了问题,觉得还行就给点

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值