Redis基本数据类型:Sorted Set (ZSet)

ZSet

一、ZSet 类型概述

Redis 的 Sorted Set 是一个 有序的、不重复的 字符串集合,结合了 Set 的唯⼀性和 List 的有序性。每个元素都会关联一个 score(分数),Redis 正是通过分数来为集合中的元素进行 从小到大 的排序。

核心特点:

  • 元素唯一:集合中的元素(member)不重复
  • 有序性:元素按照 score 排序
  • 分数可重复:不同元素可以有相同的 score

二、基本方法

  1. 添加更新与删除元素
  • ZADD key [NX|XX] [GT|LT] [CH] [INCR] score1 member1 [score2 member2 ...] :添加元素

    • NX:只添加新元素,不更新已存在的
    • XX:只更新已存在的元素,不添加新元素
    • INCR:对 score 进行增加操作
    • CH:返回被修改的元素数量
bash 复制代码
127.0.0.1:6379> zadd name 1 xiaozhang  #添加元素并设置score
(integer) 1
127.0.0.1:6379> zadd name 2 zhangxiao
(integer) 1
127.0.0.1:6379> zadd name nx 3 xiaozhang  
(integer) 0
127.0.0.1:6379> zadd name xx ch 3 xioazhang  #没有元素,更新失败
(integer) 0
127.0.0.1:6379> zadd name xx ch 3 xiaozhang
(integer) 1
127.0.0.1:6379> zadd name xx ch 4 xiaozhang
(integer) 1
127.0.0.1:6379> zrem name xiaozhang  #删除一个或多个元素
(integer) 1
127.0.0.1:6379> zrange name 0 -1
1) "zhangxiao"
  1. 查询元素
bsah 复制代码
127.0.0.1:6379> zadd map 1 one 2 twe 3 three 4 four
(integer) 4
127.0.0.1:6379> zrange map 0 -1  #按score升序获取所有的元素
1) "one"
2) "twe"
3) "three"
4) "four"
127.0.0.1:6379> zrange map 0 -1 withscores  #按score升序获取所有的元素及score
1) "one"
2) "1"
3) "twe"
4) "2"
5) "three"
6) "3"
7) "four"
8) "4"
127.0.0.1:6379> zrevrange map 0 -1  #按score降序获取所有的元素
1) "four"
2) "three"
3) "twe"
4) "one"
127.0.0.1:6379> zrangebyscore map 0 2  #返回指定分数范围的元素
1) "one"
2) "twe"
127.0.0.1:6379> zrangebyscore map 0 2 withscores
1) "one"
2) "1"
3) "twe"
4) "2"
127.0.0.1:6379> zrevrangebyscore map 3 2  #降序返回指定分数范围的元素
1) "three"
2) "twe"
127.0.0.1:6379> zrevrangebyscore map 3 2 withscores
1) "three"
2) "3"
3) "twe"
4) "2"
  1. 统计与排名操作
bash 复制代码
127.0.0.1:6379> zadd map 1 one 2 twe 3 three 4 four
(integer) 4
127.0.0.1:6379> zcard map  #统计集合中的元素数
(integer) 4
127.0.0.1:6379> zcount map -inf +inf  #获取集合某个区间中有多少元素(-inf表示负无穷,+inf表示正无穷)
(integer) 4
127.0.0.1:6379> zcount map 2 3
(integer) 2
127.0.0.1:6379> zrank map twe  #获取元素的升序排名
(integer) 1
127.0.0.1:6379> zrank map twe withscore  #获取元素的升序排名及对应的score
1) (integer) 1
2) "2"
127.0.0.1:6379> zrevrank map twe  #获取元素的降序排名    
(integer) 2
127.0.0.1:6379> zrevrank map twe withscore  #获取元素的降序排名及对应的score
1) (integer) 2
2) "2"
127.0.0.1:6379> zscore map three  #获取元素的score
"3"
  1. 集合操作
bash 复制代码
127.0.0.1:6379> zadd num 1 v1 2 v2 3 v3 4 v4
(integer) 4
127.0.0.1:6379> zadd count 3 v3 4 v4 5 v5 6 v6
(integer) 4
127.0.0.1:6379> zunion 2 num count  #获取并集
1) "v1"
2) "v2"
3) "v5"
4) "v3"
5) "v6"
6) "v4"
127.0.0.1:6379> zinter 2 num count  #获取交集
1) "v3"
2) "v4"

三、内部实现

zset 的底层实现根据元素数量和大小自动选择:

  1. ziplist(压缩列表) :

    • 当元素数量较少(默认 ≤ 128),且所有元素长度较小(默认 ≤ 64 字节)时使用
    • 内存紧凑,按 score 排序存储
  2. skiplist(跳跃表) + dict(字典) :

    • 当不满足 ziplist 条件时使用
    • skiplist 用于按 score 排序和范围查询
    • dict 用于 O(1) 时间复杂度的元素查找

四、ZSet 类型的应用场景

排行榜系统 :最经典的用法。实现游戏积分榜、商品销量排名、热门内容榜单等,通过 ZREVRANGE 快速获取排名靠前的元素。例如:ZADD leaderboard 5000 "player1" 4800 "player2"。

延迟队列 :将任务的执行时间戳作为 score,使用 ZRANGEBYSCORE 获取到期的任务,实现定时任务调度。通过 ZREM 原子性地取出并删除已处理任务。

范围查询和分段统计 :对学生成绩、商品价格区间、用户年龄分布等进行分段查询和统计,通过 ZRANGEBYSCORE 和 ZCOUNT 实现高效的范围查询。

时间轴系统 :将时间戳作为 score,存储用户动态、新闻事件、系统日志等,通过 ZREVRANGE 获取最新的内容,实现时间序列数据的管理。

带权重的标签和推荐 :存储标签及其权重值,用于热门标签推荐、内容排序等,通过 ZINCRBY 动态调整权重,ZREVRANGE 获取热门项。

相关推荐
新鲜势力呀9 小时前
PHP 定时任务系统实战:从 Cron 混乱执行到任务调度中心 + Redis队列 + 失败重试
android·java·redis
hweiyu0010 小时前
Redis命令:HPTTL
redis·缓存
imDwAaY10 小时前
Redis List 是链表吗?从 Ziplist 到 Quicklist 揭开底层实现
redis·后端
知守观10 小时前
从三个带病的 Guava 本地缓存出发:Redis + Guava 二级缓存的读写路径与失效设计推演
java·redis·后端
imDwAaY11 小时前
Redis Set 如何节省内存?从整数集合到哈希表的设计取舍
数据结构·redis·散列表
ly768911 小时前
Spring Boot 集成 Redis 企业级实践:连接池、序列化与缓存穿透雪崩的工程化防御
spring boot·redis·缓存·缓存穿透·布隆过滤器·lettuce 连接池
x-Achan12 小时前
Redis实现方案:更新策略、穿透、雪崩、击穿、工具封装
java·spring boot·redis·spring·bootstrap·mybatis
ShineWinsu1 天前
对于Redis:Hash类型的解析
c++·redis·分布式·缓存·面试·hash·哈希表
.Hypocritical.1 天前
Redis从入门到实战:核心原理、场景落地与避坑指南
数据库·redis·缓存