redis:有序集合zset

怼烎@ 2022-09-15 06:13 404阅读 0赞

介绍

有序集合保留了集合不能有重复成员的特性,但不同的是,有序集合中的元素可以排序。但是它和列表使用索引下标作为排序依据不同的是,它给每个元素设置一个分数(score)作为排序的依据

在这里插入图片描述
在这里插入图片描述

命令












































































命令 描述 返回值
zadd zadd k-name score member[score member…] —用于将一个或多个成员元素及其分数值加入到有序集当中 被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员
Zrem ZREM k-name member [member …]–用于移除有序集中的一个或多个成员,不存在的成员将被忽略 被成功移除的成员的数量,不包括被忽略的成员
Zcard ZCARD k-name —返回有序集合包含的成员数量
Zincrby ZINCRBY k-name increment member–将member成员的分值加1
ZCOUNT Zcount k-name min max–返回分值介于[min, max]之间的成员数量
ZRANK ZRANK k-name member–返回成员member在有序集合中的排名
ZREVRANK ZREVRANK k-name member–返回成员member在有序集合中的排名 成员按照分值从大到小排列
ZRANGE ZRANGE k-name start stop [WITHSCORES]–返回有序集合中排名介于[start, stop]之间的成员[和分值]
ZREVRANGE ZREVRANGE k-name start stop [WITHSCORES]–返回有序集合中排名介于[start, stop]之间的成员[和分值] 成员按照分值从大到小排列
ZSCORE ZSCORE k-name member–返回成员memeber的分值
ZRANGEBYSCORE ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT OFFSET count] 返回有序集合中,分值介于[min,max]的成员
ZREVRANGEBYSCORE ZREVRANGEBYSCORE key min max [WITHSCORES] [LIMIT OFFSET count] 返回有序集合中,分值介于[min,max]的成员
zrevrangebyrank ZREMRANGEBYRANK key start stop

集合内

zadd:添加成员

作用

  • 用于将一个或多个成员元素及其分数值加入到有序集当中。
  • 如果某个成员已经是有序集的成员,那么更新这个成员的分数值,并通过重新插入这个成员元素,来保证该成员在正确的位置上。
  • 分数值可以是整数值或双精度浮点数。
  • 如果有序集合 key 不存在,则创建一个空的有序集并执行 ZADD 操作
  • 当 key 存在但不是有序集类型时,返回一个错误。

注意: 在 Redis 2.4 版本以前, ZADD 每次只能添加一个元素。

语法

  1. redis 127.0.0.1:6379> ZADD key score member [[score member] [score member] ...]

redis3.2为zadd添加了nx、xx、ch、incr四个选项

  • nx:member必须不存在,才能设置成功,用于添加
  • xx:member必须存在,才能设置成功,用于更新
  • ch:返回此次操作后,有序集合元素和分数发生变化的个数
  • incr:对socre做增加,相当于zincrby

时间复杂度

O(M*log(N)), N 是有序集的基数, M 为成功添加的新成员的数量。

返回值

  • 被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员。

实例

  1. # 添加单个元素
  2. redis> ZADD page_rank 10 google.com
  3. (integer) 1
  4. # 添加多个元素
  5. redis> ZADD page_rank 9 baidu.com 8 bing.com
  6. (integer) 2
  7. redis> ZRANGE page_rank 0 -1 WITHSCORES
  8. 1) "bing.com"
  9. 2) "8"
  10. 3) "baidu.com"
  11. 4) "9"
  12. 5) "google.com"
  13. 6) "10"
  14. # 添加已存在元素,且 score 值不变
  15. redis> ZADD page_rank 10 google.com
  16. (integer) 0
  17. redis> ZRANGE page_rank 0 -1 WITHSCORES # 没有改变
  18. 1) "bing.com"
  19. 2) "8"
  20. 3) "baidu.com"
  21. 4) "9"
  22. 5) "google.com"
  23. 6) "10"
  24. # 添加已存在元素,但是改变 score 值
  25. redis> ZADD page_rank 6 bing.com
  26. (integer) 0
  27. redis> ZRANGE page_rank 0 -1 WITHSCORES # bing.com 元素的 score 值被改变
  28. 1) "bing.com"
  29. 2) "6"
  30. 3) "baidu.com"
  31. 4) "9"
  32. 5) "google.com"
  33. 6) "10"

