MySQL中的一些复合数据类型
ENUM 枚举类型
ENUM适合于只能在一组固定值中选一个的场景,比如性别只能为男或者女。
ENUM的优势在于:
- 只能在固定值中选择,可以在数据库层面限制非法值。
- 数据的存储用数字来存储,占用空间少。
但是它的使用有很多需要我们注意的地方,一不小心就会得到错误的结果。
create table test (name varchar(40), sex enum('male', 'female') );
ENUM类型数据存储的实际值是索引值,如上面的ENUM('male', 'female')的sex字段所有值为:
字面值 | 存储值 |
---|---|
NULL | NULL |
'' | 0 |
'male' | 1 |
'female' | 2 |
在查询的时候又会将这个编码过的数字转为实际的值。这种存储和查询的方式会导致一些处理数字的函数,也会使用存储的值来进行计算,如SUM()和AVG()。
SET集合类型
SET和ENUM类型非常相似,它适合于只能在一组固定值中选零个或多个的场景,比如一个人喜欢的颜色可以为红、黄、蓝等颜色中的一个或多个,也可以都不喜欢。
SET的优势和ENUM也相似,在于:
- 只能在固定值中选择,可以在数据库层面限制非法值。
- 数据的存储用数字来存储,占用空间少。但在枚举值数量很多,而枚举值字符数少时这一可能不成立。
create table test2 (name varchar(40), color set('red', 'green', 'blue', 'yellow'));
SET类型数据存储的实际值是索引值的和,我们所有枚举值都是按照列表中的索引值进行存储的,不同的是通过设置二进制数为1的位置,即2的幂次方。如上面的SET('red', 'blue', 'green', 'yellow')的color字段所有值为:
枚举值 | 二进制值 | 十进制数字 |
---|---|---|
red | 0001 | 1 |
green | 0010 | 2 |
blue | 0100 | 4 |
yellow | 1000 | 8 |
而当有多个值时,通过所有值的求和得到存储的值。因此存储的数据量变少了,当取出的时候编码过的数字又会被转义成实际的字符串。这种存储和查询的方式会导致一些处理数字的函数,也会使用存储的值来进行计算,如SUM()和AVG()。
由于set类型的特殊性,因此有专用的查找函数:
insert into test2(name,color) VALUES('lisi','red,blue');
select * from test2 where find_in_set('red', color);