Mysql创建外键约束时,报errno: 150

本文介绍了一种常见的数据库外键约束错误,即当定义的外键类型与引用表中的主键类型不符时出现的问题。通过具体示例展示了如何诊断此类问题,并给出了相应的解决方案。

alter table abc add column cd_id bigint default null;
alter table abc add CONSTRAINT `FK_CD_ID` FOREIGN KEY (`CD_ID`) REFERENCES `cd` (`id`) ON DELETE set null;


ERROR 1005 (HY000): Can't create table 'vcread.#sql-9ec_e14a' (errno: 150)


Cannot find an index in the referenced table where the referenced columns appear as the first columns, or column types in the table and the referenced table do not match for constraint.
(译:不能在“被reference的表”里找到包含“被reference字段”的索引,或者是两个关联字段类型不匹配)

cd表的id类型为int(11), 外键字段定义为了bigint。所以。。。



<think>嗯,用户在使用MySQL遇到了添加错误,错误号是1005,提示信息是“Duplicate key on write or update”(写入或更新出现重复)。我需要帮他分析这个问题。首先,我应该回忆一下常见的导致这个错误的原因。 首先,错误121通常和约束有关,可能是指约束的名称重复了。MySQL会给约束自动生成一个名称,如果用户自己指定了名字,而这个名字在数据库中已经存在了,就会导致这个错误。因为每个约束名称在数据库里必须是唯一的。 另创建失败还可能涉及到数据类型不匹配,或者被引用的表缺少对应的索引。不过根据错误提示中的“Duplicate key”,可能更倾向于约束名称重复的问题。用户可能在创建候没有指定名字,或者多次执行了同样的语句导致系统自动生成的名称冲突了。 需要进一步确认用户的操作步骤。比如,用户是否在创建表的候同添加,还是后来通过ALTER TABLE添加的。如果是创建出现错误,可能是约束名称在同一个数据库里重复了。如果是ALTER TABLE出现错误,可能之前已经存在同名的约束。 接下来,我应该考虑如何解决这个问题。首先,建议用户检查约束的名称是否唯一。可以通过查看information_schema.TABLE_CONSTRAINTS表来确认当前数据库中的约束名称是否存在重复。例如,执行查询: SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_SCHEMA = '数据库名' AND CONSTRAINT_TYPE = 'FOREIGN KEY'; 如果发现有重复的约束名,用户就需要在创建指定一个唯一的名称。例如,使用CONSTRAINT关字后面跟一个唯一的名称,如: ALTER TABLE table1 ADD CONSTRAINT fk_unique_name FOREIGN KEY (column1) REFERENCES table2(column2); 这样就能避免名称重复的问题了。如果用户没有指定约束名,MySQL会自动生成一个,可能在多次操作中导致重复,特别是在多次执行相同的迁移脚本。 此,虽然错误提示更可能是约束名重复,但也不能完全排除其他可能性。比如,可能用户在被引用的表上缺少主或索引,或者字段类型不匹配,这些也可能导致创建失败,不过对应的错误信息可能不同。但根据当前的错误号121,主要问题应该还是约束名重复。 因此,我应该建议用户检查约束名称是否唯一,并在创建显式指定唯一的名称,以避免系统自动生成可能导致的冲突。同,提醒用户确保被引用字段有正确的索引,以及数据类型和字符集的一致性,以排除其他潜在问题。</think>你在 MySQL 中添加遇到的 `Error 121 "Duplicate key on write or update"` 是由于 **约束名称重复** 导致的。以下是详细解释和解决方法: --- ### **问题原因** 1. **约束名称重复** MySQL 要求每个约束(Foreign Key Constraint)在数据库中必须是**唯一命名的**。如果: - 你手动指定了一个重复的约束名(如 `CONSTRAINT fk_name`),而该名称已被其他表使用。 - 未显式命名MySQL 自动生成的默认名称与其他约束名冲突。 2. **其他可能原因(较少见)** - 被引用的表缺少主或唯一索引。 - 字段类型或字符集不匹配(通常错不同)。 --- ### **解决方法** #### 1. 检查现有约束名称 运行以下 SQL 查询,列出数据库中所有约束名,确认是否有重复: ```sql SELECT CONSTRAINT_NAME, TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'FOREIGN KEY' AND TABLE_SCHEMA = '你的数据库名'; ``` 若发现重复名称,需修改新约束名。 --- #### 2. 显式指定唯一的名称 在创建,手动指定一个唯一的名称(如 `fk_table1_table2`): ```sql ALTER TABLE table1 ADD CONSTRAINT fk_unique_name -- 修改为唯一名称 FOREIGN KEY (column_in_table1) REFERENCES table2 (column_in_table2) ON DELETE CASCADE ON UPDATE CASCADE; ``` --- #### 3. 确保被引用表满足条件 - 被引用的字段(如 `table2.column_in_table2`)必须是 **主** 或 **唯一索引**。 - 字段类型、字符集、排序规则需完全一致。 --- #### 4. 其他检查 - 如果多次运行同一脚本,确保没有重复执行创建语句。 - 检查表引擎是否支持(如 InnoDB 支持,MyISAM 不支持)。 --- ### **示例:成功添加的完整步骤** ```sql -- 1. 确认被引用字段是主或唯一索引 ALTER TABLE table2 ADD UNIQUE INDEX idx_unique_column (column_in_table2); -- 2. 添加(指定唯一名称) ALTER TABLE table1 ADD CONSTRAINT fk_table1_table2 -- 唯一名称 FOREIGN KEY (column_in_table1) REFERENCES table2 (column_in_table2) ON DELETE CASCADE ON UPDATE CASCADE; ``` 通过以上步骤,可解决重复名称问题。如果仍有错,请检查字段类型和表引擎。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值