MySQL枚举与集合
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多选存标签,底层分别用序号和位存储。取值固定且变动少的字段用它们防脏数据,值频繁增加或需要多对多关系时改用独立关联表更规范。
MySQL 常用数据类型
MySQL 常用数据类型
建表选对数据类型很重要,这些常用类型要记住。
1. 数值类型
整数类型
- TINYINT: 1字节,范围 -128~127
- SMALLINT: 2字节,范围 -32768~32767
- INT: 4字节,常用,范围约 ±21亿
- BIGINT: 8字节,大数值
小数类型
- FLOAT: 单精度浮点数
- DOUBLE: 双精度浮点数
- DECIMAL: 精确小数,存金额用这个
-- 金额用 DECIMAL(总位数, 小数位数)
price DECIMAL(10,2) -- 最多10位,2位小数
2. 字符串类型
CHAR: 定长字符串,比如 CHAR(10) 存不满补空格
- 适合固定长度,比如手机号、性别
VARCHAR: 变长字符串,最常用
- VARCHAR(255),存多少占多少
- 适合变长内容,比如用户名、标题
TEXT: 长文本
- TINYTEXT、TEXT、MEDIUMTEXT、LONGTEXT
- 存文章内容、备注等
常用选择:
- 短文本:VARCHAR(50)
- 长文本:TEXT
- 固定长度:CHAR
3. 日期时间类型
DATE: 日期,格式 YYYY-MM-DD
TIME: 时间,格式 HH:MM:SS
DATETIME: 日期+时间,范围 1000-9999年
TIMESTAMP: 时间戳,范围 1970-2038年,自动更新
create_time DATETIME DEFAULT CURRENT_TIMESTAMP
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
4. 常用字段设计示例
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL COMMENT '用户名',
age TINYINT UNSIGNED COMMENT '年龄',
phone CHAR(11) COMMENT '手机号',
money DECIMAL(10,2) DEFAULT 0 COMMENT '余额',
status TINYINT DEFAULT 1 COMMENT '状态:1正常 0禁用',
content TEXT COMMENT '简介',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
5. 选择建议
1)主键ID
- 用 INT 或 BIGINT
- 不要用 UUID 做主键
2)金额
- 用 DECIMAL,不要用 FLOAT/DOUBLE
- 避免精度丢失
3)状态字段
- 用 TINYINT,不要用 VARCHAR 存 "正常/禁用"
4)时间
- 创建时间用 DATETIME
- 更新时间用 TIMESTAMP 自动更新
5)字符串
- 短文本用 VARCHAR
- 长文本用 TEXT
- 固定长度用 CHAR
6. 注意事项
- 不要过度设计: 够用就行,不要字段太大
- 能用数字不用字符串: 排序、计算都快
- 避免 NULL: 尽量设默认值,NULL 不好查询
- 加注释: 每个字段都加 COMMENT
总结
MySQL 常用数据类型要点:
- INT/BIGINT:整数
- DECIMAL:金额
- VARCHAR:字符串
- TEXT:长文本
- DATETIME/TIMESTAMP:时间
- 主键用 INT 自增
- 金额用 DECIMAL
- 状态用 TINYINT
- 字段加注释
建表选对类型,性能和存储都好。
Redis 常用数据类型
Redis 常用数据类型
Redis 不只是简单的 key-value,有5种常用数据类型,每种适合不同场景。
1. String(字符串)
最基础的类型,存字符串、数字都可以。
# 设置
set name "张三"
# 获取
get name
# 自增
incr age
# 设置过期时间
set token "abc" ex 3600
适用场景: 缓存、计数器、Session。
2. Hash(哈希)
存对象,比如用户信息。
# 设置单个字段
hset user:1 name "张三"
# 获取单个字段
hget user:1 name
# 设置多个字段
hmset user:1 name "张三" age 20 city "北京"
# 获取所有字段
hgetall user:1
适用场景: 存储对象(用户信息、商品信息)。
3. List(列表)
有序列表,可以做消息队列。
# 左侧添加
lpush list "a" "b" "c"
# 右侧添加
rpush list "d"
# 左侧弹出
lpop list
# 查看范围
lrange list 0 -1
适用场景: 消息队列、最新列表。
4. Set(集合)
无序,不重复,做去重。
# 添加
sadd set "a" "b" "c"
# 查看所有
smembers set
# 判断是否存在
sismember set "a"
# 交集
sinter set1 set2
适用场景: 去重、共同好友、标签。
5. ZSet(有序集合)
有序,带分数排序。
# 添加
zadd rank 100 "张三" 90 "李四" 80 "王五"
# 查看排名(从高到低)
zrevrank rank "张三"
# 查看分数
zscore rank "张三"
# 查看排行榜
zrevrange rank 0 9
适用场景: 排行榜、分数排序。
总结
Redis 5种数据类型:
- String:缓存、计数器
- Hash:存对象
- List:消息队列
- Set:去重、标签
- ZSet:排行榜
根据场景选对数据类型,用起来才高效。
Redis 常用数据类型
Redis 常用数据类型
Redis 不只是缓存,它有 5 种常用数据类型,用对了能解决很多问题。
1. String(字符串)
最基本的类型,一个 key 对应一个 value。
# 设置
SET name "张三"
# 读取
GET name
# 自增(计数器)
INCR page_view
# 设置过期时间(秒)
EXPIRE token 3600
# 查看过期时间
TTL token
适用场景: 缓存、计数器、分布式锁。
2. Hash(哈希)
适合存对象。
# 设置字段
HSET user:1 name "张三" age 25
# 获取字段
HGET user:1 name
# 获取所有字段
HGETALL user:1
# 删除字段
HDEL user:1 age
适用场景: 用户信息、商品信息。
3. List(列表)
有序队列,先进先出。
# 从左边插入
LPUSH messages "消息1"
LPUSH messages "消息2"
# 从右边插入
RPUSH messages "消息3"
# 从左边弹出
LPOP messages
# 查看列表
LRANGE messages 0 -1
适用场景: 消息队列、最新消息列表。
4. Set(集合)
无序不重复。
# 添加元素
SADD tags "PHP" "MySQL" "Linux"
# 查看所有元素
SMEMBERS tags
# 判断是否存在
SISMEMBER tags "PHP"
# 交集
SINTER set1 set2
适用场景: 标签、共同好友、去重。
5. ZSet(有序集合)
每个元素带分数,按分数排序。
# 添加元素
ZADD rank 100 "张三"
ZADD rank 90 "李四"
ZADD rank 80 "王五"
# 查看排行(从高到低)
ZREVRANGE rank 0 -1 WITHSCORES
# 获取排名
ZREVRANK rank "张三"
适用场景: 排行榜、热度排序。
总结
| 类型 | 特点 | 适用场景 |
|---|---|---|
| String | 简单键值 | 缓存、计数器 |
| Hash | 存对象 | 用户信息 |
| List | 有序队列 | 消息队列 |
| Set | 不重复 | 标签、去重 |
| ZSet | 带分数排序 | 排行榜 |
Redis 用熟了,能解决很多业务问题。