无法更改外键约束中使用的列

时间:2012-11-28 13:42:57

标签: mysql

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

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;

3 个答案:

答案 0 :(得分:150)

您可以关闭外键检查:

SET FOREIGN_KEY_CHECKS = 0;

/* DO WHAT YOU NEED HERE */

SET FOREIGN_KEY_CHECKS = 1;

请确保不要在制作中使用此功能并进行备份。

答案 1 :(得分:91)

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

一个解决方案就是:

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 Reference Manual: FOREIGN KEY Constraints

  

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

答案 2 :(得分:-1)

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