ENUM()リストを変更することは可能ですか?


19

ENUM()リストの変更が不可能かどうか確信が持てなかったので、テストを行いました。MySQL v5.1.58では、タイプENUM( 'yes'、 'no')の 'bool'という1つのフィールドを含むテストInnoDBテーブルを作成しました。

それから私は実行しました...

ALTER TABLE  `test`
CHANGE  `bool`  `bool` ENUM(  'yes',  'no',  'maybe' )
CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL

...そしてそれは働いた。

私は何か間違ったことをしましたか?dbエンジンに依存していますか?
誰もがENUM()リストの変更は不可能だと言うのはなぜですか?例えば。こちらhttp://komlenic.com/244/8-reasons-why-mysqls-enum-data-type-is-evil/


3
あなたが言及した記事は不可能だとは言っていません。エンジンがテーブル全体をスキャンするため、メンバーリストの変更には費用がかかると言われています。
a1ex07

10月にENUMについてのリンク(dba.stackexchange.com/a/6966/877)について言及しました。さらに、これを行う方法に関するリファレンスをMyISAM(dba.stackexchange.com/a/6548/877)に投稿しました。この場合、InnoDBは問題外です。
-RolandoMySQLDBA

回答:


14

テーブルが空である限り、問題はありません。ENUMの新しい値が追加され、テーブルにデータが入力されても名前が変更されない限り、問題ありません。

質問で再定義したENUMは、テストテーブルが最後に記憶したため、実際にはyesおよびnoの元の内部値を保持していました。

次は、データが入力されたテーブルに適用されます。

これはどうですか?

ALTER TABLE  `test`
CHANGE  `bool`  `bool` ENUM(  'no',  'yes',  'maybe' )
CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL

これで問題が発生しました。完全に設定されたテーブルのENUM値は、内部値が逆になり、yesがnoになり、noがyesになります。

これはどうですか?

ALTER TABLE  `test`
CHANGE  `bool`  `bool` ENUM(  'maybe', 'no',  'yes' )
CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL

大問題。移入されたテーブルでは、はいは多分そうです。yesで挿入された新しい行は、多分意味があるため、前のyes行から切断されます。

概要

MyISAMでこれを非常に迅速に行うには、非常にリスクの高い餌とスイッチのテクニックがあります。ibdata1とのテーブルスペースIDの相互作用のため、InnoDBでこれを行うことを強くお勧めします。


したがって、内部的には、ENUM()の順序に基づいてintとして保存されます。たとえば、ENUM( 'yes'、 'no'、 'maybe')は、 'yes'の場合​​は0、 'no'の場合は1、 'maybe'の場合は2を内部的に格納します。テーブルのメタデータは、ENUM( 'yes' => 0、 'no' => 1、 'maybe' => 2)ではなく、ENUM( 'yes'、 'no'、 'maybe')のようなものだと思います。本当ですか?
Aalexガビ

ENUMは整数ではなく文字列です:dev.mysql.com/doc/refman/5.0/en/enum.html
RolandoMySQLDBA

私はENUMが文字列であることに同意しますが、内部的には文字列として保存されていませんか?
Aalexガビ

1
あなたはこれで正しいです。私が提供したリンクには、文字列から整数へのメタデータとしてのマッピングがあります。このフレーズを探してくださいFor example, a column specified as ENUM('one', 'two', 'three') can have any of the values shown here. The index of each value is also shown.。値/インデックスマップは概念化されています。したがって、内部インデックス番号に関連付けられたテーブルにはENUM値があります。文字列を再配置すると、メタデータのインデックス作成が再配置されます。これは、ENUMを再定義する際に、データが取り込まれたテーブルに適切ではありません。
RolandoMySQLDBA

2
少なくともMariaDB / InnoDBについては、これはもう有効ではないと言えます。ENUMの中央を変更すると、値が削除または変更されるレコードが存在しない限り、他の値はそのままになります。唯一の利点は、テーブルを再構築する必要があることです。
ヌーノ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.