13

我想将数据库中某些主键列的数据类型从 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)

显示 INODB 状态输出:

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")

我猜外键定义会阻止更改任一侧的列类型。解决此问题的简单方法是删除外键定义、更改列并重新定义外键。有更好的解决方案吗?

4

4 回答 4

7

即使使用SET foreign_key_checks = 0,您也无法更改约束列的类型。来自 MySQL 文档: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.

所以,我同意德瓦特的评论。只需放下它并再次创建它。

于 2012-01-26T15:47:39.080 回答
3

我可以建议您在 GUI 工具 - dbForge Studio for MySQL(免费试用版)中重命名这些字段:

只需在数据库资源管理器中选择要重命名的字段,单击重构->重命名命令,在打开的窗口中输入新名称,然后按确定,它将自动重命名字段并重新创建所有外键。

于 2012-01-26T14:50:00.673 回答
0

即使您更改了 and 的列大小,idthing_id中的原始数据仍然是 4 字节整数,而不是 8 字节整数。但是你可以转换数据。

请尝试此解决方案。我最近不得不在一个大型数据集上做类似的事情,当数据集可能变得太大时,将 INT 列转换为 BIGINT。

ALTER TABLE `owner`
DROP FOREIGN KEY `owner_ibfk_1`;

ALTER TABLE `thing` CHANGE `id` `id` BIGINT NOT NULL AUTO_INCREMENT;
ALTER TABLE `owner` CHANGE `thing_id` `thing_id` BIGINT NOT NULL;

UPDATE `thing` SET `id` = CAST(`id` AS UNSIGNED INTEGER);
UPDATE `owner` SET `thing_id` = CAST(`thing_id` AS UNSIGNED INTEGER);

-- Now the data are BIGINTs; re-create the foreign key constraint

ALTER TABLE `owner`
  ADD CONSTRAINT `owner_ibfk_1` FOREIGN KEY (`thing_id`) REFERENCES `thing` (`id`);
于 2021-01-17T10:20:50.017 回答
-1

我有一个类似的问题,解决方案是更改条款:

ALTER TABLE table_name CHANGE id id BIGINT(20) NOT NULL AUTO_INCREMENT;

这对我有用。

于 2014-07-11T07:59:24.797 回答