Redis的sorted_set的用法,看完这一篇就够了

各位小伙伴们,我们上次讲过Redis中Set的相关操作,以及适用的一些场景,例如抽奖等。今天要讲的sorted_set,其实也是set的一种,也具有set去重的特点。和set不同的是,sorted_set是有序的,从字面意思也可以看得出来。

那sorted_set是怎么排序的,根据什么规则排序呢?往下看。

我们先来看下sored_set提供了哪些命令。

127.0.0.1:6379> help @sorted_set
  BZPOPMAX key [key ...] timeout  summary: Remove and return the member with the highest score from one or more sorted sets, or block until one is available  since: 5.0.0
  BZPOPMIN key [key ...] timeout  summary: Remove and return the member with the lowest score from one or more sorted sets, or block until one is available  since: 5.0.0

  ZADD key [NX|XX] [CH] [INCR] score member [score member ...]  summary: Add one or more members to a sorted set, or update its score if it already exists  since: 1.2.0
  ZCARD key  summary: Get the number of members in a sorted set  since: 1.2.0
  ZCOUNT key min max  summary: Count the members in a sorted set with scores within the given values  since: 2.0.0
  ZINCRBY key increment member  summary: Increment the score of a member in a sorted set  since: 1.2.0
  ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]  summary: Intersect multiple sorted sets and store the resulting sorted set in a new key  since: 2.0.0
  ZLEXCOUNT key min max  summary: Count the number of members in a sorted set between a given lexicographical range  since: 2.8.9
  ZPOPMAX key [count]  summary: Remove and return members with the highest scores in a sorted set  since: 5.0.0
  ZPOPMIN key [count]  summary: Remove and return members with the lowest scores in a sorted set  since: 5.0.0
  ZRANGE key start stop [WITHSCORES]  summary: Return a range of members in a sorted set, by index  since: 1.2.0
  ZRANGEBYLEX key min max [LIMIT offset count]  summary: Return a range of members in a sorted set, by lexicographical range  since: 2.8.9
  ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]  summary: Return a range of members in a sorted set, by score  since: 1.0.5
  ZRANK key member  summary: Determine the index of a member in a sorted set  since: 2.0.0
  ZREM key member [member ...]  summary: Remove one or more members from a sorted set  since: 1.2.0
  ZREMRANGEBYLEX key min max  summary: Remove all members in a sorted set between the given lexicographical range  since: 2.8.9
  ZREMRANGEBYRANK key start stop  summary: Remove all members in a sorted set within the given indexes  since: 2.0.0
  ZREMRANGEBYSCORE key min max  summary: Remove all members in a sorted set within the given scores  since: 1.2.0
  ZREVRANGE key start stop [WITHSCORES]  summary: Return a range of members in a sorted set, by index, with scores ordered from high to low  since: 1.2.0
  ZREVRANGEBYLEX key max min [LIMIT offset count]  summary: Return a range of members in a sorted set, by lexicographical range, ordered from higher to lower strings.  since: 2.8.9
  ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]  summary: Return a range of members in a sorted set, by score, with scores ordered from high to low  since: 2.2.0
  ZREVRANK key member  summary: Determine the index of a member in a sorted set, with scores ordered from high to low  since: 2.0.0
  ZSCAN key cursor [MATCH pattern] [COUNT count]  summary: Incrementally iterate sorted sets elements and associated scores  since: 2.8.0
  ZSCORE key member  summary: Get the score associated with the given member in a sorted set  since: 1.2.0
  ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]  summary: Add multiple sorted sets and store the resulting sorted set in a new key  since: 2.0.0

可以看到,sorted_set 中的命令大多以 Z 开头,因为set占用 S 了嘛。还有某些命令中有REV关键字,代表Reverse,反向的意思。

另外,还有两个命令以B开头,这里B代表Blocked,即阻塞的,上述帮助文档里也有说明(block until one is available)。

命令看起来挺多,我们大致做个分类。

图片

 


sorted_set的基本用法

下面,我们来看下常用命令的具体用法。

一、基本操作

 从ZADD命令可以看出,向key中添加元素时,有个参数score。没错,sorted_set 对每个元素都设定了分值,并在add时,根据这个分值进行升序排序。

  ZADD key [NX|XX] [CH] [INCR] score member [score member ...]  summary: Add one or more members to a sorted set, or update its score if it already exists  since: 1.2.0
/* 将笔试成绩(tom-100,jack-60,tony-80)放入名为 writtenTestScore 的有序集合里,返回元素个数3*/127.0.0.1:6379> zadd writtenTestScore 100 tom 60 jack 80 tony(integer) 3/面试成绩*/127.0.0.1:6379> zadd interviewScore 70 tom 80 jack 60 tony(integer) 3/*zrange列出所有元素*/127.0.0.1:6379> zrange writtenTestScore 0 -11) "jack"2) "tony"3) "tom"/*zrange列出所有元素(笔试成绩),带分值*/127.0.0.1:6379> zrange writtenTestScore 0 -1 withscores1) "jack"2) "60"3) "tony"4) "80"5) "tom"6) "100"/*列出面试成绩*/127.0.0.1:6379> zrange interviewScore 0 -1 withscores1) "tony"2) "60"3) "tom"4) "70"5) "jack"6) "80"下面是删除元素的一些操作,包括 

