Jak zmienić nazwę indeksu w MySQL

83

Chciałbym zmienić nazwę indeksu. Przejrzałem dokumentację tablicy alter , ale nie potrafię wymyślić składni, aby zmienić nazwę indeksu. Robiąc to przez GUI MySQL, porzuca indeks i tworzy nowy. Chociaż to działa, chciałbym uniknąć przebudowywania całego indeksu tylko po to, aby zmienić nazwę indeksu.

[DODATKOWE INFORMACJE]

W dokumentacji tablicy alter stwierdza

Zmiany, które modyfikują tylko metadane tabeli, a nie dane tabeli, można wprowadzić natychmiast, zmieniając plik .frm tabeli i nie dotykając zawartości tabeli. Następujące zmiany to szybkie zmiany, które można wprowadzić w ten sposób:

* Renaming a column or index.

Jednak gdy próbowałem zmienić nazwę indeksu, edytując plik .frm (w testowej bazie danych) i ponownie uruchamiając serwer, w interfejsie użytkownika pojawia się teraz komunikat „Nie można pobrać kolumn” podczas próby wyświetlenia kolumn i podczas próby uruchomienia zapytanie, zwraca błąd „Nieznany silnik tabeli ''”. Plik .frm zawiera dużo zawartości binarnej. Czy istnieje dobre narzędzie do edycji informacji binarnych?

Kibbee
źródło

Odpowiedzi:

144

Odpowiedziałem na to pytanie w 2009 roku. W tamtym czasie w MySQL nie było żadnej składni umożliwiającej zmianę nazwy indeksu.

Od tego czasu MySQL 5.7 wprowadził ALTER TABLE RENAME INDEXskładnię.

http://dev.mysql.com/doc/refman/5.7/en/alter-table.html mówi częściowo:

  • RENAME INDEX old_index_name TO new_index_namezmienia nazwę indeksu. To jest rozszerzenie MySQL w stosunku do standardowego SQL. Zawartość tabeli pozostaje niezmieniona. old_index_namemusi być nazwą istniejącego indeksu w tabeli, który nie jest usuwany przez tę samą ALTER TABLEinstrukcję. new_index_nameto nowa nazwa indeksu, która nie może powielać nazwy indeksu w tabeli wynikowej po zastosowaniu zmian. Żadna nazwa indeksu nie może być PRIMARY.

Wcześniejsze wersje MySQL, np. 5.6 i wcześniejsze, nie obsługują składni ALTER TABLEzmiany nazwy indeksu (lub klucza, który jest synonimem).

Jedynym rozwiązaniem było ALTER TABLE DROP KEY oldkeyname, ADD KEY newkeyname (...).

W ALTER INDEXMySQL nie ma polecenia. Możesz tylko DROP INDEXi wtedy CREATE INDEXz nową nazwą.


Odnośnie twojej aktualizacji powyżej: być może dokumentacja nie jest wystarczająco dokładna. Niezależnie od tego nie ma składni SQL umożliwiającej zmianę nazwy indeksu.

Indeks to struktura danych, którą można odbudować na podstawie danych (w rzeczywistości zaleca się okresowe przebudowywanie indeksów OPTIMIZE TABLE). Zajmuje to trochę czasu, ale to normalna operacja. Struktury danych indeksów są niezależne od danych tabeli, więc dodawanie lub usuwanie indeksu nie powinno wymagać dotykania danych tabeli, jak mówi dokumentacja.

Jeśli chodzi o .frmplik, MySQL nie obsługuje edycji .frmpliku. Nie zrobiłbym tego z żadnego powodu. Masz 100% gwarancji uszkodzenia stołu i uczynienia go bezużytecznym.


Bill Karwin
źródło
22
Ciekawostka: standard SQL nic nie mówi o indeksach! Jest to wyłącznie kwestia implementacji dostawcy związana z optymalizacją, więc cała składnia związana z indeksami jest zastrzeżona we wszystkich markach baz danych SQL.
Bill Karwin
1
Tak, tak się właściwie stało. Nawet spowodował awarię MySQL podczas nieprawidłowej edycji pliku. Oznaczając to jako poprawne. Idealnie byłoby po prostu zmienić nazwę indeksu, ponieważ to tylko metadane, ale wygląda na to, że funkcjonalnie nie istnieje.
Kibbee
61

W przypadku MySQL 5.7:

ALTER TABLE tbl_name RENAME INDEX old_index_name TO new_index_name

Dla starszych wersji MySQL:

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

Zobacz http://dev.mysql.com/doc/refman/5.7/en/alter-table.html

joelparkerhenderson
źródło
10
Uważaj na upuszczanie i dodawanie nowych indeksów, jeśli jest to duża tabela, może to zająć dużo czasu. Świetnym
jbrahy
3

To pytanie zostało zadane wieki temu, a ostatnio zostało zaktualizowane ponad pół roku temu. Wciąż czuję potrzebę dodania tej wskazówki:

Jeśli indeksowana kolumna jest używana w innym miejscu jako klucz obcy, możesz napotkać błąd z tym związany. Może to pomóc:

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;

Mam nadzieję, że ktoś uzna to za przydatne.

Ifedi Okonkwo
źródło
5
To wygląda źle, czy nie mógłbyś po prostu zmienić kolejności i dodać? i utrzymywać aktywne czeki? ALTER TABLE tbl ADD INDEX new_index_name (indexed_column), DROP INDEX index_name
Puggan Se
Prawdopodobnie powinienem zrobić to własną odpowiedzią Puggan Se, ponieważ jest to najbardziej wydajny / najbezpieczniejszy sposób dla mysql przed 5.7
xref
Nie wiadomo, jak indeks wpłynie na FK. Nie zmieniasz danych, tylko indeks danych.
gdbj
@gdbj Ograniczenia klucza obcego zależą od indeksu, więc nie sądzę, aby można było usunąć indeks, który jest używany przez ograniczenie klucza obcego.
Charles Wood