Redis 的命令详解 - Sorted Set 篇

5,117 阅读16分钟

相关文章

Redis 的命令详解 - Key 篇
Redis 的命令详解 - String 篇
Redis 的命令详解 - Hash 篇
Redis 的命令详解 - List 篇
Redis 的命令详解 - SET 篇

欢迎纠错(不管是错字还是内容写的有问题)!!!

Sorted Set 命令详解

跟 SET 相关的命令一共有 25 种,这里只介绍常用的,其他请参考官网

ZADD : 添加成员

起始版本 : 1.2.0
时间复杂度 : O(log(N)),其中N是有序集合中的元素数。

向有序集合(sorted set)中,添加 分数/成员(score/member)对,可以同时指定多个分数/成员(score/member)对。

分数值是一个带符号带双精度浮点型数字字符串。

  • 如果指定的成员已经在有序集合中,则会更新改成员的分数(scrore)并更新到正确的排序位置。
  • 如果key不存在,将会创建一个新的有序集合(sorted set)并将分数/成员(score/member)对添加到有序集合。

历史

redis 版本 >= 2.4 时,ZADD 命令接受多个成员。 在Redis 2.4以前,ZADD 命令只能添加或者更新一个成员。

语法

ZADD key [NX|XX] [CH] [INCR] score1 member1 [score2 member2 ...]

score 是分数,放在前面 member 是成员

ZADD 参数

redis 版本 >= Redis 3.0.2时, ZADD支持以下参数

  • XX : 只更新存在的成员,不添加新成员。
  • NX : 不更新存在的成员。只添加新成员。
  • INCR : 当指定这个参数时,成员的操作就等同ZINCRBY命令,对成员的分数进行递增操作,在此模式下只能指定一对分数/成员。
  • CH : 这个参数有点意思,它的作用是改变返回值!!!
    • 没有指定该参数时(默认情况下),返回的是新添加成员的总数,发生更新的成员不进行计数。
    • 指定该参数后,返回的是发生变化的成员总数,即新添加的成员 + 发生更新的成员。(注意,如果一个成员已存在,并且分数也相同,则不会发生更新)

返回值

  • 如果key存在,但是类型不是有序集合,将会返回一个错误应答。
  • 如果指定了,INCR 参数,返回运算后的新分数
  • 如果指定了,CH 参数, 返回的是发生变化的成员总数
  • 同时指定 INCRCH 参数,只要 INCR 生效,返回运算后的新分数
  • 即没有指定 INCR 参数,又没有指定 CH 参数,返回新添加的成员总数

分数可以精确的表示的整数的范围

Redis 有序集合的分数使用双精度64位浮点数。我们支持所有的架构,这表示为一个IEEE 754 floating point number,它能包括的整数范围是-(2^53) 到 +(2^53)。或者说是-9007199254740992 到 9007199254740992。更大的整数在内部用指数形式表示,所以,如果为分数设置一个非常大的整数,你得到的是一个近似的十进制数。

分数和排序

Sorted Set 按照分数递增的方式进行排序。且不允许存在重复的成员。

分数可以通过ZADD命令进行更新,也可以通过ZINCRBY命令来修改之前的值,分数变化后,对应的成员的排序位置也会随之改变。

获取一个成员当前的分数可以使用ZSCORE命令,也可以用它来验证成员是否存在。

相同分数的成员

有序集合里面的成员是不能重复的,但是不同成员间有可能有相同的分数。当多个成员有相同的分数时,将进行字典排序(ordered lexicographically)。

字典顺序排序用的是二进制,它比较的是字符串的字节数组。

如果用户将所有元素设置相同分数(例如0),有序集合里面的所有元素将按照字典顺序进行排序,范围查询元素可以使用ZRANGEBYLEX命令

ZSCORE : 获取成员的分数

起始版本 : 1.2.0
时间复杂度 : O(1)

语法

ZSCORE key member

返回值

成员的分数,成员不存在返回nil

ZREM : 删除成员

起始版本 : 1.2.0
时间复杂度 : O(M*log(N)),其中N是有序集合中的元素数,M是要删除的元素数。

删除指定的成员key,不存在的成员将被忽略。

语法

ZREM key member [member ...]

返回值

删除的成员数,不包括不存在的成员。

历史

reids 版本 >= 2.4时,接受多个 member 参数

ZREMRANGEBYSCORE : 删除给定分数间的所有成员

