Redis有序集合:高效排行榜实现方案
Zset有序集合
有序集合相对于字符串、列表、哈希、集合来说有一些陌生。它保留了集合不能有重复成员的特点,但和集合不同的是,有序集合中的每个元素都有一个唯一的浮点数类型的分数与之关联,使得有序集合中的元素是可以维护有序性的,单着恶搞有序不是用下表作为排序依据而是用这个分数。
有序集合提供了获取指定分数和元素范围查找,计算成员排名等功能,合理的利用有序集合,可以帮助我们在实际开发中解决很多问题
有序集合中的元素不能重复,但是分数允许重复。
普通命令
ZADD
添加或者更新指定的元素以及关联的分数到zset中,分数应该符合doube类型,+inf/-inf作为正负极限也是合法的
ZADD的相关选项
- XX:仅仅用来更新已经存在的元素,不会添加新元素
- NX:进用来添加新元素,不会更新已经存在的元素
- CH:默认情况下,ZADD返回的是本次添加的元素的个数,但指定这个选项之后,就会包含本次更新的元素的个数
- INCR:此时命令类似ZINCRBY的效果,将元素的分数加上指定的分数u。此时只能指定一个元素或者分数
语法:
ZADD key [NX | XX] [GT | LT] [CH] [INCR] score member [score member...]
时间复杂度:O(log(n))
返回值:本次添加成功的元素个数
举个例子:
ZCARD
获取一个zset得到基数,即zset中的元素个数
语法:
ZCARD key
时间复杂度:O(1)
返回值:zset内的元素个数
举个例子:
ZCOUNT
返回分数在min和max之间的元素个数,默认情况下,min和max都是包含的,可以通过(排除。
语法:
ZCOUNT key min max
时间复杂度:O(log(N))
返回值:满足条件的元素列表个数
ZRANGE
返回指定区间里的元素,分数按照升序。带上WITHSCORES可以把分数也返回
语法:
ZRANGE key start stop [WITHSCORES]
时间复杂度:O(log(N)+M)
返回值:区间内的元素列表
举个例子:
ZREVRANGE
返回指定区间里的元素,分数按照降序。带上WITHSCORES可以把分数也返回
语法:
ZREVRANGE key start stop [WITHSCORES]
时间复杂度:O(log(N)+M)
返回值:区间内的元素列表
ZRANGEBYSCORE
返回分数在min和max之间的元素,默认情况下,min和max都是包含的,可以通过(排除。
语法:
ZRANGEBYSCORE key min max [WITHSCORES]
时间复杂度:O(log(N)+M)
返回值:区间内的元素列表
ZPOPMAX
删除并返回分数最高的count个元素
语法:
ZPOPMAX key [count]
时间复杂度:O(log(N)*M)
返回值:分数和元素列表
举个例子:
BZPOPMAX
ZPOPMAX的阻塞版本
语法:
BZPOPMAX key [key ...] timeout
时间复杂度:O(log(N))
返回值:元素列表
举个例子:
ZPOPMIN
删除并返回分数最低的count个元素
语法:
ZPOPMIN key [count]
时间复杂度:O(log(N)*M)
返回值:分数和元素列表
举个例子:
BZPOPMIN
ZPOPMIN的阻塞版本
语法:
BZPOPMIN key [key ...] timeout
时间复杂度:O(log(N))
返回值:元素列表
举个例子:
ZRANK
返回指定元素的排名,升序
语法:
ZRANK key member
时间复杂度:O(log(N))
返回值:排名
举个例子:
ZREVRANK
返回执行元素的排名,降序
时间复杂度:O(log(N))
返回值:排名
ZSCORE
返回指定元素的分数
时间复杂度:O(1)
返回值:分数
举个例子
ZREM
ZREM key member [member ...]
举个例子
ZREMRANGEBYRANK
按照排序,升序删除指定范围的元素,左闭右闭
语法:
ZREMRANGEBYRANK key start stop
ZREMRANGEBYSCORE
ZREMRANGEBYSCORE key min max

ZINCRBY
ZINCRBY key increment member
时间复杂度:O(log(N))
返回值:增加后元素的分数

集合之间的操作

ZINTERSTOR


ZUNIONSTORE

命令小结

内部编码
有序集合类型的内部编码有两种
- ziplist(压缩列表):当有序集合的元素个数小于zset-max-ziplist-entries配置,同时每个元素的值都小于zset-max-ziplist-value配置时,Reids会使用ziplist来作为有序集合的内部实现,ziplist可以有效减少内存的使用
- skiplist(跳表):当ziplist条件不满足的时候,有序集合会使用ziplist作为内部实现,因为此时ziplist的操作效率会下降