138

当我试图改变我的桌子时,我得到了这个错误。

Error Code: 1833. Cannot change column 'person_id': used in a foreign key constraint 'fk_fav_food_person_id' of table 'table.favorite_food'

这是我成功运行的 CREATE TABLE STATEMENT。

CREATE TABLE favorite_food(
    person_id SMALLINT UNSIGNED,
    food VARCHAR(20),
    CONSTRAINT pk_favorite_food PRIMARY KEY(person_id,food),
    CONSTRAINT fk_fav_food_person_id FOREIGN KEY (person_id)
    REFERENCES person (person_id)
);

然后我试图执行这个语句,我得到了上面的错误。

ALTER TABLE person MODIFY person_id SMALLINT UNSIGNED AUTO_INCREMENT;
4

5 回答 5

236

您可以关闭外键检查:

SET FOREIGN_KEY_CHECKS = 0;

/* DO WHAT YOU NEED HERE */

SET FOREIGN_KEY_CHECKS = 1;

请确保不要在生产中使用它并进行备份。

于 2015-01-26T14:45:34.203 回答
146

外键字段和引用的类型和定义必须相同。这意味着您的外键不允许更改字段的类型。

一种解决方案是:

LOCK TABLES 
    favorite_food WRITE,
    person WRITE;

ALTER TABLE favorite_food
    DROP FOREIGN KEY fk_fav_food_person_id,
    MODIFY person_id SMALLINT UNSIGNED;

现在您可以更改您的 person_id

ALTER TABLE person MODIFY person_id SMALLINT UNSIGNED AUTO_INCREMENT;

重新创建外键

ALTER TABLE favorite_food
    ADD CONSTRAINT fk_fav_food_person_id FOREIGN KEY (person_id)
          REFERENCES person (person_id);

UNLOCK TABLES;

编辑: 在上面添加了锁,感谢评论

在执行此操作时,您必须禁止写入数据库,否则您将面临数据完整性问题的风险。

我在上面添加了一个写锁

除您自己的 ( INSERT, UPDATE, DELETE) 之外的任何其他会话中的所有写入查询都将等到超时或UNLOCK TABLES; 被执行

http://dev.mysql.com/doc/refman/5.5/en/lock-tables.html

编辑2:OP要求对“外键字段和引用的类型和定义必须相等。这意味着您的外键不允许更改字段的类型”这一行进行更详细的解释。

来自MySQL 5.5 参考手册:外键约束

外键和引用键中的对应列必须在 InnoDB 内部具有相似的内部数据类型,以便可以在不进行类型转换的情况下进行比较。整数类型的大小和符号必须相同。字符串类型的长度不必相同。对于非二进制(字符)字符串列,字符集和排序规则必须相同。

于 2012-11-28T13:58:43.027 回答
0

转到相关表的结构选项卡。在操作下,您有索引。放下它们

完成必要的修改后,带回外键并恢复已删除的索引。然后确保你的结构是相同的并且没有改变

于 2021-11-28T01:28:32.260 回答
0

在我的情况下,有必要添加GLOBAL.

SET FOREIGN_KEY_CHECKS = 0;
SET GLOBAL FOREIGN_KEY_CHECKS=0;

/* DO WHAT YOU NEED HERE */

SET FOREIGN_KEY_CHECKS = 1;
SET GLOBAL FOREIGN_KEY_CHECKS=1;
于 2022-02-16T17:33:03.813 回答
-3

当您设置键(主键或外键)时,您正在设置如何使用它们的限制,这反过来又限制了您可以使用它们做什么。如果你真的想改变列,你可以重新创建没有约束的表,尽管我不建议这样做。一般来说,如果你有一种情况,你想做某事,但它被一个约束所阻止,最好通过改变你想做的事情而不是约束来解决。

于 2012-11-28T13:48:03.890 回答