起始版本 : 1.2.0
时间复杂度 : O(M + log(N)),其中N是有序集合中的元素数,M是要删除的元素数。

删除分数在 min 和之间 max 之间的所有成员,包括min也包括max

语法

ZREMRANGEBYSCORE key min max

返回值

删除的成员

ZREMRANGEBYRANK : 删除指定下标间的所有成员

起始版本 : 2.0.0
时间复杂度 : O(M + log(N)),其中N是有序集合中的元素数,M是要删除的元素数。

删除开始下标结束下标之间的所有成员,下标从0开始,支持负下标,-1表示最右端成员,包括开始下标也包括结束下标

语法

ZREMRANGEBYSCORE key start stop

返回值

删除的成员

ZINCRBY : 增减成员的分数

起始版本 : 1.2.0
时间复杂度 : O(log(N)),其中N是有序集合中的元素数。

为有序集合中指定成员的分数加上一个带符号的双精度浮点数。

  • 如果 key 不存在,先创建该有序集合
  • 如果指定的成员不存在,先创建该成员,并初始化分数为0

score值必须是字符串表示的整数值或双精度浮点数,并且能接受double精度的浮点数。也有可能给一个负数来减少score的值。

语法

ZINCRBY key 带符号的双精度浮点数 member

返回值

  • 相加后的分数
  • 当key对应的value不是 Sorted Set 类型时,返回一个错误。

ZCARD : 获取集合中成员的个数

起始版本 : 1.2.0
时间复杂度 : O(1)

语法

ZCARD key

返回值

集合中成员的个数,如果key不存在,返回0

ZCOUNT : 获取集合在某个分数范围内的成员个数

起始版本 : 2.0.0
时间复杂度 : O(log(N)),其中N是有序集合中的元素数。

返回有序集合中,分数介于 minmax 之间的成员数量,包括min也包括max。

语法

ZCOUNT key min max

返回值

分数介于 minmax 之间的成员数量,如果key不存在,返回0

ZLEXCOUNT : 获取集合在某两个成员之间的成员个数

起始版本 : 2.8.9
时间复杂度 : O(log(N)),其中N是有序集合中的元素数。

返回有序集合中,介于 minmax 之间的成员数量。这里的 minmax 指的不是分数,而是成员。min 是分数小点的成员,max 是分数大点的成员,如果min成员的分数比max成员的分数还大,返回值为0

由于 Sorted Set 是有序集合(按分数从小到大排序),所以可以通过成员来搜索

语法

ZLEXCOUNT key min max

返回值

介于 minmax 之间的成员数量,包括min也包括max,如果key不存在,返回0

与 ZCOUNT的区别

ZLEXCOUNTZCOUNT 语法、作用、返回值都相同,区别在于

  • ZCOUNT 使用分数来圈定范围
  • ZLEXCOUNT 使用成员来圈定范围(利用了 Sorted Set 是有序集合的性质)

ZPOPMAX : 删除分数最大成员(右端弹出)

起始版本 : 5.0.0
时间复杂度 : O(log(N) * M),其中N是排序集中元素的数量,M是弹出元素的数量。

删除并返回有序集合中 count 个分数最高的成员

  • 如果 count 未指定,则默认值为1。
  • 如果 count >= 有序集合中成员的数量,删除并返回(弹出)所有成员

当 count > 1时,分数最高的将是第一个,其次是分数较低的元素。如果分数最高的有多个,按排列循序,从右到左,删除并返回(弹出)。

官方的解释繁琐且不精确,这里说一下我的解释。由于 Sorted Set 是按照分数进行从小到大排序的,分数相同的按照成员的字节数组排序。所以 ZPOPMAX 的作用相当于右端弹出

语法

ZPOPMAX key [count]

count 表示要弹出的个数

返回值

按照弹出循序的成员/分数对列表

ZPOPMIN : 删除分数最小成员(左端弹出)

起始版本 : 5.0.0
时间复杂度 : O(log(N) * M),其中N是排序集中元素的数量,M是弹出元素的数量。

左端弹出指定个数的成员/分数对

  • 如果 count 未指定,则默认值为1
  • 如果 count >= 有序集合中成员的数量,删除并返回(弹出)所有成员

语法

ZPOPMIN key [count]

count 表示要弹出的个数

返回值

按照弹出循序的成员/分数对列表

BZPOPMAX : (阻塞式)删除分数最大成员

起始版本 : 5.0.0
时间复杂度 : O(log(N)),其中N为有序集合中元素的数量

