1つのクエリで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

私があなたに見せようとしている以下のテクニックは鋼の根性を必要とするでしょう。

次の基準が与えられた場合

  • datadirは /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ページ、「ALTER TABLEの高速化」という小見出しの下にあります。147ページのパラグラフ1は言う:

これから説明する手法はサポートされておらず、文書化されておらず、機能しない可能性があります。あなたのリスクでそれを使用してください。最初にデータをバックアップすることをお勧めします!

試してみる !(どうなるか教えてください)

UPDATE 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、名前enumをに変更しcolumnます。

:この質問は2011-10-05にさかのぼります。私のソリューションはMYSQL 4.1以降(AFA​​IK)で有効です。


これは良い解決策のように聞こえますが(受け入れられた回答ほど神経質ではありません!)、ステップ3は少なくとも1つのALTER TABLEステートメントを必要とし、OPは1つだけを必要とするものを探していたことに注目する価値があります。繰り返しになりますが、これは完全に標準的な固溶体のようです。
RDFozz
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.