Чи можна перейменувати значення в стовпці 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');

Чи є більш ефективний спосіб зробити це, EG спосіб - це досягти за допомогою одного ALTER TABLE твердження?

Відповіді:


10

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

Дано наступні критерії

  • datadir є /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;

Це воно !!!

CAVEAT: Я НЕ МОЖУ ВЗАЙМАТИ КРЕДИТ ЗА ЦЕЙ!

Цей метод виходить з «High Performance MySQL: Оптимізація, резервне копіювання, реплікація, і багато іншого», сторінки 146-148 під підзаголовком прискорюючи ALTER TABLE . Page 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

Спробувати!


+1 за геніальну відповідь! Я, однак, не намагаюся це спробувати і повідомити вам, як виявилося, оскільки питання стосується сценарію оновлення для всього життя моїх клієнтів, виробничих баз даних ;-) Я, однак, можу спробувати це в середовищі розробки просто для розваги. Але з цим попередженням я ніколи не запускав би це у виробництві!
Джош

3

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

1- додати новий стовпець:

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

2- Скопіюйте значення стовпця в en22 із замінами:

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.