当前位置: 首页 > news >正文

Redis常见数据类型及应用场景

好的,我们来详细讲解 Redis 的数据结构及其应用场景。Redis 的强大之处不仅仅在于它支持简单的键值对,更在于它提供了丰富的数据结构,每种结构都针对特定类型的应用场景进行了优化。

核心数据结构与应用场景

Redis 主要支持以下五种核心数据结构:String(字符串)Hash(哈希)List(列表)Set(集合)Sorted Set(有序集合)。此外,还有 Bitmaps、HyperLogLogs、Streams 等更高级的结构。


1. String(字符串)

这是最简单也是最基础的数据类型。一个 Key 对应一个 Value。Value 不仅是字符串,也可以是数字(整数或浮点数),并且可以对数字进行自增/自减操作。

  • 内部实现:基于简单动态字符串(SDS)实现,可以修改的字符串,预分配内存,减少内存频繁分配。
  • 常用命令SET, GET, MSET, MGET, INCR, DECR, INCRBY

应用场景

  • 缓存:最经典的场景。将数据库查询结果、热点数据、会话信息(Session)等序列化后存入 String,加快访问速度。
    • SET user:1001 "{name: 'Alice', email: 'alice@example.com'}"
  • 计数器:利用 INCRDECR 命令实现点赞数、浏览数、库存计数等。这些操作是原子性的,非常适合高并发场景。
    • INCR article:1001:views
  • 分布式锁:利用 SET key value NX EX seconds 命令(当 key 不存在时设置,并设置过期时间)可以实现简单的分布式锁。
  • Session 共享:在集群服务中,将用户的登录会话信息集中存储在 Redis 中,实现多台服务器共享 Session。

2. Hash(哈希)

类似于 Java 中的 Map<String, Object>,是一组键值对的集合。非常适合存储对象。

  • 内部实现:底层有两种编码方式:ziplist(压缩列表,在元素少、体积小时使用)和 hashtable(哈希表)。
  • 常用命令HSET, HGET, HMSET, HMGET, HGETALL, HINCRBY

应用场景

  • 存储对象:存储用户信息、商品信息等需要多个字段的对象。相比将整个对象序列化成 String,Hash 可以单独获取、修改某个字段,更节省网络带宽和存储空间。
    • HSET user:1001 name "Alice" age "30" email "alice@example.com"
    • HGET user:1001 name -> “Alice”
  • 购物车:以用户ID为 Key,商品ID为 Field,商品数量为 Value。
    • HSET cart:1001 product:5001 3 (用户1001的商品5001数量为3)
    • HINCRBY cart:1001 product:5001 1 (增加1件)

3. List(列表)

一个简单的字符串列表,按插入顺序排序。你可以从列表的头部(左边)或尾部(右边)添加元素。

  • 内部实现:底层是 quicklist(快速列表),它是多个 ziplist 通过双向指针组成的链表,兼顾了空间效率和插入性能。
  • 常用命令LPUSH, RPUSH, LPOP, RPOP, LRANGE, BLPOP (阻塞操作)

应用场景

  • 消息队列:利用 LPUSH + BRPOP 可以实现一个简单的 FIFO(先进先出)队列。生产者从左边推入消息,消费者用阻塞方式从右边取出消息。
  • 最新列表:例如最新文章、最新评论、朋友圈时间线。利用 LPUSH 加入新元素,再用 LRANGE 0 9 获取最新的10条。
    • LPUSH news:latest "News ID 10086"
  • 记录用户操作历史:例如用户的最近搜索、最近浏览记录。

4. Set(集合)

Redis 的 Set 是 String 类型的无序集合,集合内的元素是唯一的,不允许重复。

  • 内部实现:底层是 intset(整数集合,当元素都是整数且数量少时)或 hashtable(哈希表,value 为 null)。
  • 常用命令SADD, SMEMBERS, SISMEMBER, SINTER (交集), SUNION (并集), SDIFF (差集)

应用场景

  • 标签(Tag):给用户、文章等对象打标签。可以很方便地求交集、并集等。
    • SADD article:1001:tags "tech" "redis" "database"
    • SADD user:1002:tags "tech" "python"
    • SINTER article:1001:tags user:1002:tags -> 获取共同标签 “tech”
  • 共同关注/好友:利用 SINTER 可以轻松求出两个用户的共同好友。
  • 抽奖/秒杀:利用 SADD 将所有参与用户ID加入,可以自动保证唯一性,不会重复添加。SMEMBERS 可以列出所有参与者。
  • 黑白名单:将需要过滤的 ID 放入 Set,用 SISMEMBER 快速判断某个 ID 是否在名单内。

5. Sorted Set(有序集合 / ZSet)

