假设我有一个带有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
语句完成此操作的方法?
我将要向您展示的以下技术需要钢铁般的胆量。
鉴于以下标准
/var/lib/mysql
mydb.mytb
enum_col
这是一个致命的裂缝:
CREATE TABLE mydb.mybt LIKE mydb.mytb;
ALTER TABLE mydb.mybt MODIFY enum_col ENUM('First value','Second value');
SET wait_timeout=86400; SET interactive_timeout=86400;
FLUSH TABLES WITH READ LOCK;
在单独的 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
UNLOCK TABLES;
DROP TABLE mydb.mybt;
而已 !!!
警告:我不能相信这个!
该技术来自“高性能 MySQL:优化、备份、复制等”,第 146-148 页的子标题加速ALTER TABLE下。第 147 页第 1 段说:
试试看 !(请告诉我们结果如何)
更新 2011-10-05 17:49 EDT
如果表是 MyISAM 并且您有足够的生产空间和直接停机时间窗口,请尝试以下操作:
service mysql restart --skip-networking
在单独的 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
。执行钢胆算法
mydb.mytbplay
你测试的完整性
mydb.mytbplay
如果你满意
ALTER TABLE mydb.mytb RENAME mydb.mytb_backup;
ALTER TABLE mydb.mytbplay RENAME mydb.mytb;
service mysql restart
试试看!
一个简单的解决方案是:
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
,重命名enum
为column
。注意:这个问题回到 2011-10-05,我的解决方案对 MYSQL 4.1 和更高版本(AFAIK)有效