Kann ich die Werte in einer MySQL ENUM-Spalte in einer Abfrage umbenennen?


12

Angenommen, ich habe eine Datenbanktabelle mit einem ENUM('value_one','value_two'). Ich möchte das in ein ändern ENUM('First value','Second value'). Ich mache das momentan wie folgt:

ALTER TABLE `table` MODIFY `column` ENUM('value_one','value_two','First value','Second value');
UPDATE `table` SET `column`='First Value' WHERE `column`='value_one';
UPDATE `table` SET `column`='Second Value' WHERE `column`='value_two';
ALTER TABLE `table` MODIFY `column` ENUM('First value','Second value');

Gibt es einen effizienteren Weg, dies zu tun, EG einen Weg, dies mit einer einzigen ALTER TABLE Aussage zu erreichen?

Antworten:


10

Die folgende Technik, die ich Ihnen zeigen werde, erfordert Eingeweide aus Stahl.

Angesichts der folgenden Kriterien

  • Datadir ist /var/lib/mysql
  • Tisch ist mydb.mytb
  • Die aufgerufene Aufzählungsspalte heißt enum_col
  • Motor ist MyISAM

Hier ist ein todesmutiger Riss:

  1. CREATE TABLE mydb.mybt LIKE mydb.mytb;

  2. ALTER TABLE mydb.mybt MODIFY enum_col ENUM('First value','Second value');

  3. SET wait_timeout=86400; SET interactive_timeout=86400;

  4. FLUSH TABLES WITH READ LOCK;

  5. Tauschen Sie in einer separaten OS / SSH-Sitzung die .frm-Dateien aus

    • $ mv /var/lib/mysql/mydb/mytb.frm /var/lib/mysql/mydb/myxx.frm
    • $ mv /var/lib/mysql/mydb/mybt.frm /var/lib/mysql/mydb/mytb.frm
    • $ mv /var/lib/mysql/mydb/myxx.frm /var/lib/mysql/mydb/mybt.frm
  6. UNLOCK TABLES;

  7. DROP TABLE mydb.mybt;

Das ist es !!!

CAVEAT: Ich kann dafür keinen Kredit aufnehmen!

Diese Technik stammt aus "Hochleistungs-MySQL: Optimierung, Sicherungen, Replikation und mehr", Seiten 146-148 unter der Überschrift Beschleunigung ALTER TABELLE . In Absatz 1 heißt es:

Die Technik, die wir demonstrieren möchten, wird nicht unterstützt, ist nicht dokumentiert und funktioniert möglicherweise nicht. Verwenden Sie es auf Ihr Risiko. Wir empfehlen Ihnen, zuerst Ihre Daten zu sichern!

Versuche es ! (Bitte lassen Sie uns wissen, wie es ausgegangen ist)

UPDATE 2011-10-05 17:49 EDT

Wenn es sich bei der Tabelle um MyISAM handelt und Sie über genügend Speicherplatz in der Produktion und ein direktes Ausfallzeitfenster verfügen, versuchen Sie Folgendes:

  1. service mysql restart --skip-networking

  2. Erstellen Sie in einer separaten OS / SSH-Sitzung eine Kopie der Tabelle

    • cp /var/lib/mysql/mydb/mytb.frm /var/lib/mysql/mydb/mytbplay.frm
    • cp /var/lib/mysql/mydb/mytb.MYD /var/lib/mysql/mydb/mytbplay.MYD
    • cp /var/lib/mysql/mydb/mytb.MYI /var/lib/mysql/mydb/mytbplay.MYI

INFORMATION_SCHEMA.TABLESerkennt automatisch das Vorhandensein der neuen aufgerufenen Tabelle mydb.mytbplay.

  1. Führen Sie den Mut-of-Steel-Algorithmus an mydb.mytbplay

  2. Sie testen die Integrität von mydb.mytbplay

Wenn Sie zufrieden sind

  1. ALTER TABLE mydb.mytb RENAME mydb.mytb_backup;

  2. ALTER TABLE mydb.mytbplay RENAME mydb.mytb;

  3. service mysql restart

Versuche es!


+1 für eine geniale Antwort! Ich werde es jedoch nicht versuchen und Sie wissen lassen, wie es sich herausstellte, da sich die Frage auf ein Upgrade-Skript für alle Live-Produktionsdatenbanken meiner Kunden bezieht ;-) Ich kann dies jedoch nur in einer Entwicklungsumgebung versuchen zum Spass. Aber mit dieser Warnung würde ich das nie in der Produktion ausführen!
Josh

3

Eine einfache Lösung wäre:

1- Fügen Sie eine neue Spalte hinzu:

ALTER TABLE `table` ADD `enum2` ENUM('First value', 'Second value') NOT NULL AFTER `enum`;

2- Kopieren Sie den Wert der Spalte mit Ersetzungen in enum2:

UPDATE `table` SET enum2=REPLACE(`column`, "value_one", "new value")

3- Spalte columnlöschen, umbenennen enumin column.

HINWEIS : Diese Frage geht auf den 05.10.2011 zurück. Meine Lösung gilt für MYSQL 4.1 und höher (AFAIK).


Dies klingt zwar nach einer guten Lösung (und ist bei weitem nicht so nervenaufreibend wie die akzeptierte Antwort!), Aber es ist erwähnenswert, dass für Schritt 3 mindestens eine ALTER TABLEAussage erforderlich ist und das OP nach etwas gesucht hat, für das nur eine erforderlich ist. Auch dies scheint eine vollkommen normale, solide Lösung zu sein.
RDFozz
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.