BZPOPMAXZPOPMAX 命令的阻塞版,当有序集合中没有成员时,会阻塞,指定有新成员添加进来或超时。

除此之外,BZPOPMAX 还可以指定多个key,当指定多个key时,按照参数中key的顺序,弹出第一个非空集合中分数最大的成员

语法

BZPOPMAX key1 [key2 ...] timeout

timeout 为超时时间,单位秒。设置为 0 表示无限超时

返回值

key名称、成员名称和分数,超时则返回 nil

BZPOPMIN : (阻塞式)删除分数最小成员

起始版本 : 5.0.0
时间复杂度 : O(log(N)),其中N为有序集合中元素的数量

BZPOPMINZPOPMIN 命令的阻塞版,当有序集合中没有成员时,会阻塞,指定有新成员添加进来或超时。

除此之外,BZPOPMIN 还可以指定多个key,当指定多个key时,按照参数中key的顺序,弹出第一个非空集合中分数最小的成员

语法

BZPOPMIN key1 [key2 ...] timeout

timeout 为超时时间,单位秒。设置为 0 表示无限超时

返回值

key名称、成员名称和分数,超时则返回 nil

ZUNIONSTORE : 计算多个集合的并集,并保存

起始版本 : 2.0.0
时间复杂度 : O(N) + O(M log(M)),其中 N 是所有集合的成员数量之和,M 是结果集中元素的数量。

计算指定个数的给定有序集合的并集,并将结果存储在 destination 中。

必须提供 numkeys 参数,并且 numkeys 在 key 及其他可选参数之前

指定 WEIGHTS 参数,可以为每个有序集合指定一个权重。这意味着,在将每个有序集合中的成员分数传递给聚合函数之前,都要乘以该权重。如果 WEIGHTS 未指定,则权重默认为1。

指定 AGGREGATE 参数,可以指定如何合并并集的结果。默认使用 SUM 函数。当此选项设置为MIN或时MAX,结果集将选择最小或最大分数的成员。

语法

ZUNIONSTORE destination numkeys key1 [key2 ...] [WEIGHTS weight1 [weight2 ...]] [AGGREGATE SUM | MIN | MAX]

  • destination : 目标集合,存放运算后的结果集。如果目标集合存在则覆盖。
  • numkeys : 参与运算的集合数量(key的数量)
  • WEIGHTS : 为每个集合指定权重,不指定时所有集合的权重默认为1。redis会将每个集合中的成员的分数 * 对应集合的权重
  • AGGREGATE : 汇总算法,默认使用 SUM
    • SUM : 将同一成员的分数相加
    • MIN : 取同一成员中分数最小的
    • MAX : 取同一成员中分数最大的

返回值

结果集中元素的个数

ZINTERSTORE : 计算多个集合的交集,并保存

起始版本 : 2.0.0
时间复杂度 : O(N) + O(M log(M)),其中 N 是所有集合的成员数量之和,M 是结果集中元素的数量。

计算指定个数的给定有序集合的交集,并将结果存储在 destination 中。

语法

ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM | MIN | MAX]

  • destination : 目标集合,存放运算后的结果集。如果目标集合存在则覆盖。
  • numkeys : 参与运算的集合数量(key的数量)
  • WEIGHTS : 为每个集合指定权重,不指定时所有集合的权重默认为1。redis会将每个集合中的成员的分数 * 对应集合的权重
  • AGGREGATE : 汇总算法,默认使用 SUM
    • SUM : 将同一成员的分数相加
    • MIN : 取同一成员中分数最小的
    • MAX : 取同一成员中分数最大的

返回值

结果集中元素的个数

ZRANK : 按分数从小到大获取成员在有序集合中的排名

起始版本 : 2.0.0
时间复杂度 : O(log(N))

按分数从小到大获取成员在有序集合中的排名,排名从0开始(也就是分数最小的排名为0,分数第二小的,排名为1...)

语法

ZRANK key member

返回值

成员对应的排名,如果key或成员不存在,返回nil

例子

redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
redis> ZRANK myzset "three"
(integer) 2
redis> ZRANK myzset "four"
(nil)
redis> 

ZREVRANK : 按分数从大到小获取成员在有序集合中的排名

起始版本 : 2.0.0
时间复杂度 : O(log(N))

按分数从大到小获取成员在有序集合中的排名,排名从0开始(也就是分数最大的排名为0,分数第二大的,排名为1...)

语法

ZREVRANK key member