zcard:计算成员个数

作用

返回有序集 key 的基数。

时间复杂度

O(1)

返回值

  • 当 key 存在且是有序集类型时,返回有序集的基数。
  • 当 key 不存在时,返回 0 。

实例

  1. redis > ZADD salary 2000 tom # 添加一个成员
  2. (integer) 1
  3. redis > ZCARD salary
  4. (integer) 1
  5. redis > ZADD salary 5000 jack # 再添加一个成员
  6. (integer) 1
  7. redis > ZCARD salary
  8. (integer) 2
  9. redis > EXISTS non_exists_key # 对不存在的 key 进行 ZCARD 操作
  10. (integer) 0
  11. redis > ZCARD non_exists_key
  12. (integer) 0

zscore:返回成员的分数

作用

  • 返回有序集中,成员的分数值。

语法

  1. redis 127.0.0.1:6379> ZSCORE key member

返回值

  • 成员的分数值,以字符串形式表示。
  • 如果成员元素不是有序集 key 的成员,或 key 不存在,返回 nil 。

实例

  1. redis 127.0.0.1:6379> ZRANGE salary 0 -1 WITHSCORES # 测试数据
  2. 1) "tom"
  3. 2) "2000"
  4. 3) "peter"
  5. 4) "3500"
  6. 5) "jack"
  7. 6) "5000"
  8. redis 127.0.0.1:6379> ZSCORE salary peter # 注意返回值是字符串
  9. "3500"

ZRANK:返回指定成员的排名

作用

Redis Zrank 返回有序集中指定成员的排名。其中有序集成员按分数值递增(从小到大)顺序排列。

语法

  1. redis 127.0.0.1:6379> ZRANK key member

返回值

  • 如果成员是有序集 key 的成员,返回 member 的排名。
  • 如果成员不是有序集 key 的成员,返回 nil 。

实例

  1. redis 127.0.0.1:6379> ZRANGE salary 0 -1 WITHSCORES # 显示所有成员及其 score 值
  2. 1) "peter"
  3. 2) "3500"
  4. 3) "tom"
  5. 4) "4000"
  6. 5) "jack"
  7. 6) "5000"
  8. redis 127.0.0.1:6379> ZRANK salary tom # 显示 tom 的薪水排名,第二
  9. (integer) 1

Zrevrank :返回指定成员的排名

作用

  • Redis Zrevrank 命令返回有序集中成员的排名。其中有序集成员按分数值递减(从大到小)排序。
  • 排名以 0 为底,也就是说, 分数值最大的成员排名为 0 。
  • 使用 ZRANK 命令可以获得成员按分数值递增(从小到大)排列的排名。

实例

  1. redis 127.0.0.1:6379> ZRANGE salary 0 -1 WITHSCORES # 测试数据
  2. 1) "jack"
  3. 2) "2000"
  4. 3) "peter"
  5. 4) "3500"
  6. 5) "tom"
  7. 6) "5000"
  8. redis 127.0.0.1:6379> ZREVRANK salary peter # peter 的工资排第二
  9. (integer) 1
  10. redis 127.0.0.1:6379> ZREVRANK salary tom # tom 的工资最高
  11. (integer) 0

zrem:移除成员

作用

  • Redis Zrem 命令用于移除有序集中的一个或多个成员,不存在的成员将被忽略。
  • 当 key 存在但不是有序集类型时,返回一个错误。

注意: 在 Redis 2.4 版本以前, ZREM 每次只能删除一个元素。

语法

  1. redis 127.0.0.1:6379> ZREM key member [member ...]

返回值

被成功移除的成员的数量,不包括被忽略的成员。

