MySQL 8.0 リファレンスマニュアル


11.3.6 SET 型

SET は、ゼロ以上の値を取ることができる文字列オブジェクトであり、それぞれの値は、テーブルの作成時に指定された許可される値のリストから選択する必要があります。 SET カラム値が複数のセットメンバーで構成される場合は、各メンバーはカンマ (,) で区切って指定されます。 このため、SET メンバーの値自体にはカンマを含めないでください。

たとえば、SET('one', 'two') NOT NULL として指定したカラムは、次に示す値のいずれかを取ります。

''
'one'
'two'
'one,two'

SET カラムには最大 64 個の個別のメンバーを含めることができます。

定義の中に重複した値が含まれていると、警告 (厳密な SQL モードが有効になっている場合はエラー) が発生します。

テーブルが作成されるときに、テーブル定義内の SET メンバー値から末尾のスペースが自動的に削除されます。

SET タイプの記憶域要件については、文字列型の格納要件 を参照してください。

SET 型の構文および長さの制限については、セクション11.3.1「文字列データ型の構文」 を参照してください。

SET カラムに格納された値は、取得されるときに、カラム定義で使用されていた大文字/小文字で表示されます。 SET カラムには、文字セットと照合順序を割り当てることができます。 バイナリ照合順序、または大文字と小文字を区別する照合順序の場合、カラムに値を割り当てるときに、大文字/小文字が考慮されます。

MySQL は、最初のセットメンバーに対応する格納値の低位ビットを使用して SET 値を数値で格納します。 SET 値を数値コンテキストで取得した場合、その取得された値には、カラム値を構成するセットメンバーに対応するビットセットが含まれます。 たとえば、次のように SET カラムから数値を取得できます。

mysql> SELECT set_col+0 FROM tbl_name;

メンバーが SET カラムに格納されると、その数字のバイナリ表現に設定されているビットからカラム値のセットメンバーが特定されます。 カラムが SET('a','b','c','d') として指定されている場合、セットメンバーは次の 10 進値と 2 進値を持ちます。

SET メンバー 10 進値 2 進値
'a' 1 0001
'b' 2 0010
'c' 4 0100
'd' 8 1000

このカラムに 9 の値を割り当てた場合、2 進数では 1001 となるため、SET 値の最初と 4 番目のメンバーである 'a''d' が選択され、結果として得られる値は 'a,d' になります。

1 つ以上の SET 要素を含む値には、値を挿入するときに要素がどの順序でリストされているかは関係ありません。 また、所定の要素が値の中で何回リストされているかも関係ありません。 あとから値を取得するときに、値内のそれぞれの要素は、テーブル作成時に指定された順序に従って、一度表示されます。 カラムが SET('a','b','c','d') として指定されているとします:

mysql> CREATE TABLE myset (col SET('a', 'b', 'c', 'd'));

'a,d''d,a''a,d,d''a,d,a'、および 'd,a,d' の値を挿入した場合、

mysql> INSERT INTO myset (col) VALUES 
-> ('a,d'), ('d,a'), ('a,d,a'), ('a,d,d'), ('d,a,d');
Query OK, 5 rows affected (0.01 sec)
Records: 5  Duplicates: 0  Warnings: 0

これらの値はすべて、取得されるときに 'a,d' と表示されます。

mysql> SELECT col FROM myset;
+------+
| col  |
+------+
| a,d  |
| a,d  |
| a,d  |
| a,d  |
| a,d  |
+------+
5 rows in set (0.04 sec)

サポートされていない値に SET カラムを設定すると、その値は無視され警告が表示されます。

mysql> INSERT INTO myset (col) VALUES ('a,d,d,s');
Query OK, 1 row affected, 1 warning (0.03 sec)

mysql> SHOW WARNINGS;
+---------+------+------------------------------------------+
| Level   | Code | Message                                  |
+---------+------+------------------------------------------+
| Warning | 1265 | Data truncated for column 'col' at row 1 |
+---------+------+------------------------------------------+
1 row in set (0.04 sec)

mysql> SELECT col FROM myset;
+------+
| col  |
+------+
| a,d  |
| a,d  |
| a,d  |
| a,d  |
| a,d  |
| a,d  |
+------+
6 rows in set (0.01 sec)

厳密な SQL モードが有効な場合、無効な SET 値を挿入しようとするとエラーが発生します。

SET 値は数値でソートされます。 NULL 値は非 NULL SET 値の前にソートされます。

数値引数を取る SUM()AVG() などの関数は、必要に応じて引数を数値にキャストします。 SET 値の場合は、キャスト操作によって数値が使用されます。

通常は、FIND_IN_SET() 関数か LIKE 演算子を使用して SET 値を検索します。

mysql> SELECT * FROM tbl_name WHERE FIND_IN_SET('value',set_col)>0;
mysql> SELECT * FROM tbl_name WHERE set_col LIKE '%value%';

最初のステートメントは set_colvalue セットメンバーを含む行を見つけます。 2 番目も似ていますが、同じではありません。ほかのセットメンバーの部分文字列としてであっても、set_colvalue を含む行を見つけます。

次のステートメントも使用できます。

mysql> SELECT * FROM tbl_name WHERE set_col & 1;
mysql> SELECT * FROM tbl_name WHERE set_col = 'val1,val2';

これらのうち最初のステートメントが最初のセットメンバーを含む値を探します。 2 番目のステートメントは正確に一致する値を探します。 2 番目の型は慎重に比較してください。 セット値を 'val1,val2' と比較すると、値を 'val2,val1' と比較した場合とは異なる結果が返されます。 カラム定義にリストされている順序どおりに値を指定する必要があります。

SET カラムの指定可能な値をすべて特定するには、SHOW COLUMNS FROM tbl_name LIKE set_col を使用して、出力の Type カラム内の SET 定義を構文解析します。

C API では、SET 値は文字列として返されます。 結果セットのメタデータを使用してこれらをほかの文字列から区別する方法については、C API Basic Data Structuresを参照してください。


関連キーワード:  カラム, col, メンバー, セット, 数値, クラス, 空間, FROM, リファレンス, 順序