返回值

成员对应的排名,如果key或成员不存在,返回nil

ZRANGE : 范围获取成员并按分数从小到大返回

起始版本 : 1.2.0
时间复杂度 : O(log(N) + M),N为有序集合中的元素数,M为返回的元素数。

返回开始下标和结束下标内的成员,并按照分数从小到大排序返回。

下标从0开始,支持负下标,-1表示最后一个成员,包括开始下标,也包括结束下标

由于 Sorted Set 是按分数从小到大排序,分数相同按成员字节数组排序,所以下标0表示最左边的成员,下表 -1 表示最右边的成员

下标超出范围不会产生错误。如果开始下标 > 集合最大下标或开始下标 > 结束下标,则结果为一个空列表。

如果结束下标 > 集合最大下标,则将结束下标视为集合的最大下标

语法

ZRANGE key start stop [WITHSCORES]

  • start : 开始下标
  • stop : 结束下标
  • WITHSCORES :指定此参数时,除了会返回成员外,还会返回成员对应的分数

返回值

指定范围内的成员列表,如果指定了 WITHSCORES 参数,还会包含成员对应的分数。

列表顺序按分数从小到大排序,分数相同按成员字节数组排序

ZREVRANGE : 获取指定下标内的成员并按分数从大到小返回

起始版本 : 1.2.0
时间复杂度 : O(log(N) + M),N为有序集合中的元素数,M为返回的元素数。

返回开始下标和结束下标内的成员,并按照分数从大到小排序返回。

下标从0开始,支持负下标,-1表示最后一个成员,包括开始下标,也包括结束下标

由于 Sorted Set 是按分数从小到大排序,分数相同按成员字节数组排序,所以下标0表示最左边的成员,下表 -1 表示最右边的成员

下标超出范围不会产生错误。如果开始下标 > 集合最大下标或开始下标 > 结束下标,则结果为一个空列表。

如果结束下标 > 集合最大下标,则将结束下标视为集合的最大下标

ZREVRANGE 命令与 ZRANGE 命令唯一的不同就是返回列表的顺序

语法

ZREVRANGE key start stop [WITHSCORES]

  • start : 开始下标
  • stop : 结束下标
  • WITHSCORES :指定此参数时,除了会返回成员外,还会返回成员对应的分数

返回值

指定范围内的成员列表,如果指定了 WITHSCORES 参数,还会包含成员对应的分数。

列表顺序按分数从大到小排序,分数相同按成员字节数组排序

ZRANGEBYSCORE : 获取分数范围内的成员并按从小到大返回

起始版本 : 1.0.5
时间复杂度 : O(log(N) + M),N为有序集合中的元素数,M为返回的元素数。如果M为常数(例如,始终要求使用LIMIT=10),则可以将其视为O(log(N))

返回分数在 min 和 max 之间的成员,包括min 也包括 max

语法

ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]

  • min : 小分数
  • max : 大分数
  • WITHSCORES : 设置该参数后,除了返回成员外,还会返回成员的对应分数,该参数在 Redis 2.0 开始可用
  • LIMIT offset count : 分页返回,offset 是结果集中的要返回成员的开始下标,count 是返回的条数,负数表示返回所有

返回值

成员列表,设置 WITHSCORES 参数后,还会返回成员的对应分数

列表顺序按分数从小到大排序,分数相同按成员字节数组排序

ZREVRANGEBYSCORE : 获取分数范围内的成员并按大到小返回

起始版本 : 2.2.0
时间复杂度 : O(log(N) + M),N为有序集合中的元素数,M为返回的元素数。如果M为常数(例如,始终要求使用LIMIT=10),则可以将其视为O(log(N))

返回分数在 min 和 max 之间的成员,包括min 也包括 max

此命令与 ZRANGEBYSCORE 命令的唯一区别在于,返回结果的排序

  • ZRANGEBYSCORE 按分数从小到大排序,分数相同按成员字节数组排序
  • 该命令按分数从大到小排序,分数相同按成员字节数组排序

语法

ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]

  • max : 大分数
  • min : 小分数
  • WITHSCORES : 设置该参数后,除了返回成员外,还会返回成员的对应分数
  • LIMIT offset count : 分页返回,offset 是结果集中的要返回成员的开始下标,count 是返回的条数,负数表示返回所有

返回值

成员列表,设置 WITHSCORES 参数后,还会返回成员的对应分数

列表顺序按分数从大到小排序,分数相同按成员字节数组排序