Переименование столбцов внешнего ключа в MySQL

Мы пытаемся переименовать столбец в 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 определенно относится к ограничениям внешнего ключа. См., Например,

Что означает ошибка mysql 1025 (HY000): Ошибка при переименовании ./foo (ошибка: 150) означает?

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

Итак, теперь мы пытаемся выполнить переименование в чистом SQL. Похоже, нам нужно сначала удалить внешний ключ, затем выполнить переименование, а затем снова добавить внешний ключ. Это звучит правильно? Есть ли способ лучше, поскольку он кажется довольно запутанным и громоздким?

Любая помощь приветствуется!


person Greg Detre    schedule 06.01.2010    source источник


Ответы (6)


AFAIK, сбросить ограничение, затем переименовать, а затем снова добавить ограничение - единственный способ. Сначала сделайте резервную копию!

person Dave Swersky    schedule 06.01.2010
comment
Начиная с MySQL 5.6.6, все внешние ключи теперь автоматически обновляются при переименовании столбца. dev.mysql.com/doc/refman/5.6/en/ alter-table.html - person BenL; 07.01.2015
comment
@BenL Это не совсем правильно. На странице говорится: До MySQL 5.6.6 добавление и удаление внешнего ключа в том же операторе ALTER TABLE в некоторых случаях могло быть проблематичным и поэтому не поддерживалось. Для каждой операции следует использовать отдельные операторы. Начиная с MySQL 5.6.6, добавление и удаление внешнего ключа в том же операторе ALTER TABLE поддерживается для ALTER TABLE ... ALGORITHM = INPLACE, но остается неподдерживаемым для ALTER TABLE ... ALGORITHM = COPY. . Кроме того, я собственными глазами видел, как MySQL 5.6.2 заменяет имя столбца в FK. Но в mySQL 5.0.94 это (пока) невозможно. - person hypercube; 28.05.2015

Если кто-то ищет синтаксис, он выглядит примерно так:

alter table customer_account drop foreign key `FK3FEDF2CC1CD51BAF`; 

alter table customer_account  add constraint `FK3FEDF2CCD115CB1A` foreign key (campaign_id) REFERENCES campaign(id);
person 34m0    schedule 19.02.2013

вот синтаксис SQL для обычных ключей

ALTER TABLE `thetable`
  DROP KEY `oldkey`, 
  ADD KEY `newkey` (`tablefield`);
person monika mevenkamp    schedule 28.09.2012

Расширяя ответ @Dewey, вот небольшой скрипт для полезного переименования FK, сгенерированных Hibernate ("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);
person Jan Żankowski    schedule 30.04.2016

Следующий запрос автоматически построит правильный синтаксис. Просто выполните каждую возвращенную строку, и все ваши 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';
person Dewey    schedule 12.04.2015

Эта задача упрощается, если вы используете инструменты с графическим интерфейсом. Я попытался переименовать столбец идентификатора с помощью инструмента базы данных IntelliJ IDEA и Оно работало завораживающе! Мне не нужно беспокоиться о внешних ключах при переименовании таблицы или столбца.

Дополнительные сведения см. В Справке IntelliJ IDEA | Переименование предметов.

MySQL 5.7

person naXa    schedule 22.11.2018