实例

  1. # 测试数据
  2. redis 127.0.0.1:6379> ZRANGE page_rank 0 -1 WITHSCORES
  3. 1) "bing.com"
  4. 2) "8"
  5. 3) "baidu.com"
  6. 4) "9"
  7. 5) "google.com"
  8. 6) "10"
  9. # 移除单个元素
  10. redis 127.0.0.1:6379> ZREM page_rank google.com
  11. (integer) 1
  12. redis 127.0.0.1:6379> ZRANGE page_rank 0 -1 WITHSCORES
  13. 1) "bing.com"
  14. 2) "8"
  15. 3) "baidu.com"
  16. 4) "9"
  17. # 移除多个元素
  18. redis 127.0.0.1:6379> ZREM page_rank baidu.com bing.com
  19. (integer) 2
  20. redis 127.0.0.1:6379> ZRANGE page_rank 0 -1 WITHSCORES
  21. (empty list or set)
  22. # 移除不存在元素
  23. redis 127.0.0.1:6379> ZREM page_rank non-exists-element
  24. (integer) 0

zincrby:增加成员的分数

作用

  • 为有序集 key 的成员 member 的 score 值加上增量 increment 。
  • 可以通过传递一个负数值 increment ,让 score 减去相应的值,比如 ZINCRBY key -5 member ,就是让 member 的 score 值减去 5 。
  • 当 key 不存在,或 member 不是 key 的成员时, ZINCRBY key increment member 等同于 ZADD key increment member 。
  • 当 key 不是有序集类型时,返回一个错误
  • score 值可以是整数值或双精度浮点数。

返回值

  • member 成员的新 score 值,以字符串形式表示。

实例

  1. redis> ZSCORE salary tom
  2. "2000"
  3. redis> ZINCRBY salary 2000 tom # tom 加薪啦!
  4. "4000"

zrange/zrevrange

作用

  • Redis Zrange 返回有序集中,指定区间内的成员。

    • 其中成员的位置按分数值递增(从小到大)来排序。
    • 具有相同分数值的成员按字典序(lexicographical order )来排列。
  • 如果你需要成员按值递减(从大到小)来排列,请使用 ZREVRANGE 命令。
  • 下标参数 start 和 stop 都以 0 为底,也就是说,以 0 表示有序集第一个成员,以 1 表示有序集第二个成员,以此类推。
  • 你也可以使用负数下标,以 -1 表示最后一个成员, -2 表示倒数第二个成员,以此类推。

语法

  1. redis 127.0.0.1:6379> ZRANGE key start stop [WITHSCORES]

返回值

指定区间内,带有分数值(可选)的有序集成员的列表。

实例

  1. redis 127.0.0.1:6379> ZRANGE salary 0 -1 WITHSCORES # 显示整个有序集成员
  2. 1) "jack"
  3. 2) "3500"
  4. 3) "tom"
  5. 4) "5000"
  6. 5) "boss"
  7. 6) "10086"
  8. redis 127.0.0.1:6379> ZRANGE salary 1 2 WITHSCORES # 显示有序集下标区间 1 至 2 的成员
  9. 1) "tom"
  10. 2) "5000"
  11. 3) "boss"
  12. 4) "10086"
  13. redis 127.0.0.1:6379> ZRANGE salary 0 200000 WITHSCORES # 测试 end 下标超出最大下标时的情况
  14. 1) "jack"
  15. 2) "3500"
  16. 3) "tom"
  17. 4) "5000"
  18. 5) "boss"
  19. 6) "10086"
  20. redis > ZRANGE salary 200000 3000000 WITHSCORES # 测试当给定区间不存在于有序集时的情况
  21. (empty list or set)
  22. redis 127.0.0.1:6379> ZRANGE salary 0 -1 WITHSCORES # 递增排列
  23. 1) "peter"
  24. 2) "3500"
  25. 3) "tom"
  26. 4) "4000"
  27. 5) "jack"
  28. 6) "5000"
  29. redis 127.0.0.1:6379> ZREVRANGE salary 0 -1 WITHSCORES # 递减排列
  30. 1) "jack"
  31. 2) "5000"
  32. 3) "tom"
  33. 4) "4000"
  34. 5) "peter"
  35. 6) "3500"

zrange/zrevrange:获取指定范围的元素

