【问题标题】:Renaming foreign-key columns in MySQL在 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 中进行重命名。看起来我们将不得不先删除外键,然后进行重命名,然后再次添加外键。听起来对吗?有没有更好的方法,因为这看起来很混乱和麻烦?

任何帮助将不胜感激!

【问题讨论】:

标签: sql mysql foreign-keys mysql-error-1025


【解决方案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查看更多详情。

          【讨论】:

            猜你喜欢
            • 2011-09-05
            • 2011-02-11
            • 1970-01-01
            • 1970-01-01
            • 2014-10-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多