錯誤現場
ALTER TABLE `product`
ADD CONSTRAINT `sid_ref`
FOREIGN KEY (`sid`) REFERENCES `sealer` (`id`)
ON DELETE NO ACTION ON UPDATE NO ACTION;
-- ERROR 1215 (HY000): Cannot add foreign key constraint
表結構對比
product 表 (子表)
CREATE TABLE `product` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
`sid` INT(11) NOT NULL, -- 關鍵差異:無 UNSIGNED,長度 11
PRIMARY KEY (`id`),
UNIQUE KEY `sid_index` (`sid`) USING HASH
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
sealer 表 (父表)
CREATE TABLE `sealer` (
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, -- UNSIGNED BIGINT
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
根因分析:三大不匹配
| 維度 | 父表 sealer.id | 子表 product.sid | 結果 |
| 數據類型 | BIGINT | INT | ❌ 不一致 |
| 符號屬性 | UNSIGNED | SIGNED (默認) | ❌ 不一致 |
| 顯示寬度 | 20 | 11 | ⚠️ 非決定性因素 |
InnoDB 外鍵要求:引用列與被引用列數據類型、長度、符號屬性、字符集、校對規則完全一致。任何不匹配均導致 1215 錯誤。
解決方案:修正子表列定義
ALTER TABLE `product`
MODIFY COLUMN `sid` BIGINT(20) UNSIGNED NOT NULL;
若子表已有數據,確保所有 sid 值在 BIGINT UNSIGNED 範圍內且父表 id 中存在,否則修改失敗或外鍵創建仍報錯。
驗證創建成功
ALTER TABLE `product`
ADD CONSTRAINT `sid_ref`
FOREIGN KEY (`sid`) REFERENCES `sealer` (`id`)
ON DELETE NO ACTION ON UPDATE NO ACTION;
-- Query OK, 0 rows affected
擴展:其他常見 1215 原因速查表
| 原因 | 檢查方法 | 解決 |
| 父表非 InnoDB | SHOW CREATE TABLE parent | ALTER TABLE parent ENGINE=InnoDB |
| 父表無索引/非主鍵 | SHOW INDEX FROM parent | ADD INDEX 或設為 PK |
| 字符集/校對規則不一致 | SHOW CREATE TABLE 兩表對比 | 統一 CHARSET/COLLATE |
| 數據不匹配 (子表值父表無) | SELECT sid FROM product WHERE sid NOT IN (SELECT id FROM sealer) | 清理臟數據或補全父表 |
| 列可空性不一致 | DESC 兩表 | 修正 NULL/NOT NULL |
總結
Error 1215 90% 以上由列定義不匹配引起。建立外鍵前,務必對比 SHOW CREATE TABLE 確保:類型、長度、UNSIGNED、字符集、校對規則、索引存在性 六維一致。生產環境建議通過遷移腳本管理 Schema 變更,自動校驗外鍵前置條件。