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');
これを行うためのより効率的な方法はありますか? singleALTER 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;
_
それでおしまい !!!
警告:私はこのために信用を得ることができません!
この手法は "High Performance MySQL:Optimization、Backups、Replication、and more"、Pages 146-148 under the subheadingSpeeding Up ALTER TABLE。 147ページのパラグラフ1は言う:
これから説明する手法はサポートされておらず、文書化されておらず、機能しない可能性があります。あなたのリスクでそれを使用してください。最初にデータをバックアップすることをお勧めします!
試してみる ! (どうなるか教えてください)
UPDATE 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
_でguts-of-steelアルゴリズムを実行する
_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
に変更します。
[〜#〜] note [〜#〜]:この質問は2011-10-05に戻って、私の解決策はMYSQL 4.1以降で有効(AFAIK)