作用

  • Redis Zrange 返回有序集中,指定区间内的成员。

    • 其中成员的位置按分数值递增(从小到大)来排序。
    • 具有相同分数值的成员按字典序(lexicographical order )来排列。
  • 如果你需要成员按值递减(从大到小)来排列,请使用 ZREVRANGE 命令。
  • 下标参数 start 和 stop 都以 0 为底,也就是说,以 0 表示有序集第一个成员,以 1 表示有序集第二个成员,以此类推。
  • 你也可以使用负数下标,以 -1 表示最后一个成员, -2 表示倒数第二个成员,以此类推。

语法

  1. redis 127.0.0.1:6379> ZRANGE key start stop [WITHSCORES]

返回值

指定区间内,带有分数值(可选)的有序集成员的列表。

实例

  1. redis 127.0.0.1:6379> ZRANGE salary 0 -1 WITHSCORES # 显示整个有序集成员
  2. 1) "jack"
  3. 2) "3500"
  4. 3) "tom"
  5. 4) "5000"
  6. 5) "boss"
  7. 6) "10086"
  8. redis 127.0.0.1:6379> ZRANGE salary 1 2 WITHSCORES # 显示有序集下标区间 1 至 2 的成员
  9. 1) "tom"
  10. 2) "5000"
  11. 3) "boss"
  12. 4) "10086"
  13. redis 127.0.0.1:6379> ZRANGE salary 0 200000 WITHSCORES # 测试 end 下标超出最大下标时的情况
  14. 1) "jack"
  15. 2) "3500"
  16. 3) "tom"
  17. 4) "5000"
  18. 5) "boss"
  19. 6) "10086"
  20. redis > ZRANGE salary 200000 3000000 WITHSCORES # 测试当给定区间不存在于有序集时的情况
  21. (empty list or set)

返回分数在0到100的成员.

  1. 127.0.0.1:6379> zrangebyscore user:ranking 0 100
  2. 1) "codger"
  3. 2) "hank"
  4. 3) "ann"
  5. 4) "Rico"
  6. 5) "tom"

返回分数在0到无限大的成员.

  1. 127.0.0.1:6379> zrangebyscore user:ranking 0 +inf
  2. 1) "codger"
  3. 2) "hank"
  4. 3) "ann"
  5. 4) "Rico"
  6. 5) "tom"

zcount:分数值在 min 和 max 之间的成员的数量

作用

用于计算有序集合中指定分数区间的成员数量。

语法

  1. redis 127.0.0.1:6379> ZCOUNT key min max

返回值

分数值在 min 和 max 之间的成员的数量。

实例

  1. redis 127.0.0.1:6379> ZADD myzset 1 "hello"
  2. (integer) 1
  3. redis 127.0.0.1:6379> ZADD myzset 1 "foo"
  4. (integer) 1
  5. redis 127.0.0.1:6379> ZADD myzset 2 "world" 3 "bar"
  6. (integer) 2
  7. redis 127.0.0.1:6379> ZCOUNT myzset 1 3
  8. (integer) 4

zremrangebyscore:删除分数从min到max的成员

作用

Zremrangebyscore 命令用于移除有序集中,指定分数(score)区间内的所有成员。

语法

  1. redis 127.0.0.1:6379> ZREMRANGEBYSCORE key min max

返回值

被移除成员的数量。

实例

  1. redis 127.0.0.1:6379> ZRANGE salary 0 -1 WITHSCORES # 显示有序集内所有成员及其 score 值
  2. 1) "tom"
  3. 2) "2000"
  4. 3) "peter"
  5. 4) "3500"
  6. 5) "jack"
  7. 6) "5000"
  8. redis 127.0.0.1:6379> ZREMRANGEBYSCORE salary 1500 3500 # 移除所有薪水在 1500 到 3500 内的员工
  9. (integer) 2
  10. redis> ZRANGE salary 0 -1 WITHSCORES # 剩下的有序集成员
  11. 1) "jack"
  12. 2) "5000"

集合间

zinterstore:交集

作用

  • Redis Zinterstore 命令计算给定的一个或多个有序集的交集,其中给定 key 的数量必须以 numkeys 参数指定,并将该交集(结果集)储存到 destination 。
  • 默认情况下,结果集中某个成员的分数值是所有给定集下该成员分数值之和。

