Могу ли я переименовать значения в столбце MySQL ENUM в одном запросе?

12

Предположим, у меня есть таблица базы данных с ENUM('value_one','value_two'). Я хочу изменить это на ENUM('First value','Second value'). В настоящее время я делаю это следующим образом:

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

Есть ли более эффективный способ сделать это, например, способ сделать это с помощью одного ALTER TABLE заявления?

мистифицировать
источник

Ответы:

10

Следующая техника, которую я собираюсь показать вам, требует стальных кишок.

Учитывая следующие критерии

  • Датадир /var/lib/mysql
  • стол mydb.mytb
  • enum столбец называется называется enum_col
  • двигатель MyISAM

Вот смертельная трещина в этом:

  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. В отдельной сессии OS / SSH поменяйте местами файлы .frm

    • $ 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;

Это оно !!!

ПРЕДОСТЕРЕЖЕНИЕ: Я НЕ МОГУ ЗАБРАТЬ КРЕДИТ ДЛЯ ЭТОГО!

Эта техника взята из статьи «Высокопроизводительный MySQL: оптимизация, резервное копирование, репликация и т. Д.», Страницы 146-148 в разделе «Подзаголовок, ускорение» ALTER TABLE . Страница 147 Параграф 1 говорит:

Техника, которую мы собираемся продемонстрировать, не поддерживается, не имеет документов и может не работать. Используйте это на свой риск. Мы советуем вам сначала сделать резервную копию ваших данных!

Попробуйте! (Пожалуйста, дайте нам знать, как это получилось)

ОБНОВЛЕНИЕ 2011-10-05 17:49 EDT

Если таблица - MyISAM, и у вас достаточно места на рабочем месте и окно простоя, попробуйте следующее:

  1. service mysql restart --skip-networking

  2. В отдельной сессии OS / SSH сделайте копию таблицы

    • 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.TABLESавтоматически обнаружит наличие новой таблицы с именем mydb.mytbplay.

  1. Выполните алгоритм "Стали по железу" на mydb.mytbplay

  2. Вы проверяете целостность mydb.mytbplay

Если вы удовлетворены

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

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

  3. service mysql restart

Попробуйте!

RolandoMySQLDBA
источник
+1 за гениальный ответ! Я не буду, однако, давать этому попытку и сообщать вам, как это получилось, поскольку вопрос касается сценария обновления для всех действующих, производственных баз данных моего клиента ;-) Однако я могу попробовать это в среде разработки просто ради забавы. Но с этим предупреждением я бы никогда не запустил это в производство!
Джош
3

Простое решение будет:

1- добавить новый столбец:

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

2- Скопируйте значение столбца в enum2 с заменами:

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

3- Удалить столбец column, переименовать enumв column.

ПРИМЕЧАНИЕ : этот вопрос относится к 2011-10-05, мое решение действительно для MYSQL 4.1 и новее (AFAIK)

Абделькадер Мх
источник
Хотя это звучит как хорошее решение (и не столь нервное, как принятый ответ!), Стоит отметить, что для шага 3 требуется хотя бы одно ALTER TABLEутверждение, а ОП искала что-то, что требовало только одного. Опять же, это говорит о том, что это кажется совершенно стандартным, твердым решением.
RDFozz