MySQL外键关联索引未按指定名称生成的原因及解决方法
索引命名与预期不符的原因
InnoDB引擎对所有外键关联列有强制要求:列上必须存在对应的支撑索引,外键约束才能正常创建。如果创建外键时关联列上没有可用索引,数据库会自动为该列生成配套索引。
在MySQL 8.0.22版本中,外键定义语法里FOREIGN KEY 后紧跟的索引名参数,和旧版本的生效逻辑完全不同:
- 8.0.22之前的版本,该位置填写的索引名,会直接作为自动生成的支撑索引的名称;
- 8.0.22开始,该位置的索引名仅用于匹配表上已经预先存在的同名索引,不会作为新生成索引的命名依据。
你执行外键创建语句时,owner_id是刚通过ALTER TABLE加上的新列,表上根本不存在名为idx_fk_pet_person的索引,因此数据库直接忽略了你写的自定义索引名,转而使用外键约束本身的名称fk_pet_person 作为自动生成的支撑索引的名称,最终出现了索引名和预期不符的结果。
按指定名称生成索引的操作步骤
需要调整操作顺序,先手动创建对应名称的索引,再绑定外键约束:
- 先为外键列创建自定义名称的支撑索引:
ALTER TABLE pet ADD KEY idx_fk_pet_person (owner_id);
- 再执行添加外键约束的语句,此时
FOREIGN KEY后填写的idx_fk_pet_person可以匹配到刚才创建的已存在索引,不会触发自动命名逻辑:
ALTER TABLE pet ADD CONSTRAINT `fk_pet_person` FOREIGN KEY `idx_fk_pet_person` (`owner_id`) REFERENCES `person` (`person_id`);
执行完成后查询SHOW CREATE TABLE pet,就能看到支撑索引已经按照idx_fk_pet_person 的指定名称生成。
注意:不要将外键定义里的索引名参数作为新索引的命名入口,从MySQL 8.0.22开始,这个参数的作用是指定外键需要复用的现有索引,没有预先创建对应索引的话,写在这里的自定义名称不会生效。
内容的提问来源于stack exchange,提问作者urig
相关产品推荐
相关产品推荐

