Redis 基础 -- 有序集合 SortedSet类型 和 SortedSet类型的常用命令
Posted CodeJiao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis 基础 -- 有序集合 SortedSet类型 和 SortedSet类型的常用命令相关的知识,希望对你有一定的参考价值。
文章目录
- 1. 有序集合(SortedSet)
- 1.1 ZADD:添加或更新成员
- 1.2 ZREM:移除指定的成员
- 1.3 ZSCORE:获取成员的分值
- 1.4 ZINCRBY:对成员的分值执行自增或自减操作
- 1.5 ZCARD:获取有序集合的大小
- 1.6 ZRANK、ZREVRANK:获取成员在有序集合中的排
- 1.7 ZRANGE、ZREVRANGE:获取指定索引范围内的成员
- 1.8 ZRANGEBYSCORE、ZREVRANGEBYSCORE:获取指定分值范围内的成员
- 1.9 ZCOUNT:统计指定分值范围内的成员数量
- 1.10 ZREMRANGEBYRANK:移除指定排名范围内的成员
- 1.11 ZREMRANGEBYSCORE:移除指定分值范围内的成员
- 1.12 ZDIFF:求有序集合的差集
- 1.13 ZINTER:求有序集合的交集
- 1.14 ZUNION:求有序集合的并集
- 1.15 ZDIFFSTORE:有序集合的差集运算
- 1.16 ZUNIONSTORE、ZINTERSTORE:有序集合的并集运算和交集运算
- 1.17 ZRANGEBYLEX、ZREVRANGEBYLEX:返回指定字典序范围内的成员
- 1.18 ZLEXCOUNT:统计位于字典序指定范围内的成员数量
- 1.19 ZREMRANGEBYLEX:移除位于字典序指定范围内的成员
- 1.20 ZPOPMAX、ZPOPMIN:弹出分值最高和最低的成员
- 1.21 BZPOPMAX、BZPOPMIN:阻塞式最大/最小元素弹出操作
- 1.22 重点回顾
1. 有序集合(SortedSet)
Redis的有序集合(SortedSet)同时具有 有序 和 集合 两种性质,这种数据结构中的每个元素都由一个成员和一个与成员相关联的分值组成,其中成员(value)以字符串方式存储,而分值(score)则以64位双精度浮点数格式存储。
- 下图展示了一个记录薪水数据的有序集合:
- 下图展示了一个记录水果价格的有序集合:
与集合一样,有序集合中的每个成员都是独一无二的,同一个有序集合中不会出现重复的成员。与此同时,有序集合的成员将按照它们各自的分值大小进行排序。有序集合的分值除了可以是数字之外,还可以是字符串"+inf"或者"-inf",这两个特殊值分别用于表示无穷大和无穷小。需要注意的是,虽然同一个有序集合不能存储相同的成员,但不同成员的分值却可以是相同的。当两个或多个成员拥有相同的分值时,Redis将按照这些成员在字典序中的大小对其进行排列:举个例子,如果成员"apple"和成员"zero"都拥有相同的分值100,那么Redis将认为成员"apple"小于成员"zero",这是因为在字典序中,字母"a"开头的单词要小于字母"z"开头的单词。
有序集合是Redis提供的所有数据结构中最为灵活的一种,它可以以多种不同的方式获取数据,比如根据成员获取分值、根据分值获取成员、根据成员的排名获取成员、根据指定的分值范围获取多个成员等。
1.1 ZADD:添加或更新成员
通过使用ZADD命令,用户可以向有序集合添加一个或多个新成员。
语法:
在默认情况下,ZADD命令将返回成功添加的新成员数量作为返回值。
示例:
如果我们对不存在的键salary执行以下命令:
那么命令将创建出一个包含4个成员的有序集合,如图所示:
1.1.1 更新已有成员的分值
ZADD命令除了可以向有序集合添加新成员之外,还可以对有序集合中已存在成员的分值进行更新:在默认情况下,如果用户在执行ZADD命令时,给定成员已经存在于有序集合中,并且给定的分值和成员现有的分值并不相同,那么ZADD命令将使用给定的新分值去覆盖现有的旧分值。
示例:
那么"tom"成员的分值将从原来的2000变为5000,更新后的有序集合如图所示:
1.1.2 指定要执行的操作
从Redis 3.0.2版本开始,Redis允许用户在执行ZADD命令时,通过使用可选的XX选项或者NX选项来显式地指示命令只执行更新操作或者只执行添加操作:
- 在给定XX选项的情况下,ZADD命令只会对给定成员当中已经存在于有序集合的成员进行更新,而那些不存在于有序集合的给定成员则会被忽略。换句话说,带有XX选项的ZADD命令只会对有序集合已有的成员进行更新,而不会向有序集合添加任何新成员。
- 在给定NX选项的情况下,ZADD命令只会把给定成员当中不存在于有序集合的成员添加到有序集合里面,而那些已经存在于有序集合中的给定成员则会被忽略。换句话说,带有NX选项的ZADD命令只会向有序集合添加新成员,而不会对已有的成员进行任何更新。
XX示例:
对于下图所示的有序集合来说,执行以下命令只会将已有成员"jack"的分值从原来的4000改为4500,而命令中出现的新成员"bob"则不会被添加到有序集合中:
下图展示了命令执行之后的salary有序集合,注意"bob"并没有被添加到有序集合当中。
NX示例:
如果我们对下图所示的有序集合执行以下命令:
那么ZADD命令将把新成员"bob"添加到有序集合里面,但并不会改变已有成员"jack"的分值,命令执行后的salary有序集合如图所示。
1.1.3 返回被修改成员的数量
在默认情况下,ZADD命令会返回新添加成员的数量作为返回值,但是从Redis3.0.2版本开始,用户可以通过给定CH选项,让ZADD命令返回被修改(changed)成员的数量作为返回值。
“被修改成员”指的是新添加到有序集合的成员,以及分值被更新了的成员。
1.1.4 时间复杂度说明
复杂度:O(M*log(N)),其中M为给定成员的数量,而N则为有序集合包含的成员数量。
1.2 ZREM:移除指定的成员
通过使用ZREM命令,用户可以从有序集合中移除指定的一个或多个成员以及与这些成员相关联的分值。
语法:
ZREM命令会返回被移除成员的数量作为返回值。
示例:
对于下面的有序集合来说
我们呢移除yuwen和shuxu2个元素
移除后
如果用户给定的某个成员并不存在于有序集合中,那么ZREM将自动忽略该成员。
说明:
复杂度:O(M*log(N)),其中M为给定成员的数量,N为有序集合包含的成员数量。
1.3 ZSCORE:获取成员的分值
通过使用ZSCORE命令,用户可以获取与给定成员相关联的分值。
语法:
示例:
对于下面的有序集合来说
我们去查看en对应的分数。
如果用户给定的有序集合并不存在,或者有序集合中并未包含给定的成员,那么ZSCORE命令将返回nil。
说明:
复杂度:O(1)。
1.4 ZINCRBY:对成员的分值执行自增或自减操作
通过使用ZINCRBY命令,用户可以对有序集合中指定成员的分值执行自增操作,为其加上指定的增量。
语法:
ZINCRBY命令在执行完自增操作之后,将返回给定成员当前的分值。
示例:
对于下面的有序集合来说
我们去让yuwen加5分。
我们去让shuxu减3分。
我们去让en加1.5分。
如果用户在执行ZINCRBY命令时,给定成员并不存在于有序集合中,或者给定的有序集合并不存在,那么ZINCRBY命令将直接把给定的成员添加到有序集合中,并把给定的增量设置为该成员的分值,效果相当于执行ZADD命令。
说明:
复杂度:O(log (N)),其中N为有序集合包含的成员数量。
1.5 ZCARD:获取有序集合的大小
通过执行ZCARD命令可以取得有序集合的基数,即有序集合包含的成员数量。
语法:
示例:
对于下面的有序集合来说:
我们来获取有序集合的大小:
如果用户给定的有序集合并不存在,那么ZCARD命令将返回0作为结果
说明:
复杂度:O(1)。
1.6 ZRANK、ZREVRANK:获取成员在有序集合中的排
通过ZRANK命令和ZREVRANK命令,用户可以取得给定成员在有序集合中的排名。
其中ZRANK命令返回的是成员的升序排列排名,即成员在按照分值从小到大进行排列时的排名,而ZREVRANK命令返回的则是成员的降序排列排名,即成员在按照分值从大到小进行排列时的排名。
语法:
示例:
对于下面的有序集合来说:
我们去获取en的排名(升序)
我们去获取yuwen的排名(降序)
如果用户给定的有序集合并不存在,或者用户给定的成员并不存在于有序集合当中,那么ZRANK命令和ZREVRANK命令将返回一个nil。
说明:
复杂度:O(log (N)),其中N为有序集合包含的成员数量。
1.7 ZRANGE、ZREVRANGE:获取指定索引范围内的成员
通过ZRANGE命令和ZREVRANGE命令,用户可以以升序排列或者降序排列方式,从有序集合中获取指定索引范围内的成员。
其中ZRANGE命令用于获取按照分值大小实施升序排列的成员,而ZREVRANGE命令则用于获取按照分值大小实施降序排列的成员。命令中的start索引和end索引指定的是闭区间索引范围,也就是说,位于这两个索引上的成员也会包含在命令返回的结果当中。
语法:
示例:
对于下面的有序集合来说:
获取索引 [0,3] 之间的数据
如果我们想要获取user有序集合在按照降序排列成员时,位于索引2至索引3范围内的成员,那么可以执行以下命令:
1.7.1 使用负数索引
与前面 介绍过的LRANGE命令类似,ZRANGE命令和ZREVRANGE命令除了可以接受正数索引之外,还可以接受负数索引。
比如,如果我们想要以升序排列的方式获取user有序集合的最后3个成员,那么可以执行以下命令:
与此类似,如果我们想要以降序排列的方式获取user有序集合的最后一个成员,那么可以执行以下命令:
最后,如果我们想要以升序排列或者降序排列的方式获取salary有序集合包含的所有成员,那么只需要将起始索引设置为0,结束索引设置为-1,然后调用ZRANGE命令或者ZREVRANGE命令即可。
1.7.2 获取成员及其分值
在默认情况下,ZRANGE命令和ZREVRANGE命令只会返回指定索引范围内的成员,如果用户想要在获取这些成员的同时也获取与之相关联的分值,那么可以在调用ZRANGE命令或者ZREVRANGE命令的时候,给定可选的WITHSCORES选项。
示例:
1.7.3 处理不存在的有序集合
如果用户给定的有序集合并不存在,那么ZRANGE命令和ZREVRANGE命令将返回一个空列表。
17.4 时间复杂度说明
复杂度:O(log (N) + M),其中N为有序集合包含的成员数量,而M则为命令返回的成员数量。
1.8 ZRANGEBYSCORE、ZREVRANGEBYSCORE:获取指定分值范围内的成员
通过使用ZRANGEBYSCORE命令或者ZREVRANGEBYSCORE命令,用户可以以升序排列或者降序排列的方式获取有序集合中分值介于指定范围内的成员。
语法:
升序排列的方式获取有序集合中分值介于指定范围内的成员。
降序排列的方式获取有序集合中分值介于指定范围内的成员。
命令的min参数和max参数分别用于指定用户想要获取的成员的最小分值和最大分值。
不过需要注意的是,ZRANGEBYSCORE命令和ZREVRANGEBYSCORE命令接受min参数和max参数的顺序正好相反:ZRANGEBYSCORE命令先接受min参数然后再接受max参数,而ZREVRANGEBYSCORE命令则是先接受max参数然后再接受min参数。
示例:
对于下面的有序集合来说:
我们来获取成绩在[90,115]之间的数据。
1.8.1 获取成员及其分值
与ZRANGE命令和ZREVRANGE命令类似,ZRANGEBYSCORE命令和ZREVRANGEBY SCORE命令也可以通过在执行时给定可选的WITHSCORES选项来同时获取成员及其分值。
示例:
1.8.2 限制命令返回的成员数量
在默认情况下,ZRANGEBYSCORE命令和ZREVRANGEBYSCORE命令会直接返回给定分值范围内的所有成员,但如果范围内的成员数量较多,或者我们只需要范围内的其中一部分成员,那么可以使用可选的LIMIT选项来限制命令返回的成员数量。
LIMIT选项接受offset和count两个参数作为输入,其中offset参数用于指定命令在返回结果之前需要跳过的成员数量,而count参数则用于指示命令最多可以返回多少个成员。
示例:
假设我们想要以升序排列方式获取user有序集合中分值介于 [90,115] 的第一个成员,那么可以执行以下命令:
在这个命令中,offset参数的值为0,表示命令不需要跳过任何成员;而count参数的值为1,表示命令只需要返回一个成员即可。
如果我们想要以升序排列方式,获取salary有序集合中分值介于 [90,120] 的第二个和第三个成员,那么可以执行以下命令:
在这个命令中,offset参数的值为1,表示命令需要跳过指定分值范围内的第一个成员,count参数的值为2,表示命令需要在跳过第一个成员之后,获取接下来的两个成员,而这两个成员就是位于指定分值范围内的第二个和第三个成员。
1.8.3 使用开区间分值范围
在默认情况下,ZRANGEBYSCORE命令和ZREVRANGEBYSCORE命令接受的分值范围都是闭区间分值范围,也就是说,分值等于用户给定最大分值或者最小分值的成员也会被包含在结果当中。
如果用户想要定义的是开区间而不是闭区间,那么可以在给定分值范围时,在分值参数的前面加上一个单括号“(”,这样,具有给定分值的成员就不会出现在命令返回的结果当中。
示例:
对于下面的有序集合来说:
以下命令只会返回分值位于 (90,127)的成员,不包括90和127:
1.8.4 使用无限值作为范围
ZRANGEBYSCORE命令和ZREVRANGEBYSCORE命令的min参数和max参数除了可以是普通的分值或者带有(符号的分值之外,还可以是特殊值+inf或者-inf,前者用于表示无穷大,而后者则用于表示无穷小:当我们只想定义分值范围的上限或者下限,而不是同时定义分值范围的上限和下限时,+inf和-inf就可以派上用场。
示例:
1.8.5 时间复杂度说明
复杂度:ZRANGEBYSCORE命令和ZREVRANGEBYSCORE命令的复杂度都是O(log (N) +M),其中N为有序集合包含的成员数量,而M则为命令返回的成员数量。
1.9 ZCOUNT:统计指定分值范围内的成员数量
通过使用ZCOUNT命令,用户可以统计出有序集合中分值介于指定范围之内的成员数量。
语法:
示例:
对于下面的有序集合来说:
我们可以通过执行以下命令,统计出user有序集合中分值介于[90,120]之间的成员数量:
ZCOUNT命令接受的分值范围格式和ZRANGEBYSCORE命令接受的分值范围格式完全相同:用户可以在执行ZCOUNT命令时,使用+inf表示无穷大分值,使用-inf表示无穷小分值,或者使用单括号(定义开区间分值范围。
说明:
复杂度:O(log (N)),其中N为有序集合包含的成员数量。
1.10 ZREMRANGEBYRANK:移除指定排名范围内的成员
ZREMRANGEBYRANK命令可以从升序排列的有序集合中移除位于指定排名范围内的成员,然后返回被移除成员的数量。
语法:
与Redis的其他很多范围型命令一样,ZREMRANGEBYRANK命令接受的也是一个闭区间范围,也就是说,排名为start和end的成员也将被移除。
示例:
对于下面的有序集合来说:
以下代码展示了如何移除user有序集合中升序排名0~2位的3个成员:移除元素后:
传给ZREMRANGEBYRANK命令的排名参数除了可以是正数之外还可以是负数。举个例子,假如我们需要从user有序集合中移除排名倒数前3位的成员,那么只需要执行以下命令即可。
说明:
复杂度:O(log (N) + M),其中N为有序集合包含的成员数量,M为被移除的成员数量。
1.11 ZREMRANGEBYSCORE:移除指定分值范围内的成员
ZREMRANGEBYSCORE命令可以从有序集合中移除位于指定分值范围内的成员,并在移除操作执行完毕返回被移除成员的数量。
语法:
ZREMRANGEBYSCORE命令接受的分值范围与ZRANGEBYSCORE命令和ZCOUNT命令接受的分值范围一样,都默认为闭区间分值范围,但用户可以使用(符号定义闭区间,或者使用+inf和-inf表示正无限分值或者负无限分值。
示例:
对于下面的有序集合来说:
以下代码展示了如何使用ZREMRANGEBYSCORE命令移除nums有序集合中分值介于[2,4]的成员:
移除后:
说明:
复杂度:O(log (N) + M),其中N为有序集合包含的成员数量,M为被移除成员的数量。
1.12 ZDIFF:求有序集合的差集
求有序集合的差集,该命令类似于ZDIFFSTORE,但不会存储结果排序集,而是将其返回给客户端。
语法:
示例:
对于下列的集合:
求zset1和zset2,zset3的差集。
如果需要展示分数需要加上WITHSCORES参数:
1.13 ZINTER:求有序集合的交集
求有序集合的交集,该命令类似于ZINTERSTORE,但不会存储结果排序集,而是将其返回给客户端。
语法:
示例:
对于下列的集合:
求zset1和zset2,zset3的交集。
1.14 ZUNION:求有序集合的并集
求有序集合的并集,该命令类似于ZUNIONSTORE,但不会存储结果排序集,而是将其返回给客户端。
语法:
示例:
对于下列的集合:
求zset1和zset2,zset3的并集。
1.15 ZDIFFSTORE:有序集合的差集运算
语法:
命令的numbers参数用于指定参与计算的有序集合数量,之后的一个或多个sorted_set参数则用于指定参与计算的各个有序集合键,计算得出的结果则会存储到destination参数指定的键中。
示例:
对于下列的集合:
求zset1和zset2,zset3的差集,并保存到zset4中。
1.16 ZUNIONSTORE、ZINTERSTORE:有序集合的并集运算和交集运算
命令的numbers参数用于指定参与计算的有序集合数量,之后的一个或多个sorted_set参数则用于指定参与计算的各个有序集合键,计算得出的结果则会存储到destination参数指定的键中。ZUNIONSTORE命令和ZINTERSTORE命令都会返回计算结果包含的成员数量作为返回值。
语法:
ZUNIONSTORE
ZINTERSTORE
示例:
这里就不做基本的示例了,可以参考上面的ZDIFFSTORE。
1.16.1 指定聚合函数
Redis为ZUNIONSTORE命令和ZINTERSTORE命令提供了可选的AGGREGATE选项,通过这个选项,用户可以决定使用哪个聚合函数来计算结果有序集合成员的分值。
AGGREGATE选项的值可以是SUM、MIN或者MAX中的一个,下表展示了这3个聚合函数的不同作用。
示例:
对于下图所示的3个有序集合ss1、ss2和ss3来说,使用SUM作为聚合函数进行交集计算,将得出一个分值为8的成员a:
这个分值是通过将1、2、5这3个分值相加得出的,如图所示。
使用MIN作为聚合函数进行交集计算,将得出一个分值为1的成员a:
这个分值是通过从1、2、5这3个分值中选出最小值得出的,如图所示。
最后,使用MAX作为聚合函数进行交集计算,将得出一个分值为5的成员a:
这个分值是通过从1、2、5这3个分值中选出最大值得出的,如图所示。
在没有显式地使用AGGREGATE选项指定聚合函数的情况下,ZUNIONSTORE和ZINTERSTORE默认使用SUM作为聚合函数。
1.16.2 设置权重
在默认情况下,ZUNIONSTORE和ZINTERSTORE将直接使用给定有序集合的成员分值去计算结果有序集合的成员分值,但是在有需要的情况下,用户也可以通过可选的WEIGHTS参数为各个给定有序集合的成员分值设置权重。
在使用WEIGHTS选项时,用户需要为每个给定的有序集合分别设置一个权重,命令会将这个权重与成员的分值相乘,得出成员的新分值,然后执行聚合计算;与此相反,如果用户在使用WEIGHTS选项时,不想改变某个给定有序集合的分值,那么只需要将那个有序集合的权重设置为1即可。
示例:
如果我们对下图所示的3个有序集合执行以下命令:
那么wss1有序集合成员"a"的分值2将被乘以3,变为6; wss2有序集合成员"b"的分值4则会被乘以5,变为20;wss3有序集合成员的分值3则会保持不变;通过进行并集计算,命令最终将得出图6-32所示的结果有序集合weighted-result。
1.16.3 使用集合作为输入
ZUNIONSTORE和ZINTERSTORE除了可以使用有序集合作为输入之外,还可以使用集合作为输入:在默认情况下,这两个命令将把给定集合看作所有成员的分值都为1的有序集合来进行计算。如果有需要,用户也可以使用WEIGHTS选项来改变给定集合的分值,比如,如果你希望某个集合所有成员的分值都被看作10而不是1,那么只需要在执行命令时把那个集合的权重设置为10即可。
示例:
对于下图所示的集合和有序集合来说,我们可以执行以下命令,对它们进行并集计算,并将计算结果存储到mixed有序集合中:
下图展示了mixed有序集合示例。
1.16.4 时间复杂度说明
复杂度:ZUNIONSTORE命令的复杂度为O(Nlog(N)),其中N为所有给定有序集合的成员总数量。ZINTERSTORE命令的复杂度为O(Nlog(N)*M),其中N为所有给定有序集合中,基数最小的那个有序集合的基数,而M则是给定有序集合的数量。
1.17 ZRANGEBYLEX、ZREVRANGEBYLEX:返回指定字典序范围内的成员
ZRANGEBYLEX命令可以从字典序排列的有序集合中获取位于字典序指定范围内的成员。
ZREVRANGEBYLEX命令是逆序版的ZRANGEBYLEX命令,它会以逆字典序的方式返回指定范围内的成员。
语法:
ZRANGEBYLEX
ZREVRANGEBYLEX
命令的min参数和max参数用于指定用户想要获取的字典序范围,它们的值可以是以下4种值之一:
- 带有
[
符号的值表示在结果中包含与给定值具有同等字典序大小的成员。 - 带有
(
符号的值表示在结果中不包含与给定值具有同等字典序大小的成员。 - 加号+表示无穷大。
- 减号-表示无穷小。
示例:
ZRANGEBYLEX:
对于下图所示的words有序集合来说,如果我们想要通过ZRANGEBYLEX命令获取words有序集合包含的所有成员,那么只需要将min参数的值设置为-, max参数的值设置为+即可:
如果我们想要获取words有序集合中所有以字母"a"开头的成员,那么只需要将min参数的值设置为[a , max参数的值设置为(b即可:
ZREVRANGEBYLEX:
以下代码展示了如何以逆字典序的方式返回有序集合中所有以字母"a"和字母"b"开头的成员:
1.17.1 限制命令返回的成员数量
与有序集合的其他范围型获取命令一样,ZRANGEBYLEX和ZREVRANGEBYLEX也可以通过可选的LIMIT选项来限制命令返回的成员数量。
示例:
以下代码展示了如何以逆字典序的方式返回有序集合中第一个以字母"b"开头的成员:
1.17.2 时间复杂度说明
复杂度:ZRANGEBYLEX命令和ZREVRANGEBYLEX命令的复杂度都为O(log (N)+ M),其中N为有序集合包含的元素数量,而M则为命令返回的成员数量。
1.18 ZLEXCOUNT:统计位于字典序指定范围内的成员数量
对于按照字典序排列的有序集合,用户可以使用ZLEXCOUNT命令统计有序集合中位于字典序指定范围内的成员数量。
语法:
ZLEXCOUNT命令的min参数和max参数的格式与ZRANGEBYLEX命令接受的min参数和max参数的格式完全相同。
示例:
对于words有序集合:
通过执行以下命令,我们可以统计出words有序集合中以字母"a"开头的成员数量:
或者使用以下命令,统计出有序集合中字典序大于等于字母"b"的成员数量:
说明:
复杂度:O(log (N)),其中N为有序集合包含的成员数量。
1.19 ZREMRANGEBYLEX:移除位于字典序指定范围内的成员
对于按照字典序排列的有序集合,用户可以使用ZREMRANGEBYLEX命令去移除有序集合中位于字典序指定范围内的成员。
语法:
这个命令的min参数和max参数的格式与ZRANGEBYLEX命令以及ZLEXCOUNT命令接受的min参数和max参数的格式完全相同。ZREMRANGEBYLEX命令在移除用户指定的成员之后,将返回被移除成员的数量作为命令的返回值。
示例:
对于words有序集合:
展示了如何移除words有序集合中所有以字母"b"开头的成员:
说明:
复杂度:O(log (N) + M),其中N为有序集合包含的成员数量,M为被移除成员的数量。
1.20 ZPOPMAX、ZPOPMIN:弹出分值最高和最低的成员
ZPOPMAX和ZPOPMIN是Redis 5.0版本新添加的两个命令,分别用于移除并返回有序集合中分值最大和最小的N个元素。
语法:
ZPOPMAX
ZPOPMIN
其中被移除元素的数量可以通过可选的count参数来指定。如果用户没有显式地给定count参数,那么命令默认只会移除一个元素。
示例:
对于下图所示的有序集合user来说,我们可以通过执行以下两个命令,分别移除有序集合中分值最大和最小的元素:
也可以一次弹出多个最大的元素,下面展示一次弹出最大的2个元素。
说明:
复杂度:O(N),其中N为命令移除的元素数量。
1.21 BZPOPMAX、BZPOPMIN:阻塞式最大/最小元素弹出操作
BZPOPMAX命令和BZPOPMIN命令分别是ZPOPMAX命令以及ZPOPMIN命令的阻塞版本,这两个阻塞命令都接受任意多个有序集合和一个秒级精度的超时时限作为参数。
语法:
BZPOPMAX
BZPOPMIN
接收到参数的BZPOPMAX命令和BZPOPMIN命令会依次检查用户给定的有序集合,并从它遇到的第一个非空有序集合中弹出指定的元素。如果命令在检查了所有给定有序集合之后都没有发现可弹出的元素,那么它将阻塞执行命令的客户端,并在给定的时限之内等待可弹出的元素出现,直到等待时间超过给定时限为止。用户可以通过将超时时限设置为0来让命令一直阻塞,直到可弹出的元素出现为止。
BZPOPMAX命令和BZPOPMIN命令在成功弹出元素时将返回一个包含3个项的列表,这3个项分别为被弹出元素所在的有序集合、被弹出元素的成员以及被弹出元素的分值。与此相反,如果这两个命令因为等待超时而未能弹出任何元素,那么它们将返回一个空值作为结果。
示例:
对于下图所示的有序集合user来说,我们可以通过执行以下两个命令,分别移除有序集合中分值最大的元素:
说明:
复杂度:O(N),其中N为用户给定的有序集合数量。
1.22 重点回顾
- 有序集合同时拥有“有序”和“集合”两种性质,集合性质保证有序集合只会包含各不相同的成员,而有序性质则保证了有序集合中的所有成员都会按照特定的顺序进行排列。
- 在一般情况下,有序集合成员的大小由分值决定,而分值相同的成员的大小则由成员在字典序中的大小决定。
- 成员的分值除了可以是数字之外,还可以是表示无穷大的"+inf"或者表示无穷小的"-inf"。
- ZADD命令从Redis 3.0.2版本开始,可以通过给定可选项来决定执行添加操作或是执行更新操作。
- 因为Redis只提供了对成员分值执行加法计算的ZINCRBY命令,而没有提供相应的减法计算命令,所以我们只能通过向ZINCRBY命令传入负数增量来对成员分值执行减法计算。
- ZINTERSTORE命令和ZUNIONSTORE命令除了可以使用有序集合作为输入之外,还可以使用集合作为输入。在默认情况下,这两个命令会把集合的成员看作分值为1的有序集合成员来计算。
- 当有序集合的所有成员都拥有相同的分值时,用户可以通过ZRANGEBYLEX、ZLEXCOUNT、ZREMRANGEBYLEX等命令,按照字典序对有序集合中的成员进行操作。
以上是关于Redis 基础 -- 有序集合 SortedSet类型 和 SortedSet类型的常用命令的主要内容,如果未能解决你的问题,请参考以下文章