MysqlにてEnumに値を設定しなかった場合

nomoa,Mysql

MysqlにてEnumに値を設定せずにinsertした場合の挙動が気になったのでメモ

再現手順

Docs (opens in a new tab)に従ってサンプルテーブルの作成

mysql> CREATE TABLE shirts ( name VARCHAR(40), size ENUM('x-small', 'small', 'medium', 'large', 'x-large') NOT NULL);
Query OK, 0 rows affected (0.05 sec)

mysql> show columns from shirts;
+-------+----------------------------------------------------+------+-----+---------+-------+
| Field | Type                                               | Null | Key | Default | Extra |
+-------+----------------------------------------------------+------+-----+---------+-------+
| name  | varchar(40)                                        | YES  |     | NULL    |       |
| size  | enum('x-small','small','medium','large','x-large') | NO   |     | NULL    |       |
+-------+----------------------------------------------------+------+-----+---------+-------+
2 rows in set (0.01 sec)

Enumのデフォルトの値を設定せずにinsertした場合、自動で一番最初の値が設定される。

mysql> insert into shirts (name) values ('test1');
Query OK, 1 row affected (0.01 sec)

mysql> select * from shirts;
+-------+---------+
| name  | size    |
+-------+---------+
| test1 | x-small |
+-------+---------+
1 row in set (0.01 sec)

If an ENUM column is declared to permit NULL, the NULL value is a valid value for the column, and the default value is NULL. If an ENUM column is declared NOT NULL, its default value is the first element of the list of permitted values.

まじかー、状態を表現するためにEnum使うときはDefaultの状態を設定するの理にかなってるが、今回例示したサンプルや権限設定みたいに初期値が固定できないものに対して最初の値を自動でinsertするのは問題あると思うんだけども。

SQLの記述ミスの可能性を考慮してenumの例外値を一つ増やすのも微妙。 例えばshirtsであればsize: 'none'を設定して使用された場合はアプリケーション側で例外投げるように設定する。 データベースに値が入って取得されて初めてエラーに気づけるのでこれはよろしくない。

まとめ

適切なデフォルト値を設定することを前提としてライブラリを使ってinesrtからEnumが抜けないように型で制御して避ける。

© nomoa.devRSS