重命名 MySQL 中的外键列

问题描述 投票:0回答:8

我们正在尝试重命名 MySQL(5.1.31,InnoDB)中作为另一个表的外键的列。

起初,我们尝试使用 Django-South,但遇到了一个已知问题:

http://south.aeracode.org/ticket/243

操作错误:(1025,“将'./xxx/#sql-bf_4d'重命名为'./xxx/cave_event'时出错(errno:150)”)

并且

将“./xxx/#sql-bf_4b”重命名为“./xxx/cave_event”时出错(errno:150)

这个错误 150 肯定与外键约束有关。参见例如

mysql error 1025 (HY000): Error on rename of './foo' (errorno: 150) 是什么意思?

http://www.xaprb.com/blog/2006/08/22/mysqls-error-1025-explained/

所以,现在我们尝试在原始 SQL 中进行重命名。看来我们必须先删除外键,然后重命名,然后再次添加外键。听起来对吗?有没有更好的方法,因为这看起来相当混乱和麻烦?

任何帮助将不胜感激!

sql mysql foreign-keys mysql-error-1025
8个回答
61
投票

AFAIK,删除约束,然后重命名,然后添加回约束是唯一的方法。 先备份!


29
投票

如果有人正在寻找语法,它会是这样的:

alter table customer_account drop foreign key `FK3FEDF2CC1CD51BAF`; 

alter table customer_account  add constraint `FK3FEDF2CCD115CB1A` foreign key (campaign_id) REFERENCES campaign(id);

3
投票

这是常规键的 SQL 语法

ALTER TABLE `thetable`
  DROP KEY `oldkey`, 
  ADD KEY `newkey` (`tablefield`);

1
投票

扩展 @Dewey 的答案,这里有一个小脚本,可以以有用的方式重命名 Hibernate 生成的 FK

("FK__" + table name + "__" + referenced table name)

SELECT CONCAT(
  "alter table ", TABLE_NAME, " drop foreign key ", CONSTRAINT_NAME,";\n",
  "alter table ", TABLE_NAME, " drop key ", CONSTRAINT_NAME, ";\n",
  "alter table ", TABLE_NAME, " add key FK__", table_name, "__",
      referenced_table_name, " (", column_name, ");\n",
  "alter table ", TABLE_NAME, " add constraint FK__", table_name, "__",
      referenced_table_name , " foreign key (", column_name, ") ",
      "references ", referenced_table_name,
      "(", referenced_column_name, ");"
  ) AS runMe 
FROM
  information_schema.key_column_usage
WHERE 
  TABLE_SCHEMA='myschemaname' 
  AND 
  constraint_name like 'FK_%';

一点输出:

alter table visitor_browsers drop foreign key FK_4ygermmic4fujggq1kp96dx47;
alter table visitor_browsers drop key FK_4ygermmic4fujggq1kp96dx47;
alter table visitor_browsers add key FK__visitor_browsers__websites (website);
alter table visitor_browsers add constraint FK__visitor_browsers__websites foreign key (website) references websites(id);

0
投票

以下查询将自动构建正确的语法。 只需执行返回的每一行,您所有的 FKEY 就会消失。

我把相反的部分(把它们加回来)留给你作为练习。

SELECT CONCAT("alter table ", TABLE_NAME," drop foreign key `", CONSTRAINT_NAME,"`; ") AS runMe
FROM information_schema.key_column_usage 
WHERE TABLE_SCHEMA='MY_SCHEMA_NAME';

0
投票

2022 年 3 月

我知道这个问题已经很老了,但是如果有人正在寻找带有解释的答案,那么这里就是。下面的代码已经过测试。

  1. 首先删除旧的约束
    OldColumnConstrain
  2. 删除旧的外键列
    OldColumnName
  3. 添加新的外键列
    NewColumnName
    ,数据类型为
    INTEGER UNSIGNED NULL
  4. (可选)我想要在特定列之后添加这个新外键 -
    AFTER previousColumn
  5. 使用参考表
    newColumnConstrain
     约束新列 
    t1
ALTER TABLE t1
DROP FOREIGN KEY OldColumnConstrain,
DROP COLUMN OldColumnName,
ADD NewColumnName INTEGER UNSIGNED NULL AFTER previousColumn,
ADD CONSTRAINT newColumnConstrain FOREIGN KEY (NewColumnName) REFERENCES t2(id);

重要

运行上述查询会将旧列重命名为新列(不完全是重命名,而是删除和添加列),但请注意列数据将丢失,并将被替换为

NULL

你真的可以重命名你的fk吗?

我想不是。如果我找到解决方案,我会更新这个答案。
请参阅此答案https://stackoverflow.com/a/2014519/5413283


0
投票

现在不需要采取额外的行动。当使用

ALGORITHM = INPLACE
时,MySQL/MariaDB会自动修改外键约束。

因此,例如以下内容就足够了:

ALTER TABLE `example`
    ALGORITHM = INPLACE,
    CHANGE COLUMN `xxx` `yyy` INT(11) NOT NULL;

-2
投票

如果您使用 GUI 工具,此任务会变得更简单。我尝试使用 IntelliJ IDEA Database tool 重命名 ID 列,效果非常好!重命名表或列时,我不必担心外键。

查看更多详细信息 IntelliJ IDEA 帮助 |重命名项目

MySQL 5.7

© www.soinside.com 2019 - 2024. All rights reserved.