我有一个具有以下架构定义的表:
CREATE TABLE `currency` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`code` char(3) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL
PRIMARY KEY (`id`),
UNIQUE KEY `code_UNIQUE` (`code`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
我想要的是删除id
列并将code
作为新的主键。并且其他一些表具有此表的外键。我尝试了以下命令但失败了:
SET FOREIGN_KEY_CHECKS=0;
ALTER TABLE `currency` CHANGE COLUMN `id` `id` INT(11) NOT NULL, DROP PRIMARY KEY;
ALTER TABLE currency ADD PRIMARY KEY (code);
SET FOREIGN_KEY_CHECKS=1;
MySQL抛出以下异常:
[查询2中的错误]将“./db/#sql-849_1”重命名为“./db/currency”时出错(错误号:150 - 错误地形成了外键约束) 执行停止了!
答案 0 :(得分:12)
错误
重命名时错误...错误号:150 - 外键约束形成错误)
发生是因为您尝试删除引用的主键,即使您使用SET FOREIGN_KEY_CHECKS=0;
禁用外键约束检查
禁用外键检查将允许您临时删除currency
表中的行或在外键表中添加无效的currencyId
,但不能删除主键。
更改已被其他表引用的PRIMARY KEY并不简单,因为您可能会丢失表之间的参照完整性并丢失数据之间的关系。为了保存数据,您需要一个过程,例如:
code
)code
的{{1}}外键
currencyId
外键列currencyId
表格上的主键currency
列以下操作无需禁用code
,但需要对引用FOREIGN_KEY_CHECKS
的所有表重复执行外键映射/删除/重新创建步骤:
currency
答案 1 :(得分:3)
正在运行
ALTER TABLE myTable DROP PRIMARY KEY;
导致错误,如
`Error Code: 1025. Error on rename of 'some_name' to 'another_name' (errno: 150 - Foreign key constraint is incorrectly formed)`
删除,创建新列并将其添加为主键 all 作为一个单一命令就像一个魅力。
即使我不知道根本原因,但这是我提出的最终解决方案:
-- Suppose c1 and c2 are a composite primary key and
-- I want to add an incremental primary key named id
ALTER TABLE myTable
DROP PRIMARY KEY,
ADD id INT(10) UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST,
ADD INDEX `an_index_name_for_c1_c2` (`c1`, `c2`);
请注意,为了遗留代码的性能,我将以前的复合主键列添加为新的复合索引。
答案 2 :(得分:0)
为什么不
?
我必须承认我现在(没有)的流量不多,只是测试了可以轻松恢复的数据,但这对我来说很好。