MySQL里那个ENUM类型到底是咋回事,怎么用还挺多细节没说清楚
- 问答
- 2025-12-26 15:03:27
- 4
ENUM是啥?怎么用?
比方说,你有个用户表,里面要记录用户的性别,性别通常就三种情况:“男”、“女”,或者有时候有个“保密”,你当然可以用VARCHAR类型,直接存文字,但那样有个问题,万一有人手一抖,输了个“男性”,或者“Man”,就跟“男”对不上了,查询和统计的时候会很麻烦。
用ENUM就能解决这个问题,你在建表的时候就可以这么写(这里只是举个例子,你不用记具体代码):
CREATE TABLE users (
id INT,
name VARCHAR(100),
gender ENUM('男', '女', '保密')
);
这句话的意思就是,给gender字段划下道儿了:你这辈子只能从‘男’、‘女’、‘保密’这三个值里选,选了‘男’,数据库里存的就是‘男’,选了‘保密’存的就是‘保密’,想存个‘未知’?门儿都没有,数据库会报错或者存个空值进去(取决于你的设置)。
那些没人明说但很重要的细节
光知道这是个选择题还不够,里面有几个坑,不踩过可能真不知道。
-
它实际存的是数字,不是文字 这是ENUM最核心的一个“秘密”,你以为你存进去的是“男”这个汉字,但MySQL为了省地方,实际在硬盘上存的是一个数字编号,它会把你的选项列表自动编号:‘男’是1,‘女’是2,‘保密’是3,你存‘男’,它实际存的是数字1,这么做的好处是超级省空间,比如你选项有100个,它可能只需要1个字节就能存下,比存一串文字节省多了,但这也是很多问题的根源。

-
排序可能跟你想的不一样 既然实际存的是数字,那排序(ORDER BY)的时候,就不是按选项的文字拼音或者笔画来排了,而是按那个数字编号来排,举个例子,如果你定义的是 ENUM('西瓜', '苹果', '香蕉'),西瓜’编号是1,‘苹果’是2,‘香蕉’是3,你按这个字段排序,出来的顺序永远是 西瓜 -> 苹果 -> 香蕉,哪怕你心里觉得按拼音应该是“苹果”排最前面也没用,这个特性有时候会很让人困惑。
-
处理“脏数据”的方式 如果你硬要往里塞一个不在选项列表里的值,MySQL会怎么处理呢?这取决于你的SQL模式设置。
- 如果是严格模式(现在高版本MySQL默认就是),那对不起,直接报错,插不进去。
- 如果不是严格模式,MySQL会尝试“宽容”处理:它会塞一个空字符串('')进去,而这个空字符串在ENUM里的编号是0,这意味着,你的数据里会混进一个你根本没定义的“隐藏选项”,将来查询
WHERE gender = '男'的时候,这些脏数据是查不出来的,因为它们本质是空字符串,不是‘男’,这会成为数据质量的一个大坑。
-
修改选项列表是个“昂贵”的操作 假如你的业务变了,原来性别只有“男”、“女”,现在要加个“未知”,你需要用ALTER TABLE命令去修改这个ENUM的定义,加上新选项,这个操作在MySQL里,特别是对于大表来说,代价很高,它可能意味着MySQL需要重建整个表(锁表,耗时很长),而不是简单地加个选项就完事了,相比之下,如果你用另一张专门的表(比如叫
genders)来存所有可能的性别,然后在用户表里用外键关联过去,那么增加一个新的性别选项,只需要在genders表里插入一行新记录就行了,非常快,而且不影响用户表,这是很多人后来放弃ENUM,改用外键关联小表的原因之一。 -
可移植性问题 ENUM类型并不是所有的数据库系统都支持的,如果你现在用MySQL开发,以后万一想换到PostgreSQL或者Oracle等其他数据库,这个ENUM类型可能就无法直接迁移过去,你得想办法把这些字段改成VARCHAR之类的通用类型,这又是一个麻烦事。

那到底该不该用ENUM?
这么说吧,ENUM就像是一把非常专用的螺丝刀,用在特定的场景下很顺手,但不能啥螺丝都用它拧。
-
适合用ENUM的情况:
- 选项值非常固定,几乎永远不可能改变,是/否”、“开/关”、“红/黄/绿”这种标准状态。
- 你对存储空间有极致的追求,能省一个字节是一个字节。
- 你非常确定这个数据库就是MySQL,没有迁移到其他数据库的计划。
-
不适合用ENUM的情况:
- 选项未来有可能会增加或变更,比如商品分类、用户标签等。
- 你需要按选项的文字含义进行排序。
- 你追求数据库设计的规范性和可移植性。
总结一下:ENUM是个好东西,它通过限制选择保证了数据的一致性,还节省空间,但你必须清楚它的底细:它用数字存、按数字排序、改起来麻烦、对脏数据处理方式诡异,对于那些值会变动的类别,更稳妥、更专业的做法往往是单独建一张“字典表”然后用外键关联,虽然稍微复杂一点,但灵活性和可维护性要高得多。
本文由雪和泽于2025-12-26发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/68853.html
