重命名 MySQL 中的外键列

发布于 2024-08-16 23:54:11 字数 917 浏览 11 评论 0原文

我们正在尝试重命名 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错误1025(HY000):重命名“./foo”时出错(错误号:150)是什么意思?

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

所以现在我们'正在尝试在原始 SQL 中进行重命名。

我们是否必须先删除外键,然后重命名,然后再次添加外键?

既然这看起来相当混乱和麻烦,有什么更好的方法呢?

We're trying to rename a column in MySQL (5.1.31, InnoDB) that is a foreign key to another table.

At first, we tried to use Django-South, but came up against a known issue:

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

OperationalError: (1025, "Error on rename of './xxx/#sql-bf_4d' to './xxx/cave_event' (errno: 150)")

AND

Error on rename of './xxx/#sql-bf_4b' to './xxx/cave_event' (errno: 150)

This error 150 definitely pertains to foreign key constraints. See e.g.

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/

So now we're trying to do the renaming in raw SQL.

Do we have to drop the foreign key first, then do the rename, and then add the foreign key back again?

What is a better way, since this seems pretty confusing and cumbersome?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

双马尾 2024-08-23 23:54:12

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

AFAIK, dropping the constraint, then rename, then add the constraint back is the only way. Backup first!

帅冕 2024-08-23 23:54:12

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

alter table customer_account drop foreign key `FK3FEDF2CC1CD51BAF`; 

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

In case anyone is looking for the syntax it goes something like this:

alter table customer_account drop foreign key `FK3FEDF2CC1CD51BAF`; 

alter table customer_account  add constraint `FK3FEDF2CCD115CB1A` foreign key (campaign_id) REFERENCES campaign(id);
〆凄凉。 2024-08-23 23:54:12

这是常规键的 SQL 语法

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

here is the SQL syntax for regular keys

ALTER TABLE `thetable`
  DROP KEY `oldkey`, 
  ADD KEY `newkey` (`tablefield`);
往事风中埋 2024-08-23 23:54:12

扩展@Dewey的答案,这里有一个小脚本,用于以有用的方式重命名由Hibernate生成的FK(“FK__”+表名+“__”+引用的表名)

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

Expanding on @Dewey's answer, here's a little script to rename FKs generated by Hibernate in a useful manner ("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_%';

A bit of output:

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);
旧时浪漫 2024-08-23 23:54:12

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

The following query will build the correct syntax automatically.
Just execute each line returned and all your FKEYs will be gone.

I leave the reverse (adding them back) as an exercise for you.

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';
漆黑的白昼 2024-08-23 23:54:12

现在不需要采取额外的行动。当使用ALGORITHM = INPLACE时,MySQL/MariaDB会自动修改外键约束。

请参阅 https ://dev.mysql.com/doc/refman/8.4/en/innodb-online-ddl-operations.html#online-ddl-column-operations“重命名列”

例如以下内容是充足的:

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

No extra actions are needed nowadays. When using ALGORITHM = INPLACE, MySQL/MariaDB automatically modifies the foreign key constraint.

See https://dev.mysql.com/doc/refman/8.4/en/innodb-online-ddl-operations.html#online-ddl-column-operations "Renaming a column"

So for example the following would be sufficient:

ALTER TABLE example
    ALGORITHM = INPLACE,
    CHANGE COLUMN xxx yyy INT(11) NOT NULL;
蒗幽 2024-08-23 23:54:12

下面的代码经过测试。

  1. 首先删除旧约束 OldColumnConstrain
  2. 删除旧外键列 OldColumnName
  3. 添加数据类型为 INTEGER UNSIGNED NULL 的新外键列 NewColumnName
  4. (可选)我想要在特定列之后使用这个新外键 - AFTER previousColumn
  5. 使用引用表 t1 约束新列 newColumnConstrain >
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

The code below is tested.

  1. Drop the old constrain first OldColumnConstrain
  2. Drop the old Foreign key column OldColumnName
  3. Add the new foreign key column NewColumnName with the datatype INTEGER UNSIGNED NULL
  4. (optional) I want this new foreign key after a specific column - AFTER previousColumn
  5. Constrain the new column newColumnConstrain with the reference table 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);

Important

Running the above query will rename your Old column to a New column (not exactly renaming but deleting and adding a column), but WATCHOUT that column data will be lost and it will be replaced with NULL.

Can you ACTUALLY rename your fk?

I guess not.
See this answer https://stackoverflow.com/a/2014519/5413283

ˉ厌 2024-08-23 23:54:12

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

请参阅 IntelliJ IDEA 帮助 | 了解更多详细信息重命名项目

MySQL 5.7

This task becomes simpler if you use GUI tools. I tried to rename ID column using IntelliJ IDEA Database tool and it worked like a charm! I don't have to bother about foreign keys when renaming a table or column.

See more details in IntelliJ IDEA Help | Renaming items.

MySQL 5.7

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文