サーチ…


なぜENUM?

ENUMは行の属性を提供する方法を提供します。少数の非数値オプションを持つ属性が最適に機能します。例:

reply ENUM('yes', 'no')
gender ENUM('male', 'female', 'other', 'decline-to-state')

値は文字列です。

INSERT ... VALUES ('yes', 'female')
SELECT ... --> yes female

代案としてのTINYINT

私たちが持っているとしましょう

type ENUM('fish','mammal','bird')

代わりに

type TINYINT UNSIGNED

プラス

CREATE TABLE AnimalTypes (
    type TINYINT UNSIGNED NOT NULL AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL  COMMENT "('fish','mammal','bird')",
    PRIMARY KEY(type),
    INDEX(name)
) ENGINE=InnoDB

これは多対多のテーブルに非常によく似ています。

比較、そしてENUMより良いか悪いか:

  • (悪化する)INSERT: typeを検索する必要がある
  • (悪い)SELECT:文字列を取得するためにJOINする必要があります(ENUMはあなたに努力のストリングを与えます)
  • (より良い)新しいタイプの追加:単にこのテーブルに挿入します。 ENUMでは、ALTER TABLEを実行する必要があります。
  • (同じ)いずれのテクニック(255までの値用)でも1バイトしかかかりません。
  • (混在)データの整合性の問題もあります: TINYINTは無効な値をTINYINTます。 ENUMは特殊な空ストリング値に設定します(厳密なSQLモードが有効になっていない場合は拒否されます)。ルックアップテーブルに外部キーを設定することで、 TINYINTデータ整合性をTINYINTさせることができます。これは、適切なクエリ/結合を使用しても、他のテーブルに到達するためのコストはわずかです。 ( FOREIGN KEYsは無料ではありません)

代わりのVARCHAR

私たちが持っているとしましょう

type ENUM('fish','mammal','bird')

代わりに

type VARCHAR(20)  COMENT "fish, bird, etc"

これは、新しいタイプが簡単に追加されるという点で、全く自由である。

比較、そしてENUMより良いか悪いか:

  • (同じ)INSERT:単に文字列を提供する
  • (悪化しますか?)INSERTではタイプミスが気付かれません
  • (同じ)SELECT:実際の文字列が返されます
  • (悪化する)より多くのスペースが消費される

新しいオプションを追加する

ALTER TABLE tbl MODIFY COLUMN type ENUM('fish','mammal','bird','insect');

ノート

  • MODIFY COLUMNのすべてのケースと同様に、 NOT NULLと元々存在していた他の修飾子も含めなければなりNOT NULL 。それ以外の場合は失われます。
  • あなたがリストの最後に追加し、リストが256の項目の下にある場合はALTER単にスキーマを変更することで行われます。つまり、長いテーブルコピーはありません。 (旧バージョンのMySQLにはこの最適化がありませんでした。)

NULLとNOT NULL

NULLと 'bad-value'がNULL可能な列とNULL可能でない列に格納されているときにどうなるかの例。また、 +0を介して数値へのキャストの使用法も表示されます。

CREATE TABLE enum (
    e     ENUM('yes', 'no')   NOT NULL,
    enull ENUM('x', 'y', 'z')     NULL
        );
INSERT INTO enum (e, enull)
    VALUES
        ('yes', 'x'),
        ('no',  'y'),
        (NULL,  NULL),
        ('bad-value', 'bad-value');
Query OK, 4 rows affected, 3 warnings (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 3

mysql>SHOW WARNINGS;
+---------+------+--------------------------------------------+
| Level   | Code | Message                                    |
+---------+------+--------------------------------------------+
| Warning | 1048 | Column 'e' cannot be null                  | 
| Warning | 1265 | Data truncated for column 'e' at row 4     |
| Warning | 1265 | Data truncated for column 'enull' at row 4 |
+---------+------+--------------------------------------------+
3 rows in set (0.00 sec)

それらの挿入の後のテーブルには何が入っていますか?これは "+0"を使用して数値にキャストし、何が格納されているかを確認します。

mysql>SELECT e, e+0 FROM enum;
+-----+-----+
| e   | e+0 |
+-----+-----+
| yes |   1 |
| no  |   2 |
|     |   0 |  -- NULL
|     |   0 |  -- 'bad-value'
+-----+-----+
4 rows in set (0.00 sec)

mysql>SELECT enull, enull+0 FROM enum;
+-------+---------+
| enull | enull+0 |
+-------+---------+
| x     |       1 |
| y     |       2 |
| NULL  |    NULL |
|       |       0 |  -- 'bad-value'
+-------+---------+
4 rows in set (0.00 sec)


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow