MySQL ENUM sütunundaki değerleri tek bir sorguda yeniden adlandırabilir miyim?


12

Diyelim bir ile bir veritabanı tablo var ENUM('value_one','value_two'). Bunu bir olarak değiştirmek istiyorum ENUM('First value','Second value'). Şu anda bunu şu şekilde yapıyorum:

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

Bunu yapmanın daha etkili bir yolu var mı, EG bunu tek bir ALTER TABLE ifadeyle başarmanın bir yolu var mı?

Yanıtlar:


10

Size göstermek üzere olduğum follolwing tekniği, çelik bağırsaklara ihtiyaç duyacaktır.

Aşağıdaki kriterler göz önüne alındığında

  • datadir /var/lib/mysql
  • tablo mydb.mytb
  • enum sütunu denir enum_col
  • motor MyISAM

İşte ölüme meydan okuyan bir çatlak:

  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. Ayrı bir OS / SSH Oturumunda, .frm dosyalarını değiştirin

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

Bu kadar !!!

CAVEAT: BU KREDİ ALAMIYORUM!

Bu teknik, "Yüksek Performanslı MySQL: Optimizasyon, Yedeklemeler, Çoğaltma ve daha fazlası", Sayfa 146-148'den ALTER TABLE Hızlandırma Alt Başlığı altındadır . Paragraf 1 diyor ki:

Göstermek üzere olduğumuz teknik desteksiz, belgesizdir ve işe yaramayabilir. Risk altında kullanın. Önce verilerinizi yedeklemenizi öneririz!

Bir şans ver ! (Lütfen bunun nasıl ortaya çıktığını bize bildirin)

GÜNCELLEME 2011-10-05 17:49 EDT

Tablo MyISAM ise ve üretimde yeterli alanınız ve düz duruş süreniz varsa, şunu deneyin:

  1. service mysql restart --skip-networking

  2. Ayrı bir OS / SSH Oturumunda tablonun bir kopyasını oluşturun

    • 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.TABLESadlı yeni tablonun varlığını otomatik olarak algılar mydb.mytbplay.

  1. Çelik bağırsak algoritmasını mydb.mytbplay

  2. Bütünlüğünü test edersin mydb.mytbplay

Memnun olursan

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

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

  3. service mysql restart

Bir şans ver!


Ustaca bir cevap için +1! Bununla birlikte, bunu denemeyeceğim ve soru tüm müşterimin canlı, üretim veritabanları için bir yükseltme komut dosyasına atıfta bulunduğunda nasıl ortaya çıktığını size bildirmeyeceğim ;-) Ancak, bunu sadece bir geliştirme ortamında deneyebilirim eğlence için. Ama bu uyarı ile bunu asla üretimde yapmam!
Josh

3

Basit bir çözüm:

1- yeni bir sütun ekleyin:

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

2- Kolonun değerini enum2'ye değiştirerek kopyalayın:

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

3- Damla kolon column, adlandırma enumile column.

NOT : bu soru 2011-10-05'e kadar, benim çözüm MYSQL 4.1 ve daha yeni (AFAIK) için geçerlidir


Bu iyi bir çözüm gibi görünse de (ve kabul edilen cevap kadar sinir bozucu değil!), 3. adımın en az bir ALTER TABLEifade gerektirdiğini ve OP'nin sadece bir tane gerektiren bir şey aradığını belirtmek gerekir. Yine, bu mükemmel bir standart, sağlam bir çözüm gibi görünüyor dedi.
RDFozz
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.