与 Set 类似,也是 String 类型元素的集合,且不允许重复。但每个元素都会关联一个 double 类型的分数(score)。Redis 正是通过分数来为集合中的成员进行从小到大的排序。成员是唯一的,但分数可以重复。

  • 内部实现:底层是 ziplist(压缩列表)或 skiplist(跳跃表) + dict(字典)的组合,跳跃表保证范围查询的效率,字典保证按成员查询的效率。
  • 常用命令ZADD, ZRANGE (按分数正序), ZREVRANGE (按分数倒序), ZRANK, ZREVRANK, ZRANGEBYSCORE

应用场景

  • 排行榜:这是最经典的应用场景。将分数设为点击量、销量、热度等,自动进行排序。
    • ZADD leaderboard 100 "player1" 200 "player2"
    • ZREVRANGE leaderboard 0 9 WITHSCORES -> 获取排行榜前十名
  • 带权重的队列:分数可以作为优先级,实现优先级队列。
  • 范围查找:例如处理成绩表,快速查找分数在 [90, 100] 之间的学生。
    • ZRANGEBYSCORE grades 90 100
  • 延时任务:将任务的执行时间作为 score,用一个进程轮询获取到期的任务(ZRANGEBYSCORE key 0 <当前时间戳>)。

其他高级数据结构

  • Bitmaps(位图): 本质上是 String,但可以对字符串的位进行操作。适用于大量布尔值的存储,如用户签到记录(每天1bit)、活跃用户统计,极其节省空间。
  • HyperLogLogs: 用于做基数统计(估算一个集合中不重复元素的个数),标准误差仅0.81%。优点是非常节省空间。适用于统计网站的 UV(独立访客)、搜索关键词的不重复数量等,PFADD, PFCOUNT, PFMERGE
  • Geospatial(地理空间): 可以存储地理坐标,并计算距离、查找范围内成员等。适用于附近的人、地理位置推荐。
  • Streams(流): Redis 5.0 引入,专门为消息队列设计,支持多消费者组、消息持久化、确认机制,功能比 List 更强大,是更专业的消息队列解决方案。

总结与选择建议

数据结构特性典型应用场景
String简单键值,支持数字和位操作缓存、计数器、分布式锁
Hash适合存储对象,可部分更新用户信息、购物车、配置项
List有序、可重复,支持阻塞操作消息队列、最新列表、历史记录
Set无序、唯一,支持集合运算标签、共同好友、抽奖、黑白名单
Sorted Set唯一、有序(按分数排序)排行榜、优先级队列、范围查找
Bitmaps极省空间的布尔状态存储用户签到、活跃用户统计
HyperLogLog极省空间的基数估算网站UV统计
Streams持久化的消息流复杂消息队列

选择时考虑以下几点

  1. 数据形态:是需要一个对象(Hash)、一个列表(List)、一个不重复集合(Set)还是一个带排序的集合(ZSet)?
  2. 操作类型:是需要频繁读取部分字段(Hash),还是需要排序(ZSet),或是需要集合运算(Set)?
  3. 性能与效率:String 存储序列化对象虽然简单,但修改一个字段就需要整个读写,不如 Hash 高效。在元素较少时,Redis 会使用更紧凑的编码(如 ziplist)来节省内存。
http://www.dtcms.com/a/360232.html

相关文章:

  • Pytest 插件介绍和开发
  • 极客时间AI 全栈开发实战营毕业总结(2025年8月31日)
  • NCCL-TEST ib集群测试UCX代替方案
  • mit6.031软件构造 笔记 Testing
  • ROI、 binning、下采样功能区别
  • windows编译minicap.so文件
  • 由题构造 嵌入汇编(汇编)
  • NAS Docker 安装N8N
  • 计算机视觉与深度学习 | 双目立体特征提取与匹配算法综述——理论基础、OpenCV实践与MATLAB实现指南
  • 猛犸Lark max 无线麦克风录音爆音问题的解决
  • 【STC库函数】使用芯片自带的EEPROM来保存掉电不丢失的数据
  • 开发常用工具专栏
  • 赵玉平《梁山政治》读书笔记(下部)
  • wifi控制舵机
  • WinExec
  • Nginx反向代理及配置
  • c++ 线程局部存储(Thread-Local Storage,TLS)
  • Langflow Memory 技术深度分析
  • java--浅拷贝深拷贝
  • Introduction to GIS —— Chapter 3(Vector Data Model)
  • 雪花算法生成分布式ID
  • AI 智能体汇总,自动执行任务的“真 Agent”
  • 动态规划入门(三):一些经典动态规划模型
  • 赵玉平《刘备谋略》读书笔记(下部)
  • 小迪自用web笔记22
  • 01背包day35
  • 设计模式 | 常见的设计模式(单例、工厂、代理、适配器、责任链等等)
  • VisionProC#联合编程火花塞距离检测与VisionPro操作
  • libmodbus库,c++配置方法
  • 【CUDA入门·Lesson 1】Ubuntu实战:CUDA 概念、nvidia-smi 工具与 GPU 参数详解