Mysql 无法更改主键,因为;格式不正确的外键约束“;错误
我有一个具有以下模式定义的表:Mysql 无法更改主键,因为;格式不正确的外键约束“;错误,mysql,sql,Mysql,Sql,我有一个具有以下模式定义的表: 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`),
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-外键约束格式不正确)
停止执行
错误
重命名…时出错。。。错误号:150-外键约束格式不正确)
发生这种情况是因为您试图删除引用的主键,即使您使用SET foreign\u key\u CHECKS=0禁用外键约束检查代码>
禁用外键检查将允许您临时删除currency
表中的一行,或在外键表中添加无效的currencyId
,但不会删除主键
更改已被其他表引用的主键并不简单,因为可能会丢失表之间的引用完整性和数据之间的关系。为了保存数据,您需要一个过程,例如:
- 向每个FK表添加新的外键列(
code
)
- 通过更新映射上一个
currencyId
中的code
外键
- 删除现有的外键
- 删除旧的
currencyId
外键列
- 删除所有FK后,更改
currency
表上的主键
- 基于新的
code
列重新建立外键
无需禁用外键检查
,但需要对引用货币的所有表重复外键映射/删除/重新创建步骤:
-- Add new FK column
ALTER TABLE FKTable ADD currencyCode char(3)
CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL;
-- Map FK column to the new Primary Key
UPDATE FKTable
SET currencyCode = (SELECT `code` FROM currency WHERE id = FKTable.currencyId);
-- Drop the old foreign key + column
ALTER TABLE FKTable DROP FOREIGN KEY FKTable_Currency;
ALTER TABLE FKTable DROP COLUMN currencyId;
-- Once the above is done for all FK tables, drop the PK on currency
ALTER TABLE `currency` CHANGE COLUMN `id` `id` INT(11) NOT NULL,
DROP PRIMARY KEY;
ALTER TABLE currency ADD PRIMARY KEY (`code`);
ALTER TABLE FKTable ADD CONSTRAINT FKTable_Currency2
FOREIGN KEY (currencyCode) REFERENCES currency(`code`);
运行
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`);
请注意,为了旧代码的性能,我添加了以前的复合主键列作为新的复合索引。为什么不添加
- 删除外键
- 删除主键
- 创建主键
- 创建外键
?
我不得不承认,我现在没有多少流量(没有),只是测试了一些可以轻松恢复的数据,但对我来说效果很好。这对我帮助很大。谢谢+1在我的情况下,我创建了unique
索引,但无法删除它。我必须先创建一个primary
键,然后删除唯一的键。