Appearance
Redis 数据结构怎么选:String、Hash、List、Set、ZSet、Bitmap、HyperLogLog 的使用场景
很多人会用 Redis,但容易停留在:
- 会
set/get - 会
hset/hget - 会
zadd
可一到实际建模时,就会开始犹豫:
- 这个场景用 String 还是 Hash
- 排行榜为什么适合 ZSet
- 去重和计数该怎么选
先说结论
可以先按这套直觉理解:
String:最通用,适合缓存单值Hash:适合对象字段集合List:适合简单队列Set:适合去重集合ZSet:适合排序和排行榜Bitmap:适合布尔位图统计HyperLogLog:适合近似去重计数
真正选型时,不是看哪个“更高级”,而是看:
- 你的读写模式
- 你的查询方式
- 你的内存成本和精度要求
一、String:最通用,但别什么都往里塞
String 是 Redis 最常见的数据类型。
适合:
- 缓存 JSON
- 验证码
- 分布式锁标记
- 简单计数
优点:
- API 直观
- 性能稳定
- 适用面非常广
边界:
- 对象整体更新方便,但单字段修改不够细
- JSON 很大时容易演变成大 Key
二、Hash:对象建模更自然
如果你缓存的是对象,而且经常按字段读写,Hash 通常更合适。
例如:
- 用户资料
- 商品基础信息
- 配置对象
优点:
- 字段级更新更自然
- 不用每次整块改整个 JSON
边界:
- 字段太多、值太大时,也可能演变成大 Key
三、List:适合简单消息队列和时间顺序数据
适合:
- 简单任务队列
- 时间顺序日志片段
- 最新消息列表
优点:
- 头尾插入性能好
边界:
- 随机访问不是强项
- 更复杂的消息可靠性和消费组语义,不适合强行拿它替代专业 MQ
四、Set:去重很自然
适合:
- 标签集合
- 用户关注集合
- 某个活动参与用户集合
优点:
- 天然去重
- 支持交并差集
边界:
- 不适合做有序场景
五、ZSet:排序场景非常强
如果你需要:
- 排行榜
- 热门榜单
- 延迟队列的时间排序
ZSet 往往是首选。
它的核心特点是:
- 每个元素带一个 score
- 支持按 score 有序访问
这类结构非常适合:
- 积分榜
- 热度榜
- 最近活跃排序
六、Bitmap:适合位级布尔统计
典型场景:
- 用户签到
- 在线状态
- 某天是否访问过
优势:
- 非常省空间
边界:
- 适合布尔位场景,不适合复杂对象结构
七、HyperLogLog:适合近似去重计数
典型场景:
- UV 统计
- 大规模去重计数
优势:
- 内存占用非常低
边界:
- 是近似值,不是精确去重结果
如果业务要求绝对精确,就不适合。
八、业务里怎么选更稳
1. 只是缓存一个对象整体
先问:
- 会不会频繁改单个字段
如果不会,String + JSON 很常见。
2. 对象字段经常单独更新
考虑:
Hash
3. 需要天然去重
考虑:
Set
4. 需要排序和排名
考虑:
ZSet
5. 需要高密度布尔状态统计
考虑:
Bitmap
九、几个容易踩的坑
1. 把 Redis 结构当数据库表来设计
Redis 更适合高性能访问层,不适合复杂关系模型硬套。
2. 只看功能,不看 Key 大小
同一种结构用对了类型,未必就规避了大 Key 风险。
3. 不考虑后续查询方式
很多人是“先能存进去”,但真正性能差异往往出现在“怎么取出来”。
一句话总结
Redis 数据结构选型的重点,不是背命令,而是让“业务访问方式”和“底层结构特性”匹配起来。
当你先想清楚读写模式、排序需求、去重需求和内存约束时,类型选择会自然很多。