在 MySQL 中重命名外键列

Posted

技术标签:

【中文标题】在 MySQL 中重命名外键列【英文标题】:Renaming foreign-key columns in MySQL 【发布时间】:2011-01-02 03:19:08 【问题描述】:

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

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

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

OperationalError: (1025, "将 './xxx/#sql-bf_4d' 重命名为 './xxx/cave_event' 时出错 (errno: 150)")

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

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

What does mysql error 1025 (HY000): Error on rename of './foo' (errorno: 150) mean?

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

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

任何帮助将不胜感激!

【问题讨论】:

How do I rename a foreign key in mysql?的可能重复 【参考方案1】:

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

【讨论】:

自 MySQL 5.6.6 起,所有外键现在在重命名列时会自动更新。 dev.mysql.com/doc/refman/5.6/en/alter-table.html @BenL 这并不完全正确。该页面说:“在 MySQL 5.6.6 之前,在同一 ALTER TABLE 语句中添加和删除外键在某些情况下可能会出现问题,因此不受支持。每个操作应使用单独的语句。从 MySQL 5.6.6 开始, ALTER TABLE ... ALGORITHM=INPLACE 支持在同一 ALTER TABLE 语句中添加和删除外键,但 ALTER TABLE ... ALGORITHM=COPY 仍然不支持。”。此外,我亲眼看到 MySQL 5.6.2 替换了 FK 中的列名。但在 mySQL 5.0.94 中,这(还)不可能。【参考方案2】:

如果有人在寻找语法,它会变成这样:

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`);

【讨论】:

【参考方案4】:

扩展@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);

【讨论】:

【参考方案5】:

以下查询将自动构建正确的语法。 只需执行返回的每一行,您的所有 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';

【讨论】:

【参考方案6】:

如果您使用 GUI 工具,此任务会变得更简单。我尝试使用 IntelliJ IDEA Database tool 重命名 ID 列,它就像一个魅力!重命名表或列时,我不必担心外键。

在IntelliJ IDEA Help | Renaming items查看更多详情。

【讨论】:

以上是关于在 MySQL 中重命名外键列的主要内容,如果未能解决你的问题,请参考以下文章

#1025 - mysql 中重命名错误(错误号:150)

在 Entity Framework Core 中重命名外键而不删除数据

在 MySQL 中重命名表

如何在mysql中重命名数据库? [复制]

如何在 MySQL 中重命名模式

如何在 MySQL 的一个原子操作中重命名两个表