力扣刷题的时候碰见枚举类型,我一看,咦,这居然在我的知识库之外。不行,我得把它添加进来。于是我翻遍了资料,终于把它弄明白了。

然而高兴了不到一天,发现它的缺点也是一大堆,甚至还有人文中表明不建议使用。

顿时,我的这个心情,格外复杂。但也不想让自己的精力就这么白白浪费了,就把它放在这里吧。供想学习枚举类型的小伙伴参考参考。

 应用场景

如果每条记录的某属性都是在一组固定值中选一个,那么这个属性就可以用枚举类型来进行存储,例如性别只能在男女中选一个。

枚举类型可以规范数据,限定只能插入规定的数据项。

举个例子:

create table gender(
     sex enum('male','female') default 'male'
 );
 -- 创建表gender,其中sex字段的数据类型是枚举类型。
 -- 那么在插入数据时,每条记录的sex属性就只能在male和female中选一个。
 insert into gender values('男');  -- 报错
 insert into gender values('female');  -- 成功,插入一条记录,其sex属性值为female

mysql 枚举多值查询 数据库枚举类型怎么用_数据

 枚举类型可以节约存储空间。

在上面的例子中,存储时,每条记录的sex属性值存储的不是字符串male和female,而是下标1和2。在某些情况下可以减少存储空间。

一条记录节约一点小小的存储空间,数据量少的时候也许差别不大,但若成千上万条数据呢?

有长必有短,enum也有很多缺点,为避免引起错误,缺点需要格外注意。

语法

-- 创建表时
 列名 enum('属性值1','属性值2','属性值3'...)

插入数据

插入数据时既可以插入规定的数据,也可以采用下标的形式插入。

但是如果采用下标类型插入数据的话,要注意下标与属性值得对应关系。

1、插入规定数据

在插入数据时,可以插入创建表时规定的一组数据中的一个。例如:

create table gender(
     sex enum('male','female') default 'male'
 );
 -- 插入数据
 insert into gender values('male');
 -- 由于mysql对大小写不敏感,以下语句也是可以执行成功的。
 insert into gender values('Female');
 insert into gender values('MALE');

2、采用下标的形式插入

create table gender(
     sex enum('male','female') default 'male'
 );
 insert into gender(sex) values(1);  -- 成功,sex=male
 insert into gender values(2);  -- 成功,sex=female
 -- 采用下标的形式插入数据时,类型限制不严格(string、int类型都可以),以下语句也可以成功执行。
 insert into gender values('1');
 insert into gender values('2');

查询数据

与插入数据一样,查询数据时也有两种方式。

一种是根据规范数据正常查询。一种是根据下标查询。

-- 数据准备
 create table test_order(
     order_id char(5) primary key,
     user_id char(3),
     product_name varchar(50),
     price int,
     order_state enum('待支付','待发货','运输中','已收货')
 );
 insert into test_order values
     ('00001','001','iphone14',6199,1),  -- 待支付
     ('00002','002','华为笔记本',4500,2),  -- 待发货
     ('00003','001','六神花露水',15,2),  -- 待发货
     ('00004','003','小米音箱',299,3),  -- 运输中
     ('00005','002','罗技无线鼠标',35,3),  -- 运输中
     ('00006','004','洗地机',1999,2),  -- 待发货
     ('00007','005','立白洗衣液',69,4),  -- 已收货
     ('00008','005','护手霜',109,2),  -- 待发货
     ('00010','004','蓝月亮洗衣液',68,4);  -- 已收货
 -- 查询还未发货的订单,提醒卖家发货
 -- 根据规定的数据正常查询
 select * from test_order where order_state='待发货';
 -- 根据下标查询
 select * from test_order where order_state=2;

mysql 枚举多值查询 数据库枚举类型怎么用_mysql_02

 

mysql 枚举多值查询 数据库枚举类型怎么用_mysql 枚举多值查询_03

 注意:

  • 根据规定数据正常查询时,由于mysql对大小写不敏感,所以不区分大小写。
  • 根据下标查询时,只能用int类型,不能使用string类型。

mysql 枚举多值查询 数据库枚举类型怎么用_mysql_04

 修改数据

修改数据同插入数据相似,支持规范数据和下标两种形式。下标可以是int型,也可以是string类型。

-- 编号为00002的订单,卖家已经发货,将其状态修改为运输中
 update test_order set order_state=3 where order_id='00002';

mysql 枚举多值查询 数据库枚举类型怎么用_mysql_05

 

mysql 枚举多值查询 数据库枚举类型怎么用_mysql_06

缺点

枚举类型可以使用下标来进行操作,但是从上面的例子中,下标似乎是从1开始的?这是因为0具有特殊意义。


 create table test_order(   order_id char(5) primary key,   user_id char(3),   product_name varchar(50),   price int,   order_state enum('待支付','待发货','运输中','已收货')  );  -- 这里 待支付-1,待发货-2,运输中-3,已收货-4


上面例子中,如果往enum列中插入无效值,会直接报错。因为目前使用的版本开启了严格模式。

在比较古老的版本中,或者关闭掉严格模式的情形下,如果插入无效值,可以被插入,但是插入的是一个空字符串,这个空字符串的索引为0

第2个要注意的点是:不要使用数字作为枚举值!!!

因为enum类型每条记录存储的是下标,也支持下标进行操作。如果使用数字作为枚举值很容易造成混乱。例如:


 enum('5','3','2','1')  insert into test values('2');  -- 存储的是枚举值2,还是下标为2的枚举值3?


第3个要注意的点是:枚举值的修改和添加问题。

如果枚举值已经被引用,那么将无法被修改。

例如,尝试把上面例子中的待支付改成待付款。

修改已引用的枚举值(报错)

mysql 枚举多值查询 数据库枚举类型怎么用_学习_07

 添加新的枚举值(只能在列表最后添加)

mysql 枚举多值查询 数据库枚举类型怎么用_mysql_08

 修改未引用的枚举值(成功)

mysql 枚举多值查询 数据库枚举类型怎么用_mysql_09

 更多关于枚举类型的限制,参考:臭名昭著的 MySQL ENUM 类型 ( 上 ) - MySQL 拾遗 - 简单教程,简单编程