关于mysql的decimal类型的外键的一个特殊限制

一、问题描述

在oracle, postgresql正常运行的Hibenate/JPA应用程序,切换到mysql时却在插入数据时报错:“MySQLIntegrityConstraintViolationException: Cannot add or update a child row: a foreign key constraint fails……”。

检查应用程序代码,没发现不对;网上直接搜索,也没发现有价值的线索。

回到mysql,先删掉报错时的外键,再次启动应用程序,插入数据成功。然后再想加上外键时,同样的错误提示出现了。看来问题不在应用程序,而在mysql这边。

锁定范围后再上网搜索,原因很快确定:是因为子表的关联键是decimal(15),而父表的主键却是decimal(17)。父表主键的范围超出了子表键的范围。

把子表关联键的类型改为decimal(17),加外键成功;再执行应用程序的插入数据功能,一切OK!

二、进一步测试

再去翻阅mysql官方文档,发现对外键有这样的限制条件:

Corresponding columns in the foreign key and the referenced key must have similar data types. The size and sign of integer types must be the same. The length of string types need not be the same. For nonbinary (character) string columns, the character set and collation must be the same.

这里面只提到integer, string,没有提到decimal类型,于是做了个测试。将本例中子表关联键的长度改为decimal(18),发现也正常。说明对于decimal类型,子表关联键的类型可以是父表主键的超集,当然最好是完全一样。

三、吐槽

随笔结尾时,忍不住想吐槽一下:

  • oracle, postgresql对这种情况都是容忍的,为什么mysql不容忍?
  • 不容忍就不容忍吧,为什么不在创建空子表的外键时就报错(至少来个警告吧),而非要等到运行时才出来?
  • 最后吐槽一下官方文档,如果不是恰巧遇到,估计一辈子都不知道decimal类型的外键有这种限制。

猜你喜欢

转载自www.cnblogs.com/wggj/p/9023540.html
今日推荐