我可以在一个查询中重命名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');

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

Answers:


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:优化,备份,复制等”,标题为“加速ALTER TABLE 下的第146-148页。页面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为您提供巧妙的答案!但是,我不会尝试,并让您知道结果如何,因为该问题涉及我所有客户的实时生产数据库的升级脚本;-)但是,我可以在开发环境中尝试为了娱乐。但是有了这个警告,我将永远不会在生产中运行它!
乔什(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-删除列column,重命名enumcolumn

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


虽然这听起来像是一个很好的解决方案(并且不像公认的答案那样令人不安!),但值得注意的是,第3步确实需要至少一个ALTER TABLE声明,并且OP正在寻找仅需要一个声明的东西。再次说,这似乎是一个完美的标准,可靠的解决方案。
RDFozz
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.