我可以在一个查询中重命名 MySQL ENUM 列中的值吗?

Jos*_*osh 12 mysql alter-table

假设我有一个带有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');
Run Code Online (Sandbox Code Playgroud)

有没有更有效的方式来做到这一点,例如,用一个做到这一点的方式 单一的 ALTER TABLE声明?

Rol*_*DBA 10

我将要向您展示的以下技术将需要钢铁般的胆量。

鉴于以下标准

  • 数据目录是 /var/lib/mysql
  • 表是 mydb.mytb
  • 调用的枚举列被调用 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 页在副标题Speeding Up 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

试一试!


小智 5

一个简单的解决方案是:

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,重命名enumcolumn.

注意:这个问题可以追溯到 2011-10-05,我的解决方案适用于 MYSQL 4.1 和更新版本(AFAIK)

  • 虽然这听起来像是一个很好的解决方案(并且不像公认的答案那么令人伤脑筋!),但值得注意的是,步骤 3 确实需要至少一个“ALTER TABLE”语句,并且 OP 正在寻找只需要一个的东西。话虽如此,这似乎是一个完美的标准、可靠的解决方案。 (2认同)