Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 无法更改主键,因为;格式不正确的外键约束“;错误_Mysql_Sql - Fatal编程技术网

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
键,然后删除唯一的键。