mysql 使用外键将 int 列更改为 bigint
我想将数据库中一些主键列的数据类型从 INT 更改为 BIGINT。以下定义是一个说明问题的玩具示例:
CREATE TABLE IF NOT EXISTS `owner` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`thing_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `thing_id` (`thing_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
DROP TABLE IF EXISTS `thing`;
CREATE TABLE IF NOT EXISTS `thing` (
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
ALTER TABLE `owner`
ADD CONSTRAINT `owner_ibfk_1` FOREIGN KEY (`thing_id`) REFERENCES `thing` (`id`);
现在,当我尝试执行以下命令之一时:
ALTER TABLE `thing` CHANGE `id` `id` BIGINT NOT NULL AUTO_INCREMENT;
ALTER TABLE `owner` CHANGE `thing_id` `thing_id` BIGINT NOT NULL;
我遇到错误
#1025 - Error on rename of './debug/#[temp-name]' to './debug/[tablename]' (errno: 150)
SHOW INODB STATUS 输出:
LATEST FOREIGN KEY ERROR
------------------------
120126 13:34:03 Error in foreign key constraint of table debug/owner:
there is no index in the table which would contain
the columns as the first columns, or the data types in the
table do not match the ones in the referenced table
or one of the ON ... SET NULL columns is declared NOT NULL. Constraint:
,
CONSTRAINT "owner_ibfk_1" FOREIGN KEY ("thing_id") REFERENCES "thing" ("id")
我猜测外键定义会阻止更改列在任一侧键入。解决此问题的简单方法是删除外键定义、更改列并重新定义外键。有更好的解决方案吗?
I want to change the datatype of some primary-key columns in my database from INT to BIGINT. The following definition is a toy-example to illustrate the problem:
CREATE TABLE IF NOT EXISTS `owner` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`thing_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `thing_id` (`thing_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
DROP TABLE IF EXISTS `thing`;
CREATE TABLE IF NOT EXISTS `thing` (
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
ALTER TABLE `owner`
ADD CONSTRAINT `owner_ibfk_1` FOREIGN KEY (`thing_id`) REFERENCES `thing` (`id`);
Now when i try to execut one of the following commands:
ALTER TABLE `thing` CHANGE `id` `id` BIGINT NOT NULL AUTO_INCREMENT;
ALTER TABLE `owner` CHANGE `thing_id` `thing_id` BIGINT NOT NULL;
i'm running into an error
#1025 - Error on rename of './debug/#[temp-name]' to './debug/[tablename]' (errno: 150)
SHOW INODB STATUS outputs:
LATEST FOREIGN KEY ERROR
------------------------
120126 13:34:03 Error in foreign key constraint of table debug/owner:
there is no index in the table which would contain
the columns as the first columns, or the data types in the
table do not match the ones in the referenced table
or one of the ON ... SET NULL columns is declared NOT NULL. Constraint:
,
CONSTRAINT "owner_ibfk_1" FOREIGN KEY ("thing_id") REFERENCES "thing" ("id")
I'm guessing that the foreign key definition blocks changing the column type on either side. The naive approach to solve this problem would be to delete the foreign key definitions, alter the columns and re-define the foreign keys. is there a better solution?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
即使使用
SETforeign_key_checks = 0
,您也无法更改约束列的类型。来自 MySQL 文档: http://dev.mysql .com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
但是,即使foreign_key_checks = 0,InnoDB也不允许创建外键约束,其中列引用不匹配的列类型。
因此,我同意 Devart 的评论。只需删除它并重新创建它即可。
Even with
SET foreign_key_checks = 0
, you can't alter the type of the constraint column.From MySQL doc : http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html
However, even if foreign_key_checks = 0, InnoDB does not permit the creation of a foreign key constraint where a column references a nonmatching column type.
So, I agree with the comment of Devart. Just drop it and create it again.
我建议您在 GUI 工具中重命名这些字段 - dbForge Studio for MySQL(免费试用版):
只需在数据库资源管理器中选择要重命名的字段,单击“重构”->“重命名”命令,在打开的窗口中输入新名称,然后按“确定”,它将重命名该字段并自动重新创建所有外键。
I could suggest you to rename such fields in GUI tool - dbForge Studio for MySQL (free trial edition):
Just select the field you want to rename in the Database Explorer, click on Refactoring->Rename command, enter new name in openned window, and press OK, it will rename the field and recreate all foreign keys automatically.
即使您更改了
id
和thing_id
的列大小,行中的原始数据仍然是 4 字节整数而不是 8 字节整数。但您可以转换数据。请尝试使用此解决方案。我最近不得不对一个大型数据集做类似的事情,当数据集可能变得太大时,将 INT 列转换为 BIGINT。
Even though you changed the column size of
id
andthing_id
, the raw data in the rows is still 4 byte integers instead of 8 byte integers. But you can convert the data.Try this solution instead. I had to do something similar recently on a large data set, converting INT columns to BIGINT when the data set threatened to grow too large.
我遇到了类似的问题,解决方案是更改条款:
这对我有用。
I had a similar problem the solution is the change clause:
That worked for me.