MySQL中的一些复合数据类型

发布时间 2023-09-16 23:31:16作者: strongmore

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);

参考

MySQL的复合数据类型:ENUM和SET