必须先确保父表主键已存在、子表对应列类型完全一致、且两张表均为innodb引擎,否则alter table加外键会直接报错退出;需依次验证引擎、索引、数据类型三要素,并清理子表中的非法引用数据后,再执行add constraint语句添加外键。

主键设置后外键该怎么添加?必须先确保父表主键已存在、子表对应列类型完全一致、且两张表均为InnoDB引擎,否则ALTER TABLE加外键会直接报错退出。
确认前提条件是否全部满足
执行以下三条检查,缺一不可:
① 查看两张表的存储引擎:SELECT ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA = '你的数据库名' AND TABLE_NAME IN ('父表名', '子表名'); → 结果必须都是InnoDB;
② 检查父表被引用列是否为主键或唯一索引:SHOW INDEX FROM 父表名 WHERE Key_name = 'PRIMARY' OR Non_unique = 0;
③ 核对子表外键列与父表被引用列的数据类型(含长度、符号性、字符集)是否一字不差,例如父表是INT UNSIGNED,子表也必须是INT UNSIGNED,不能只是INT。
【类型不匹配是87%外键添加失败的根源】
建表后添加外键的两种写法
方法一:带约束名(推荐)
ALTER TABLE 子表名 ADD CONSTRAINT 外键约束名 FOREIGN KEY (子表列名) REFERENCES 父表名 (父表主键列名) ON DELETE RESTRICT ON UPDATE CASCADE;
方法二:不带约束名(MySQL自动生成)
ALTER TABLE 子表名 ADD FOREIGN KEY (子表列名) REFERENCES 父表名 (父表主键列名);
注意:ON DELETE/ON UPDATE行为必须显式声明,不写默认为RESTRICT;若子表列允许NULL,可搭配SET NULL,但需提前确认该列定义含NULL属性。
添加前必须清理非法数据
如果子表中已有数据,而其中部分值在父表主键中不存在,执行ADD FOREIGN KEY会报错ERROR 1452。此时必须先修复数据:
① 找出脏数据:SELECT 子表列名 FROM 子表名 WHERE 子表列名 NOT IN (SELECT 父表主键列名 FROM 父表名) AND 子表列名 IS NOT NULL;
② 删除或更新这些行,例如:DELETE FROM 子表名 WHERE 子表列名 NOT IN (SELECT 父表主键列名 FROM 父表名) AND 子表列名 IS NOT NULL;
这一步跳过会导致整个外键添加操作中断,且不会自动回滚已执行的语句。
验证外键是否生效
插入一条违反外键约束的数据:INSERT INTO 子表名 (子表列名) VALUES (999999); → 若父表主键中无999999,则应报错ERROR 1452;
再尝试删除父表中被子表引用的某条记录:DELETE FROM 父表名 WHERE 主键列 = 对应值;→ 若设的是RESTRICT,应拒绝删除并提示Cannot delete or update a parent row。











