Bisakah saya mengganti nama nilai dalam kolom ENUM MySQL dalam satu permintaan?

12

Misalkan saya memiliki tabel Database dengan ENUM('value_one','value_two'). Saya ingin mengubahnya menjadi ENUM('First value','Second value'). Saya sedang melakukan itu sebagai berikut:

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

Apakah ada cara yang lebih efisien untuk melakukan ini, EG cara untuk mencapai ini dengan satu ALTER TABLE pernyataan?

Josh
sumber

Jawaban:

10

Teknik follolwing yang akan saya tunjukkan kepada Anda akan membutuhkan nyali baja.

Diberi kriteria berikut

  • datadir adalah /var/lib/mysql
  • meja adalah mydb.mytb
  • disebut kolom enum disebut enum_col
  • Mesinnya adalah MyISAM

Berikut ini adalah celah yang menantang kematian:

  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. Dalam Sesi OS / SSH yang terpisah, tukar file .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;

Itu dia !!!

CAVEAT: SAYA TIDAK BISA MENGAMBIL KREDIT UNTUK INI!

Teknik ini berasal dari "MySQL Kinerja Tinggi: Optimalisasi, Cadangan, Replikasi, dan banyak lagi", Halaman 146-148 di bawah Subheading Mempercepat ALTER TABLE . Halaman 147 Paragraf 1 mengatakan:

Teknik yang akan kami tunjukkan tidak didukung, tidak berdokumen, dan mungkin tidak berfungsi. Gunakan dengan risiko Anda. Kami menyarankan Anda untuk mencadangkan data Anda terlebih dahulu!

Cobalah ! (Tolong beri tahu kami bagaimana hasilnya)

UPDATE 2011-10-05 17:49 EDT

Jika tabelnya adalah MyISAM dan Anda memiliki cukup ruang dalam produksi dan jendela down-up langsung, coba ini:

  1. service mysql restart --skip-networking

  2. Dalam Sesi OS / SSH yang terpisah, buat salinan tabel

    • 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.TABLESsecara otomatis akan mendeteksi keberadaan tabel baru yang disebut mydb.mytbplay.

  1. Lakukan algoritma nyali-baja pada mydb.mytbplay

  2. Anda menguji integritas mydb.mytbplay

Jika Anda puas

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

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

  3. service mysql restart

Cobalah!

RolandoMySQLDBA
sumber
+1 untuk jawaban yang cerdas! Namun, saya tidak akan mencoba ini dan memberi tahu Anda bagaimana hasilnya karena pertanyaannya mengacu pada skrip pemutakhiran untuk semua pelanggan saya, basis data produksi ;-) Namun, saya dapat mencoba ini hanya di lingkungan pengembangan untuk kesenangan. Tetapi dengan peringatan itu saya tidak pernah menjalankan ini dalam produksi!
Josh
3

Solusi sederhana adalah:

1- tambahkan kolom baru:

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

2- Salin nilai kolom ke enum2 dengan penggantian:

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

3 - Drop kolom column, ganti nama enummenjadi column.

CATATAN : pertanyaan ini kembali ke 2011-10-05, solusi saya valid untuk MYSQL 4.1 dan yang lebih baru (AFAIK)

Abdelkader Mh
sumber
Walaupun ini terdengar seperti solusi yang baik (dan tidak hampir sama menegangkannya dengan jawaban yang diterima!), Perlu dicatat bahwa langkah 3 memang membutuhkan setidaknya satu ALTER TABLEpernyataan, dan OP sedang mencari sesuatu yang hanya membutuhkan satu. Sekali lagi, itu mengatakan, sepertinya solusi yang benar-benar standar, solid.
RDFozz