ZPOPMAX/BZPOPMAX,ZPOPMIN/BZPOPMIN、ZREM等。

127.0.0.1:6379> ZADD testREM 1 a 2 b 3 c 4 d(integer) 4127.0.0.1:6379> zpopmax testREM 1) "d"2) "4"127.0.0.1:6379> zrem testREM a(integer) 1/*删除10个最大的元素并返回*/127.0.0.1:6379> zpopmax testREM 101) "c"2) "3"3) "b"4) "2"/*元素为空,阻塞1s后,返回空*/127.0.0.1:6379> BZPOPMAX testREM 1(nil)(1.01s/*取某个元素的分值*/127.0.0.1:6379> ZSCORE interviewScore tony"60"

二、统计类操作

统计类操作大致包括两类,一类是取元素的个数或排名,一类是取元素的列表。

/*列出80-100分数段的元素个数*/127.0.0.1:6379> zcount writtenTestScore 80 100(integer) 2/*返回集合中元素个数*/127.0.0.1:6379> zcard writtenTestScore (integer) 3/*取jack的排名*/127.0.0.1:6379> ZRANK writtenTestScore jack(integer) 0
/*取出80-100分数段的元素*/127.0.0.1:6379> ZRANGEBYSCORE writtenTestScore 80 100 withscores1) "tony"2) "80"3) "tom"4) "100"/*取笔试分数最高的前两名*/127.0.0.1:6379> ZREVRANGE writtenTestScore 0 1 withscores1) "tom"2) "100"3) "tony"4) "80"

三、运算类操作

127.0.0.1:6379> ZRANGE writtenTestScore 0 -1 withscores1) "jack"2) "60"3) "tony"4) "80"5) "tom"6) "100"
对jack的分值进行加法运算后,jack排到了第二个位置。
127.0.0.1:6379> ZINCRBY writtenTestScore 30 jack"90"127.0.0.1:6379> ZRANGE writtenTestScore 0 -1 withscores1) "tony"2) "80"3) "jack"4) "90"5) "tom"6) "100"

也就是说,sorted_set 对集合的每一次变更,都随时维护着一个按分值排序的顺序。

下面来看并集与交集的操作。

为了方便理解交集和并集,我们分别对writtenTestScore和

interview_Score进行增加元素的操作。即polly只参加了笔试,lucy只参加了面试。

127.0.0.1:6379> zadd writtenTestScore 50 polly (integer) 1127.0.0.1:6379> ZRANGE writtenTestScore 0 -1 withscores1) "polly"2) "50"3) "tony"4) "80"5) "jack"6) "90"7) "tom"8) "100"127.0.0.1:6379> zadd interviewScore 50 lucy(integer) 1127.0.0.1:6379> ZRANGE interviewScore 0 -1 withscores1) "lucy"2) "50"3) "tony"4) "60"5) "tom"6) "70"7) "jack"8) "80"
假设现在要根据笔试(权重0.6)和面试(权重0.4)的总分数进行排序,可以用 ZUNIONSTORE 来实现。
127.0.0.1:6379> ZUNIONSTORE result 2 writtenTestScore interviewScore weights 0.6 0.4 aggregate sum(integer) 5/*lucy只参加了面试,50*0.4=20; tony笔试80*0.6+面试60*0.4=72*/127.0.0.1:6379> ZRANGE result 0 -1 withscores 1) "lucy" 2) "20" 3) "polly" 4) "30" 5) "tony" 6) "72" 7) "jack" 8) "86" 9) "tom"10) "88"

假设需求有变化,增加条件限制:面试和笔试都参加的。此时,可以使用集合交集运算 ZINTERSTORE。

127.0.0.1:6379> ZINTERSTORE result 2  writtenTestScore interviewScore weights 0.6 0.4 aggregate sum(integer) 3127.0.0.1:6379> ZRANGE result 0 -1 withscores1) "tony"2) "72"3) "jack"4) "86"5) "tom"6) "88"

 

关于sorted_set的排序算法

sorted_set对于集合变更的操作,例如zadd,zrem,zpop,zincrby等,都随时维护着一个排序。

简单理解,这里的排序算法是用skipList(跳表)实现的。举个例子,跳表的算法类似于,我们找书上的某一页,会先找到目录一样。当然,跳表的“目录”可能不止一层。


总结

稍微总结一下,本次分享了sorted_set的三种类型的操作,分别是基本操作(包括添加、删除)、统计类(集合中符合某些条件的元素个数、排名、元素列表)操作以及运算类(交集、并集、加法)操作。

sorted_set一般适用于排行榜,例如按照动态的点赞数(作为set中key的分值)、帖子的点击率排名等场景。

简单理解,sorted_set使用跳表实现的。

好了,本次分享就是这样,我们下次见。

 

关注我,持续输出技术干货。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冷风在北京

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值