语法

  1. zinterstore storeKey keyNum key [key ...] [weights weight [weight...]] [aggregate sum|min|max]

参数说明:

  • storeKey:交集计算结果保存到这个键下.
  • keyNum:需要做交集的键的个数.
  • key[key …]:需要做交集的键.
  • weights weight [weight…]:每个键的权重,在做交集计算时,每个键中的每个member的分值会和这个权重相乘,每个键的权重默认为1.
  • aggregate sum|min|sum:计算成员交集后,分值可以按照sum(和)、min(最小值)、max(最大值)做汇总.默认值为sum.

实例

  1. # 有序集 mid_test
  2. redis 127.0.0.1:6379> ZADD mid_test 70 "Li Lei"
  3. (integer) 1
  4. redis 127.0.0.1:6379> ZADD mid_test 70 "Han Meimei"
  5. (integer) 1
  6. redis 127.0.0.1:6379> ZADD mid_test 99.5 "Tom"
  7. (integer) 1
  8. # 另一个有序集 fin_test
  9. redis 127.0.0.1:6379> ZADD fin_test 88 "Li Lei"
  10. (integer) 1
  11. redis 127.0.0.1:6379> ZADD fin_test 75 "Han Meimei"
  12. (integer) 1
  13. redis 127.0.0.1:6379> ZADD fin_test 99.5 "Tom"
  14. (integer) 1
  15. # 交集
  16. redis 127.0.0.1:6379> ZINTERSTORE sum_point 2 mid_test fin_test
  17. (integer) 3
  18. # 显示有序集内所有成员及其分数值
  19. redis 127.0.0.1:6379> ZRANGE sum_point 0 -1 WITHSCORES
  20. 1) "Han Meimei"
  21. 2) "145"
  22. 3) "Li Lei"
  23. 4) "158"
  24. 5) "Tom"
  25. 6) "199"

zunionstore:并集

该命令的所有参数和zinterstore是一致的,只不过做的是并集计算.

内部编码

有序集合类型的内部编码有两种:

  • ziplist(压缩列表):当有序集合的元素个数小于zset-max-ziplistentries配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value配置(默认64字节)时,Redis会用ziplist来作为有序集合的内部实现
  • skiplist(跳跃表):当ziplist条件不满足时,有序集合会使用skiplist作为内部实现

使用场景

有序集合比较典型的使用场景就是排行榜系统。例如视频网站需要对用户上传的视频做排行榜,榜单的维度可能是多个方面的:按照时间、按照播放数量、按照获得的赞数

  1. 添加用户赞数

例如用户mike上传了一个视频,并获得了3个赞,可以使用有序集合的 zadd和zincrby功能:

  1. zadd user:ranking:2016_03_15 mike 3

如果之后再获得一个赞,可以使用zincrby:

  1. zincrby user:ranking:2016_03_15 mike 1
  1. 取消用户赞数

由于各种原因(例如用户注销、用户作弊)需要将用户删除,此时需要将用户从榜单中删除掉,可以使用zrem。例如删除成员tom:

  1. zrem user:ranking:2016_03_15 mike
  1. 展示获取赞数最多的十个用户

    zrevrangebyrank user:ranking:2016_03_15 0 9

  2. 展示用户信息以及用户分数

此功能将用户名作为键后缀,将用户信息保存在哈希类型中,至于用户的分数和排名可以使用zscore和zrank两个功能:

  1. hgetall user:info:tom zscore user:ranking:2016_03_15 mike zrank user:ranking:2016_03_15 mike

发表评论

表情:
评论列表 (有 0 条评论,404人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Zset有序集合

    有序集合相对于字符串、列表、哈希、集合来说会有⼀些陌⽣。它保留了集合不能有重复成员的特点,但与集合不同的是,有序集合中的每个元素都有⼀个唯⼀的浮点类型的分数(score)...

    相关 redis有序集合zset

    介绍 有序集合保留了集合不能有重复成员的特性,但不同的是,有序集合中的元素可以排序。但是它和列表使用索引下标作为排序依据不同的是,它给每个元素设置一个分数(score)作