Redis数据结构介绍

一、前言:Redis 不只是"缓存工具"

很多人认为 Redis 只是用来做缓存的,其实它是一个功能强大的内存数据结构服务器

Redis 提供了 5 种核心数据类型,每种都针对特定场景做了深度优化:

  • 缓存用户信息?用 Hash
  • 实现消息队列?用 List
  • 做共同好友推荐?用 Set
  • 打造实时排行榜?用 ZSet(Sorted Set)

掌握这些数据结构,你才能真正发挥 Redis 的威力!

本文将带你:

✅ 深入理解五大基本数据类型的内部结构

✅ 掌握常用命令与操作示例

✅ 结合真实业务场景说明用途

✅ 避开常见使用误区


二、String(字符串)------ 最基础但最常用

🔹 特点

  • 最简单的 Key-Value 结构
  • Value 可以是字符串、数字、甚至二进制数据(如图片)
  • 支持 原子自增/自减INCR / DECR

🔧 常用命令

bash 复制代码
SET user:1001 "张三"
GET user:1001
INCR page_view:home      # 页面访问计数 +1
SETEX token:abc123 3600 "user_data"  # 带过期时间

🎯 典型场景

  • 缓存简单对象(如用户昵称、配置项)
  • 分布式计数器(秒杀库存、接口限流)
  • 分布式锁 (配合 SET key value NX EX

💡 技巧:用 INCRBY 实现批量加减,避免多次网络往返。


三、Hash(哈希)------ 存储对象的首选

🔹 特点

  • 类似编程语言中的 Map / Dictionary
  • 一个 Key 对应多个字段(field)和值(value)
  • 适合存储结构化对象,避免序列化整个对象

🔧 常用命令

bash 复制代码
# 存储用户信息
HSET user:1001 name "张三" age 28 city "北京"

# 获取单个字段
HGET user:1001 name

# 获取所有字段
HGETALL user:1001

# 原子递增
HINCRBY user:1001 login_count 1

🎯 典型场景

  • 用户资料存储(无需每次读取整个对象)
  • 商品属性(颜色、尺寸、库存等)
  • 会话状态管理

✅ 优势:比 String 存 JSON 更节省内存,且支持字段级更新。


四、List(列表)------ 双向链表实现的队列

🔹 特点

  • 底层是 快速列表(quicklist),由 ziplist + linkedlist 优化而成
  • 支持从头部或尾部插入/弹出元素
  • 可用于实现栈、队列、阻塞队列

🔧 常用命令

bash 复制代码
# 从左侧推入
LPUSH news:list "头条新闻1"
LPUSH news:list "头条新闻2"

# 从右侧弹出(先进先出)
RPOP news:list

# 获取最新5条
LRANGE news:list 0 4

# 阻塞式弹出(等待消息)
BRPOP task:queue 10  # 等待10秒

🎯 典型场景

  • 消息队列(轻量级任务分发)
  • 最新动态/评论列表(如朋友圈 feed 流)
  • 秒杀商品库存队列

⚠️ 注意:List 不适合大数据量随机访问(LINDEX 时间复杂度 O(N))。


五、Set(集合)------ 自动去重的无序集合

🔹 特点

  • 元素唯一(自动去重)
  • 无序(不保证插入顺序)
  • 支持集合运算:交集、并集、差集

🔧 常用命令

bash 复制代码
# 添加标签
SADD user:1001:tags "科技" "篮球" "电影"

# 判断是否包含
SISMEMBER user:1001:tags "篮球"

# 获取所有标签
SMEMBERS user:1001:tags

# 计算两个用户的共同兴趣
SINTER user:1001:tags user:1002:tags

🎯 典型场景

  • 用户标签系统
  • 共同好友/关注推荐
  • 抽奖去重(确保每人只中一次)

💡 性能:SADD / SISMEMBER 时间复杂度为 O(1),极快!


六、ZSet(Sorted Set,有序集合)------ 带权重的集合

🔹 特点

  • 每个成员(member)关联一个分数(score)
  • 元素按 score 自动排序
  • 支持范围查询(如 Top N、区间查找)

🔧 常用命令

bash 复制代码
# 添加成员(score 可为整数或浮点)
ZADD game:rank 95 "玩家A"
ZADD game:rank 98 "玩家B"
ZADD game:rank 92 "玩家C"

# 获取排名前3(从高到低)
ZREVRANGE game:rank 0 2 WITHSCORES

# 获取某玩家的分数
ZSCORE game:rank "玩家A"

# 获取分数在 90~100 之间的玩家
ZRANGEBYSCORE game:rank 90 100

🎯 典型场景

  • 游戏积分排行榜
  • 延迟任务队列(score = 执行时间戳)
  • 带权推荐系统(如热度 + 时间衰减)

⚡ 核心优势:插入、删除、查询 Top K 的时间复杂度均为 O(log N)


七、底层实现简析(拓展知识)

数据类型 底层编码(encoding) 说明
String int / raw / embstr 小整数直接存指针,短字符串用 embstr 优化
Hash ziplist / hashtable 元素少时用 ziplist 节省内存
List quicklist ziplist 的双向链表,兼顾内存与性能
Set intset / hashtable 全为整数且数量少时用 intset
ZSet ziplist / skiplist 少量元素用 ziplist,多则用跳表(skiplist)

📌 Redis 会根据数据规模自动切换编码,无需手动干预。


八、常见误区与最佳实践

❌ 误区 1:用 String 存整个 JSON 对象

问题 :更新单个字段需全量反序列化+写回
建议 :改用 Hash,字段级操作更高效

❌ 误区 2:在 List 中频繁随机访问

问题LINDEX 是 O(N),大数据量会卡顿
建议 :如需索引,考虑用 ZSet + 自增 ID 模拟

❌ 误区 3:ZSet 存超大集合(百万级)

问题 :内存占用高,范围查询变慢
建议 :分片(如按天分 key:rank:20251103

✅ 最佳实践:

  • Key 命名规范业务:实体:id(如 user:profile:1001
  • 设置 TTL:避免内存无限增长
  • 避免 Big Key:单个 value 不超过 10KB,List/Set/ZSet 元素不超过 5000

九、结语

感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!

相关推荐
最后的最后、7966 分钟前
SQLi-Labs 六关 SQL 注入过关笔记
数据库·笔记·sql
晓子文集8 分钟前
Tushare接口文档:现金流量表(cashflow)
大数据·数据库·大模型·金融数据·量化投资·tushare
zander25813 分钟前
138. 随机链表的复制
数据结构·算法·链表
難釋懷18 分钟前
Nginx代理https请求
redis·nginx·https
会编程的土豆19 分钟前
数据库mysql八股
数据库·笔记·八股
过期动态20 分钟前
【LeetCode 热题 100】找到字符串中所有字母异位词
java·数据结构·算法·leetcode·职场和发展·rabbitmq
来一碗刘肉面29 分钟前
栈在递归中的应用
数据结构·算法
nVisual35 分钟前
巡检任务与工单闭环方案
运维·服务器·数据库·数据中心基础设施
施嘉伟1 小时前
它以为自己连的是MongoDB
数据库·mongodb
皓月斯语1 小时前
程序设计语言的特点
开发语言·数据结构·c++