MySQL枚举与集合
时间:2026-10-19 07:24 作者:emer 分类: 无
MySQL枚举与集合
引言
状态、性别、标签这类取值固定的字段,有人用varchar存中文,导致拼写不一、无法约束。MySQL提供ENUM单选和SET多选两个字符串型,把合法值列在定义里,从源头限制脏数据。
ENUM单选
一个字段只能取定义值中的一个,适合性别、订单状态:
CREATE TABLE orders (
id INT PRIMARY KEY AUTO_INCREMENT,
status ENUM('待付款','已付款','已发货','已完成','已取消') NOT NULL DEFAULT '待付款'
);
插入不在列表的值,严格模式直接报错,非严格模式存空串,避免写错状态。
SET多选
一个字段可存多个定义值,适合兴趣、标签、权限位:
CREATE TABLE users (
id INT PRIMARY KEY,
interest SET('阅读','运动','音乐','旅行') NOT NULL
);
-- 插入多个值,逗号分隔
INSERT INTO users(interest) VALUES('阅读,音乐');
底层按位存储,最多64个成员。
两者区别
- ENUM单选,SET多选;
- ENUM内部按序号1、2、3存储,SET按二进制位;
- ENUM常见于状态机,SET常见于标签和多选权限;
- SET查单个值用FIND_IN_SET:
SELECT * FROM users WHERE FIND_IN_SET('阅读', interest);
注意事项
- 新增/修改枚举值要ALTER TABLE,字段多、值不稳定就别用ENUM;
- 枚举值排序按内部序号而非字面字母序,容易误判;
- 中文枚举注意字符集一致;
- 关系型设计里多值标签更推荐关联表,SET只适合简单固定多选;
- 不要用ENUM存会频繁增长的分类。
总结
ENUM单选约束状态,SET多选存标签,底层分别用序号和位存储。取值固定且变动少的字段用它们防脏数据,值频繁增加或需要多对多关系时改用独立关联表更规范。