ENUM
は、テーブルを作成する際カラム仕様の中で明確に列挙された許容値リストから選択された値を持つ文字列オブジェクトです。列挙値は引用された文字列直定数である必要があります。
これは、式でも、文字列値を評価するものでもありません。たとえば、次のようにして
ENUM
カラムを持つテーブルを作成できます。
CREATE TABLE sizes ( name ENUM('small', 'medium', 'large') );
しかし、前述の
CREATE TABLE
ステートメントを次のように少し変えた場合は機能しません。
CREATE TABLE sizes ( c1 ENUM('small', CONCAT('med','ium'), 'large') );
また、ユーザー変数を列挙値として使用することもできません。次の 1 組のステートメントは機能しません。
SET @mysize = 'medium'; CREATE TABLE sizes ( name ENUM('small', @mysize, 'large') );
数値を列挙値として使用する場合は、引用符で囲む必要があります。
定義の中に重複した値が含まれていると、警告 (厳密な SQL モードが有効になっている場合はエラー) が発生します。
一定の状況では、空の文字列
(''
) や
NULL
を使用することもできます。
もし ENUM
に無効な値
(許容値リストに存在しない文字列)
を挿入すると、特別エラー値として空の文字列が代わりに挿入されます。この文字列は数値
0
を持つため、「通常」の空の文字列とは区別することができます。これについては、あとで詳しく説明します。
もし厳密な SQL モードが有効なら、無効な
ENUM
値を挿入しようとするとエラーが発生します。
もし ENUM
カラムが NULL
の許容を宣言すると、NULL
値はそのカラムにとって正当な値となり、デフォルト値は
NULL
になります。もし
ENUM
カラムが NOT NULL
を宣言すると、許容値リストの最初の要素がそのデフォルト値となります。
それぞれの列挙値はインデックスを持ちます。
カラム仕様の中の許容可能要素リストからの値は 1 から始まる番号がつけられています。
空の文字列エラー値のインデックス値は 0
です。つまり、次の
SELECT
ステートメントでは、無効な
ENUM
値が割り当てられている行を検索できます。
mysql> SELECT * FROM tbl_name
WHERE enum_col
=0;
NULL
値のインデックスは
NULL
です。
「インデックス」 という言葉は、列挙値リストの中の位置だけを表しています。これは、テーブルインデックスとはまったく関係がありません。
たとえば、ENUM('one', 'two',
'three')
として指定されたカラムは、次に示すどの値も取ることができます。それぞれの値のインデックスも示しています。
値 | インデックス |
NULL |
NULL |
'' |
0 |
one |
1 |
two |
2 |
three |
3 |
1 つの列挙は最大 65,535 要素を持つことができます。
テーブルが作成されたときに、テーブル定義の中の
ENUM
メンバー値から末尾のスペースが自動的に削除されます。
検索されたときは、ENUM
カラムに格納された値はカラム定義で使用されたレターケースで表示されます。ENUM
カラムはキャラクタセットと照合に指定できることを覚えて置いてください。バイナリ、またはケースに敏感な照合には、カラムに値を指定するときレターケースが考慮されます。
もし ENUM
値を数値コンテキストで検索するなら、カラム値のインデックスは返されます。たとえば、このようにして
ENUM
カラムから数値を検索することができます。
mysql> SELECT enum_col
+0 FROM tbl_name
;
もし ENUM
カラムに数字を格納すると、その数字は可能値のインデックスとして扱われ、格納された値はそのインデックスを持つ列挙メンバーとなります。(しかしこれはすべての入力を文字列として扱う
LOAD DATA
とは機能
しません)。もし数値が引用されると、列挙値リストの中に適合する文字列がなければ、そのままインデックスとして解釈されます。これらの理由により、ENUM
カラムを数字のように見える列挙値で定義することは、複雑になり得るのでお勧めできません。たとえば、次のカラムには
'0'
、'1'
、および
'2'
の文字列値を持つ列挙メンバーが指定されていますが、1
、2
、および
3
の数値インデックス値は次のようになります。
numbers ENUM('0','1','2')
2
を格納すると、それはインデックス値とみなされ、'1'
(インデックス 2 の値)
になります。'2'
を格納すると、それは列挙値と一致するので、'2'
として格納されます。'3'
を格納すると、どの列挙値とも一致しないのでインデックスとして扱われ、'2'
(インデックス 3 の値) になります。
mysql>INSERT INTO t (numbers) VALUES(2),('2'),('3');
mysql>SELECT * FROM t;
+---------+ | numbers | +---------+ | 1 | | 2 | | 2 | +---------+
ENUM
値は、カラム仕様にリストされた列挙メンバーの順番に従ってソートされます。(言い換えると、ENUM
値はそれらのインデックス番号によってソートされるということになります)。たとえば、ENUM('a',
'b')
では 'a'
が
'b'
の前にソートされますが、ENUM('b',
'a')
では 'b'
が
'a'
の前にソートされます。空の文字列は空ではない文字列の前にソートされ、NULL
値はその他のすべての列挙値の前にソートされます。予期しない結果を防ぐためには、ENUM
リストをアルファベット順に指定してください。カラムがインデックス番号ではなく、語彙的にソートされるために、GROUP
BY CAST(col AS CHAR)
か
GROUP BY CONCAT(col)
を利用することもできます。
数値引数を要求する
SUM()
や
AVG()
などの関数は、必要に応じて数値引数を数値にキャストします。ENUM
値の場合は、キャスト操作によってインデックス番号が使用されます。
ENUM
カラムに有効なすべての値を究明したければ、SHOWCOLUMNSFROM
をし、出力の
tbl_name
LIKEenum_col
Type
カラムの中の ENUM
定義を解析してください。