在 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 中重命名外键列的主要内容,如果未能解决你的问题,请参考以下文章