目录
一.介绍
ZSET(有序集合)是 Redis 提供的一种数据结构,它与普通集合(SET)类似,不同之处在于每个元素都关联一个双精度浮点数的分数(score)。这使得 ZSET 在普通集合的基础上增加了一个排序的特性。这次的有序并不是list按顺序插入,而是指升序和降序。默认是升序
相当于给SET集合的元素标上个优先级排序,注:score可以重复
二.命令
ZADD命令
往有序集合当中添加元素和分数,
语法:ZADD key [ nx | xx ] [gt | lt ] [ch] [incr] score1 member1 score2 member2 ...
nx
:表示只在成员不存在时添加。xx
:表示只在成员已经存在时进行更新操作。- lt: 要求新分数要比原来分数低。
- gt: 要求新分数比原来分数高
- ch:命令会返回添加或更新的成员数量。如果没有指定该选项,则返回的是添加的成员数量(不包括更新的成员)。
- incr:元素已经存在,则将其原有的分数增加给定的分数。
zrange
查询结果,连带分数
语法:zrange key start end withscores
ZCARD
获取元素个数
语法:ZCARD KEY
ZCOUNT
获取最小范围到最大范围的值,返回个数。
语法:ZCOUNT key [ ( ] min [ ( ] max 添加上( 表示,不包括这个数值
ZRANGEBYSCORE
用于获取有序集合中指定分数范围内的成员列表
语法:
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
- WITHSCORES:可选参数,如果指定了此参数,则返回结果包含成员及其分数。
- LIMIT offset count:可选参数,用于限制返回结果的数量,从偏移量
offset
开始,最多返回count
个成员。
ZREVRANGE
逆序获取有序集合中指定分数范围内的成员列表
语法:zrevrange key 0 -1 withscores
ZPOPMAX
删除并返回分数最高的count个元素,如果相同,则根据字典序删除
语法:ZPOPMAX key [count]
注:ZPOPMIN,同样的语法使用
BZPOPMAX
从阻塞的有序集合中弹出分数最高的成员。当集合中没有元素时,直到元素可以弹出或者超时时间到达。
语法:BZPOPMAX key [key ...] timeout
注:BZPOPMIN同样的语法
ZRANK
获取指定元素的排名
语法:ZRANK KEY member
注:ZREVRANK 获取元素的倒数排名
zrem
根据member元素,删除
语法:zrem key member [member]
ZREMRANGEBYRANK
根据下标范围,删除元素
语法:zremrangebyrank key start stop
ZINCRBY
指定元素,给分数添加指定值
语法:ZINCRBY KEY 值 member
和SET一样,也拥有交、并。但没有直接支持的差集指令
交集:ZINTERSTORE output(存放在output当中) 2(这个代表几个成员) zset1 zset2 WEIGHTS 2 3 [ AGGREGATE MAX(相同值取最大值> | sum 取和 | MIN取最小值) ]
将 zset1
和 zset2
中分数值最大的成员放入 output
中,其中 zset1
的分数乘以 2,zset2
的乘以 3,如果有多个成员具有相同的分数,那么将使用指定的聚合函数来决定使用哪一个。
并集: ZUNIONSTORE DESTINATION NUMKEYS KEY [ KEY...] [WEIGHTS weight [weight ...] ] [ AGGREGATE <SUM | MIN | MAX >]
DESTINATION: 存储的位置
weights :权重,分数相乘
sum:相同member的值相加 MIN:相同的member取最小 MAX :相同的member取最大
三.编码方式
有序集合(ZSET)的内部编码采用了一种叫做 ziplist 的压缩列表(compressed list)来存储。
压缩列表 (ziplist):
- Redis 使用压缩列表作为内部数据结构来存储小型的有序集合。压缩列表是一种紧凑的连续内存结构,可以有效地存储较少数量的元素。
- 压缩列表通过将多个小元素存储在一起,并采用一些压缩技术来减少内存使用。这对于存储少量元素的有序集合非常有效,可以减少内存碎片化并提高存取效率。
升级为跳表 (skiplist):
- 当有序集合的元素数量增多,或者元素的大小超出了压缩列表的限制时,Redis 会将其升级为另一种更为复杂的数据结构,即跳表(skiplist)。
- 跳表是一种基于有序链表的数据结构,通过多级索引来加速元素的查找,能够在 O(log N) 的时间复杂度内进行插入、删除和查找操作。
跳表优势:
- 相对于压缩列表能够处理更大量级的数据,因为其查找效率更高,适用于大型的有序集合。
- 跳表的结构允许有序集合的元素按照分数进行排序,并支持高效的范围查询(range queries)操作。
四.应用场景
这种数据结构应用于各种各样的排行榜。例如:
- 游戏排行榜,记录每一名玩家的分数
- 热搜榜,记录每一条搜索的热度值
疑问?redis是内存存储的啊,少得可怜啊,可是玩家个数那么多,使用ZSET真的可以存储吗?
假设,游戏名按4个字节存储,分数按照8个字节存储,那么就12个字节,假设中国14亿玩家都玩游戏,那么就需要14.4GB,而ZGST是可以存储的下。
疑问?热搜榜,怎么设定呢?这个分数怎么获取呢?
答:你忘记了吗,我们可以使用WEIGHT权重,然后通过点赞量、转发量、评论量等,进行并集计算,得出最终分数。