Redis 常用数据类型有哪些?String、Hash、List、Set、ZSet 应该怎么选?
下面是一段教学用的模拟面试。
🧑💻 面试官:用户资料存 Redis,你会用什么类型?
🙋♂️ 我:用户资料是一个对象,所以用 Hash。
🧑💻 面试官:如果每次都把整份资料读出来,从不单独改字段呢?
🙋♂️ 我:那也可以序列化成 JSON,用 String 保存。
🧑💻 面试官:同样是一群用户,排队、去重和积分排行,为什么不能都用 List?
类型不是根据“对象长得像什么”来选,而是根据「你准备怎样读、怎样改」来选。
面试速答(60 秒版)
Redis 常见的基础类型包括 String、Hash、List、Set 和 ZSet,但 Redis 的类型并不只有这五种。
String 适合保存一个完整值,例如缓存 JSON,或者配合自增命令做计数。Hash 可以按字段读写,适合需要分别修改昵称、头像这类字段的资料。
List 保留元素顺序,也允许重复,可以从两端插入和取出。Set 不保留可依赖的业务顺序,但支持成员去重、交集和差集。ZSet 则在成员唯一的基础上增加分数,适合按积分或时间排序、查询范围。
实际选型时,先列出需要执行的操作。整份读取和局部更新,去重和排序,是不同的需求。同时还要考虑键的生命周期、数据规模和失败处理,不能只看哪种类型写起来方便。

知识点详解:同样保存用户,操作方式可以完全不同
整份缓存,还是单独改字段?
假设页面每次都需要完整的用户简介。后端从数据库取得资料,序列化成 JSON,放进一个 String。读取时一次取回,缓存过期后重新生成。这种方式很直观。
但如果昵称、头像和设置由不同功能分别更新,每次都先读取整份 JSON、修改一个字段、再整体写回,就容易出现覆盖:两个请求都从旧 JSON 开始,一个改昵称,一个改头像,后写的可能盖掉前一个修改。
Hash 允许直接操作指定字段,少做整份搬运。不过,Hash 并不会让多条命令自动成为一个原子业务操作。两个字段必须一起满足条件时,仍需要考虑事务、脚本或其他合适的更新方式。
这里也要区分两个名字:Redis 的 Hash 是一种对外的数据类型;“哈希表”是实现数据结构。不能把底层实现名称直接当成使用规则。

排队、去重和排行,分别需要什么能力?
我们还是看用户,但这次看三种操作。
客服接待队列要保留先后,某个用户可能多次进入,List 可以满足两端进出的操作。它只是队列材料,不会自动提供完整的业务确认、重试和持久可靠性。任务取出后进程崩溃怎么办,仍要另外设计。
活动参与名单要判断“这个用户有没有参加过”,Set 的成员唯一性就很合适。需要计算两个活动的共同参与者,还能使用集合运算。
积分榜既要保证一个用户只出现一次,又要按分数排序,那么使用 ZSet 更自然。一个成员对应一个分数,更新分数后排名可能变化。分数相同时还存在明确的成员排序规则,不能默认按插入时间排。
不要给 List 加上“天然去重”,也不要给 Set 加上“插入顺序就是排名”。这些操作语义不同。Redis 数据类型文档可以作为查阅入口。

选了类型,还要设计 key 和过期策略
假设资料键叫 user:42。这个键究竟是缓存副本,还是唯一的数据来源?答案会影响它能不能过期,丢失后怎么恢复。
接着再看粒度。把所有用户塞进一个巨大 Hash,和每个用户一个 Hash,并不是只差键名。前者的整体大小、访问热点以及生命周期都可能更难管理。
过期能力也要按实际版本核对。现代 Redis 已经提供 Hash 字段过期相关命令,不能继续把“字段绝对不能单独过期”当成普遍结论;项目能不能用,要看服务版本和客户端支持。
类型选型解决的是操作契约,不是整个存储设计。
怎么知道选型真的合适?
先用需要支持的操作写一组用例:读取全部字段、修改单字段、去重、取前十名、按分数范围查询。
再放入接近实际规模的数据,观察单次操作延迟、内存、返回体积以及热点键。不要只测十条数据,就宣布哪种类型最省内存。
如果一开始只需整份缓存,用 String 完全合理。后来局部更新越来越多,再考虑调整。不是用更复杂的类型,才说明懂 Redis。
面试官继续追问
List 可以直接替代消息队列吗?
可以组成简单队列,但不能因此宣称业务可靠性已经完成。消费确认、处理中任务、失败重试和积压监控需要额外方案。需要消费组等能力时,也可以考虑 Streams,不要只盯着五种基础类型。
ZSet 分数一样,会不会丢一个成员?
不会因为分数相同就合并。唯一的是成员,不是分数。只有再次写入同一成员时,才是在更新这个成员的分数。
一个用户对象,到底是 String 还是 Hash?
先问“是否局部读写”。如果主要整份读取、整份失效,String 很方便;如果经常按字段操作,Hash 更贴近需求。之后再用真实数据核对内存和延迟,不靠对象外形拍板。
面试速记卡
- String:保存完整值,也可用相应命令完成计数等操作。
- Hash:按字段操作;多字段业务规则仍需单独保证。
- List:有序、可重复,适合两端进出。
- Set:成员唯一,适合去重和集合运算。
- ZSet:成员唯一且带分数,适合排序与范围查询。
- 选型:先看操作,再看规模、过期与可靠性。
公司面试真题
真题根据求职者公开面经整理,题意经过概括,非逐字原话或公司官方题库;本文为 Sunday 的独立解析。
京东 · 数据开发 / 后端 · 校招
Redis 的数据类型和底层结构有哪些?(题意整理)
京东数据开发工程师后端一面 ↗
原帖发布于 2025-08-31(秋招记录)美团 · Java后端 · 实习
Redis 常见数据类型的底层结构是什么?(题意整理)
4.21美团Java实习一二面面经 ↗
面试记录为 2020-04-21、2020-04-24;原帖编辑于 2020-11-14