Как переименовать индекс в MySQL

83

Я хочу переименовать индекс. Я просмотрел документацию по изменению таблицы , но не могу понять синтаксис, чтобы просто переименовать индекс. При выполнении этого через графический интерфейс MySQL он удаляет индекс и создает новый. Хотя это работает, я бы не хотел перестраивать весь индекс только для изменения имени индекса.

[ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ]

В документации по таблице изменений указано

Изменения, которые изменяют только метаданные таблицы, но не данные таблицы, могут быть сделаны немедленно, изменив файл .frm таблицы и не касаясь содержимого таблицы. Следующие изменения - это быстрые изменения, которые можно сделать таким образом:

* Renaming a column or index.

Однако, когда я попытался переименовать индекс, отредактировав файл .frm (в тестовой базе данных) и перезапустив сервер, теперь в пользовательском интерфейсе появляется сообщение «Не удалось получить столбцы» при попытке перечислить столбцы и при попытке запустить запрос, он возвращает ошибку "Неизвестный табличный движок" "". В файле .frm много двоичного содержимого. Есть ли хороший инструмент для редактирования двоичной информации.

Кибби
источник

Ответы:

144

Я ответил на этот вопрос в 2009 году. В то время в MySQL не было синтаксиса для переименования индекса.

С тех пор в MySQL 5.7 появился ALTER TABLE RENAME INDEXсинтаксис.

http://dev.mysql.com/doc/refman/5.7/en/alter-table.html частично говорит:

  • RENAME INDEX old_index_name TO new_index_nameпереименовывает индекс. Это расширение MySQL для стандартного SQL. Содержание таблицы остается без изменений. old_index_nameдолжно быть именем существующего индекса в таблице, который не удаляется тем же ALTER TABLEоператором. new_index_name- это новое имя индекса, которое не может дублировать имя индекса в результирующей таблице после применения изменений. Ни одно имя индекса не может быть PRIMARY.

Более ранние версии MySQL, например 5.6 и более ранние, не поддерживают синтаксис ALTER TABLEдля переименования индекса (или ключа, который является синонимом).

Единственным решением было ALTER TABLE DROP KEY oldkeyname, ADD KEY newkeyname (...).

В ALTER INDEXMySQL нет команды. Можно только DROP INDEXи тогда CREATE INDEXс новым именем.


Что касается вашего обновления выше: возможно, документация недостаточно точна. Тем не менее, нет синтаксиса SQL для переименования индекса.

Индекс - это структура данных, которую можно перестроить из данных (на самом деле рекомендуется периодически перестраивать индексы с помощью OPTIMIZE TABLE). На это нужно время, но это обычная операция. Структуры данных индексов отделены от данных таблицы, поэтому добавление или удаление индекса не должно касаться данных таблицы, как говорится в документации.

Что касается .frmфайла, MySQL не поддерживает редактирование .frmфайла. Я бы не стал этого делать ни по какой причине. Вы на 100% гарантированно испортите свою таблицу и сделаете ее непригодной для использования.


Билл Карвин
источник
22
Интересный факт: стандарт SQL вообще ничего не говорит об индексах! Это чисто проблема реализации поставщика, связанная с оптимизацией, поэтому весь синтаксис, связанный с индексами, является проприетарным для всех марок баз данных SQL.
Билл Карвин,
1
Да, это примерно то, что произошло. Даже MySQL вылетал при неправильном редактировании файла. Пометить это как правильное. В идеале вы могли бы просто переименовать индекс, потому что это просто метаданные, но похоже, что функционально этого не существует.
Kibbee
61

Для MySQL 5.7:

ALTER TABLE tbl_name RENAME INDEX old_index_name TO new_index_name

Для более старых версий MySQL:

ALTER TABLE tbl_name DROP INDEX old_index_name, ADD INDEX new_index_name (...)

См. Http://dev.mysql.com/doc/refman/5.7/en/alter-table.html

Джоэлпаркерхендерсон
источник
10
Будьте осторожны, отбрасывая и добавляя новые индексы, если это большая таблица, это может занять много времени. Отличный способ сделать это на большом столе - использовать pt-online-schema-change: percona.com/doc/percona-toolkit/2.1/…
jbrahy
3

Этот вопрос был задан много лет назад, и последний раз обновлялся более полугода назад. Тем не менее, я чувствую необходимость добавить этот совет:

Если индексированный столбец используется в другом месте в качестве внешнего ключа, вы можете столкнуться с ошибкой, связанной с этим. Это может помочь:

SET FOREIGN_KEY_CHECKS = 0;
ALTER TABLE tbl DROP INDEX index_name;
ALTER TABLE tbl ADD INDEX new_index_name (indexed_column);
SET FOREIGN_KEY_CHECKS = 1;

Надеюсь, кто-то сочтет это полезным.

Ифеди Оконкво
источник
5
Плохие швы, не могли бы вы просто поменять порядок при падении и добавить? и держать проверки активными? ALTER TABLE tbl ADD INDEX new_index_name (indexed_column), DROP INDEX index_name
Пагган Се
Вероятно, это должен быть собственный ответ Puggan Se, так как это наиболее эффективный / безопасный способ для mysql до 5.7
xref
Не понимаю, как на FK повлияет индекс. Вы не изменяете данные, а только индекс данных.
gdbj
@gdbj Ограничения внешнего ключа зависят от индекса, поэтому я не думаю, что вы можете отбросить индекс, который используется ограничением внешнего ключа.
Charles Wood