ฉันสามารถเปลี่ยนชื่อค่าในคอลัมน์ 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

เทคนิค follolwing ฉันกำลังจะแสดงให้คุณเห็นว่าจะต้องมีความกล้าเหล็ก

ได้รับเกณฑ์ดังต่อไปนี้

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

แค่นั้นแหละ !!!

ถ้ำ: ฉันไม่สามารถรับเครดิตได้!

เทคนิคนี้มาจาก"MySQL ประสิทธิภาพสูง: การเพิ่มประสิทธิภาพการสำรองข้อมูลการจำลองแบบและอื่น ๆ " หน้า 146-148ภายใต้หัวข้อย่อยการเร่งความเร็วตารางการเปลี่ยนแปลง หน้า 147 ย่อหน้าที่ 1 พูดว่า:

เทคนิคที่เรากำลังจะสาธิตไม่ได้รับการสนับสนุนไม่มีเอกสารและอาจใช้งานไม่ได้ ใช้ความเสี่ยงของคุณ เราแนะนำให้คุณสำรองข้อมูลของคุณก่อน!

ให้มันลอง ! (โปรดแจ้งให้เราทราบว่าเปิดใช้งานอย่างไร)

อัพเดท 2011-10-05 17:49 EDT

หากตารางคือ MyISAM และคุณมีพื้นที่เพียงพอในการผลิตและหน้าต่างหยุดทำงานตรงให้ลองทำดังนี้:

  1. service mysql restart --skip-networking

  2. ใน OS / SSH Session แยกทำสำเนาของตาราง

    • 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. ดำเนินการอัลกอริทึม guts-of-steel 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 สำหรับคำตอบที่แยบยล! ฉันจะไม่ลองทำสิ่งนี้และบอกให้คุณรู้ว่ามันเป็นอย่างไรเมื่อคำถามนั้นอ้างถึงสคริปต์อัปเกรดสำหรับฐานข้อมูลการผลิตสดของลูกค้าทั้งหมดของฉัน ;-) ฉันอาจลองใช้สิ่งนี้ในสภาพแวดล้อมการพัฒนา เพื่อความสนุก. แต่ด้วยคำเตือนนั้นฉันจะไม่ผลิตสิ่งนี้ในการผลิต!
Josh

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- คอลัมน์ Drop columnเปลี่ยนชื่อไปenumcolumn

หมายเหตุ : คำถามนี้กลับไปยัง 2011-10-05 โซลูชันของฉันใช้ได้กับ MYSQL 4.1 และใหม่กว่า (AFAIK)


ในขณะที่สิ่งนี้ฟังดูเหมือนเป็นคำตอบที่ดี (และไม่ใกล้เคียงกับคำตอบที่ยอมรับได้!) แต่ก็น่าสังเกตว่าขั้นตอนที่ 3 นั้นต้องการALTER TABLEคำสั่งอย่างน้อยหนึ่งคำและ OP กำลังมองหาสิ่งที่ต้องการเพียงสิ่งเดียวเท่านั้น อีกครั้งที่กล่าวว่าดูเหมือนเป็นโซลูชั่นที่สมบูรณ์แบบที่เป็นมาตรฐาน
RDFozz
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.