Endo Tech Blog

Techブログと言う名のただのブログです。

MySQLのenum構文とset構文について

ここ最近MySQLというかSQLの文法を勉強している

github.com

その中でenum構文とset構文が結構使えそうだなぁと思ったので復習メモです。

enum構文

複数の値から1つだけが格納できるようにする。 MySQL の設定にもよるけど、設定した値以外をはじくことができる。 また内部的には連番で振られているので12みたいに指定できる。

コードで見てみる。

create table users (
  id int unsigned primary key auto_increment,
  name varchar(20),
  score float,
  rank enum('gold', 'silver', 'bronze')
);

enum()で囲っているgold, silver, bronzeが設定している値になっています。 ここではgold, silver, bronzeは入るけどそれ以外は入らない。 なので以下のようなsql文は通るけど

insert into users (name, score, rank) values ('endu', 5.8, 'silver');

これは当然怒られる。

insert into users (name, score, rank) values ('endu', 5.8, 'red');  
-- ERROR 1265 (01000): Data truncated for column 'rank' at row 1

で、内部的には連番なので

gold→1
silver→2
bronze→3

以下のようなSQL文を叩いてもちゃんと取得できる

select * from users where rank = 2;


+----+---------+-------+--------+
| id | name    | score | rank   |
+----+---------+-------+--------+
|  1 |endu |   5.8 | silver |
+----+---------+-------+--------+
1 row in set (0.00 sec)

set構文

上記で紹介したenum構文が1つの値しか格納できないに対して、set構文は複数入れられます。 注意する点として、挿入時に順番を変えたとしてもcreate table で定義した順番に戻っている。 したがって抽出時にはこちらの順番を守りつつ条件を指定してあげる必要があります。

コードで見てみる

create table users (
  id int unsigned primary key auto_increment,
  name varchar(20),
  score float,
  coins set('gold', 'silver', 'bronze')
);

inset文で複数の値を入れる。

insert into users (name, score, coins) values ('endu', 5.8, 'bronz,gold');
insert into users (name, score, coins) values ('endu', 5.8, 'bronz,gold');


+----+---------+-------+-------------+
| id | name    | score | coins       |
+----+---------+-------+-------------+
|  1 | taguchi |   5.8 | gold,silver |
|  2 | taguchi |   5.8 | gold,bronz  |
+----+---------+-------+-------------+

順番を入れ替えても、tableで定義した順番で入るようになっている。

またselect文で抽出する時も順番を守らないと取得できない。

OK
select * from users where coins = 'gold,silver';

NG
select * from users where coins = 'silver,gold';

なのでlike文とかで検索すると良い。

select * from users where coins like '%gold%';

おわり