1. 程式人生 > >關於mysql的decimal類型的外鍵的一個特殊限制

關於mysql的decimal類型的外鍵的一個特殊限制

出了 exception 沒有 CI types bin 一個 插入數據 postgres

一、問題描述

在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類型的外鍵有這種限制。

關於mysql的decimal類型的外鍵的一個特殊限制