Redis 的命令详解 - Sorted 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 参数后,还会返回成员的对应分数

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

 

全部评论

相关推荐

最近又搬回宿舍了,在工位坐不住,写一写秋招起伏不断的心态变化,也算对自己心态的一些思考表演式学习从开始为实习准备的时候就特别焦虑,楼主一开始选择的是cpp后端,但是24届这个方向已经炸了,同时自己又因为本科非92且非科班,所以感到机会更加迷茫。在某天晚上用java写出hello world并失眠一整晚后选择老本行干嵌入式。理想是美好的,现实情况是每天忙但又没有实质性进展,总是在配环境,调工具,顺带还要推科研。而这时候才发现自己一直在表演式学习,徘徊在设想如何展开工作的循环里,导致没有实质性进展。现在看来当时如果把精力专注在动手写而不是两只手端着看教程,基本功或许不会那么差。实习的焦虑5月,楼主...
耶比:哲学上有一个问题,玛丽的房间:玛丽知道眼睛识别色彩的原理知道各种颜色,但是她生活在黑白的房间里,直到有一天玛丽的房门打开了她亲眼看到了颜色,才知道什么是色彩。我现在最大可能的减少对非工作事情的思考,如果有一件事困扰了我, 能解决的我就直接做(去哪里或者和谁吵架等等……),解决不了的我就不想了,每一天都是最年轻的一天,珍惜今天吧
投递比亚迪等公司10个岗位 > 秋招被确诊为…… 牛客创作赏金赛
点赞 评论 收藏
分享
无情咸鱼王的秋招日记之薛定谔的Offer:好拒信,偷了,希望有机会用到
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
11-24 20:55
阿里国际 Java工程师 2.7k*16.0
程序员猪皮:没有超过3k的,不太好选。春招再看看
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务