redis:有序集合zset

介绍

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

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

命令

命令描述返回值
zaddzadd k-name score member[score member…] --用于将一个或多个成员元素及其分数值加入到有序集当中被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员
ZremZREM k-name member [member …]–用于移除有序集中的一个或多个成员,不存在的成员将被忽略被成功移除的成员的数量,不包括被忽略的成员
ZcardZCARD k-name --返回有序集合包含的成员数量
ZincrbyZINCRBY k-name increment member–将member成员的分值加1
ZCOUNTZcount k-name min max–返回分值介于[min, max]之间的成员数量
ZRANKZRANK k-name member–返回成员member在有序集合中的排名
ZREVRANKZREVRANK k-name member–返回成员member在有序集合中的排名成员按照分值从大到小排列
ZRANGEZRANGE k-name start stop [WITHSCORES]–返回有序集合中排名介于[start, stop]之间的成员[和分值]
ZREVRANGEZREVRANGE k-name start stop [WITHSCORES]–返回有序集合中排名介于[start, stop]之间的成员[和分值]成员按照分值从大到小排列
ZSCOREZSCORE k-name member–返回成员memeber的分值
ZRANGEBYSCOREZRANGEBYSCORE key min max [WITHSCORES] [LIMIT OFFSET count]返回有序集合中,分值介于[min,max]的成员
ZREVRANGEBYSCOREZREVRANGEBYSCORE key min max [WITHSCORES] [LIMIT OFFSET count]返回有序集合中,分值介于[min,max]的成员
zrevrangebyrankZREMRANGEBYRANK key start stop

集合内

zadd:添加成员

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

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

语法
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 为成功添加的新成员的数量。

返回值
  • 被成功添加的新成员的数量,不包括那些被更新的、已经存在的成员。
实例
# 添加单个元素

redis> ZADD page_rank 10 google.com
(integer) 1


# 添加多个元素

redis> ZADD page_rank 9 baidu.com 8 bing.com
(integer) 2

redis> ZRANGE page_rank 0 -1 WITHSCORES
1) "bing.com"
2) "8"
3) "baidu.com"
4) "9"
5) "google.com"
6) "10"


# 添加已存在元素,且 score 值不变

redis> ZADD page_rank 10 google.com
(integer) 0

redis> ZRANGE page_rank 0 -1 WITHSCORES  # 没有改变
1) "bing.com"
2) "8"
3) "baidu.com"
4) "9"
5) "google.com"
6) "10"


# 添加已存在元素,但是改变 score 值

redis> ZADD page_rank 6 bing.com
(integer) 0

redis> ZRANGE page_rank 0 -1 WITHSCORES  # bing.com 元素的 score 值被改变
1) "bing.com"
2) "6"
3) "baidu.com"
4) "9"
5) "google.com"
6) "10"

zcard:计算成员个数

作用

返回有序集 key 的基数。

时间复杂度

O(1)

返回值
  • 当 key 存在且是有序集类型时,返回有序集的基数。
  • 当 key 不存在时,返回 0 。
实例
redis > ZADD salary 2000 tom    # 添加一个成员
(integer) 1

redis > ZCARD salary
(integer) 1

redis > ZADD salary 5000 jack   # 再添加一个成员
(integer) 1

redis > ZCARD salary
(integer) 2

redis > EXISTS non_exists_key   # 对不存在的 key 进行 ZCARD 操作
(integer) 0

redis > ZCARD non_exists_key
(integer) 0

zscore:返回成员的分数

作用
  • 返回有序集中,成员的分数值。
语法
redis 127.0.0.1:6379> ZSCORE key member
返回值
  • 成员的分数值,以字符串形式表示。
  • 如果成员元素不是有序集 key 的成员,或 key 不存在,返回 nil 。
实例
redis 127.0.0.1:6379> ZRANGE salary 0 -1 WITHSCORES    # 测试数据
1) "tom"
2) "2000"
3) "peter"
4) "3500"
5) "jack"
6) "5000"

redis 127.0.0.1:6379> ZSCORE salary peter              # 注意返回值是字符串
"3500"

ZRANK:返回指定成员的排名

作用

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

语法
redis 127.0.0.1:6379> ZRANK key member
返回值
  • 如果成员是有序集 key 的成员,返回 member 的排名。
  • 如果成员不是有序集 key 的成员,返回 nil 。
实例
redis 127.0.0.1:6379> ZRANGE salary 0 -1 WITHSCORES        # 显示所有成员及其 score 值
1) "peter"
2) "3500"
3) "tom"
4) "4000"
5) "jack"
6) "5000"

redis 127.0.0.1:6379> ZRANK salary tom                     # 显示 tom 的薪水排名,第二
(integer) 1

Zrevrank :返回指定成员的排名

作用
  • Redis Zrevrank 命令返回有序集中成员的排名。其中有序集成员按分数值递减(从大到小)排序。
  • 排名以 0 为底,也就是说, 分数值最大的成员排名为 0 。
  • 使用 ZRANK 命令可以获得成员按分数值递增(从小到大)排列的排名。
实例
redis 127.0.0.1:6379> ZRANGE salary 0 -1 WITHSCORES     # 测试数据
1) "jack"
2) "2000"
3) "peter"
4) "3500"
5) "tom"
6) "5000"

redis 127.0.0.1:6379> ZREVRANK salary peter     # peter 的工资排第二
(integer) 1

redis 127.0.0.1:6379> ZREVRANK salary tom       # tom 的工资最高
(integer) 0

zrem:移除成员

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

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

语法
redis 127.0.0.1:6379> ZREM key member [member ...]
返回值

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

实例
# 测试数据

redis 127.0.0.1:6379> ZRANGE page_rank 0 -1 WITHSCORES
1) "bing.com"
2) "8"
3) "baidu.com"
4) "9"
5) "google.com"
6) "10"


# 移除单个元素

redis 127.0.0.1:6379> ZREM page_rank google.com
(integer) 1

redis 127.0.0.1:6379> ZRANGE page_rank 0 -1 WITHSCORES
1) "bing.com"
2) "8"
3) "baidu.com"
4) "9"


# 移除多个元素

redis 127.0.0.1:6379> ZREM page_rank baidu.com bing.com
(integer) 2

redis 127.0.0.1:6379> ZRANGE page_rank 0 -1 WITHSCORES
(empty list or set)


# 移除不存在元素

redis 127.0.0.1:6379> ZREM page_rank non-exists-element
(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 值,以字符串形式表示。
实例
redis> ZSCORE salary tom
"2000"

redis> ZINCRBY salary 2000 tom   # tom 加薪啦!
"4000"

zrange/zrevrange

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

    • 其中成员的位置按分数值递增(从小到大)来排序。
    • 具有相同分数值的成员按字典序(lexicographical order )来排列。
  • 如果你需要成员按值递减(从大到小)来排列,请使用 ZREVRANGE 命令。

  • 下标参数 start 和 stop 都以 0 为底,也就是说,以 0 表示有序集第一个成员,以 1 表示有序集第二个成员,以此类推。

  • 你也可以使用负数下标,以 -1 表示最后一个成员, -2 表示倒数第二个成员,以此类推。

语法
redis 127.0.0.1:6379> ZRANGE key start stop [WITHSCORES]
返回值

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

实例
redis 127.0.0.1:6379> ZRANGE salary 0 -1 WITHSCORES             # 显示整个有序集成员
1) "jack"
2) "3500"
3) "tom"
4) "5000"
5) "boss"
6) "10086"

redis 127.0.0.1:6379> ZRANGE salary 1 2 WITHSCORES              # 显示有序集下标区间 1 至 2 的成员
1) "tom"
2) "5000"
3) "boss"
4) "10086"

redis 127.0.0.1:6379> ZRANGE salary 0 200000 WITHSCORES         # 测试 end 下标超出最大下标时的情况
1) "jack"
2) "3500"
3) "tom"
4) "5000"
5) "boss"
6) "10086"

redis > ZRANGE salary 200000 3000000 WITHSCORES                  # 测试当给定区间不存在于有序集时的情况
(empty list or set)
redis 127.0.0.1:6379> ZRANGE salary 0 -1 WITHSCORES        # 递增排列
1) "peter"
2) "3500"
3) "tom"
4) "4000"
5) "jack"
6) "5000"

redis 127.0.0.1:6379> ZREVRANGE salary 0 -1 WITHSCORES     # 递减排列
1) "jack"
2) "5000"
3) "tom"
4) "4000"
5) "peter"
6) "3500"

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

作用
  • Redis Zrange 返回有序集中,指定区间内的成员。
    • 其中成员的位置按分数值递增(从小到大)来排序。
    • 具有相同分数值的成员按字典序(lexicographical order )来排列。
  • 如果你需要成员按值递减(从大到小)来排列,请使用 ZREVRANGE 命令。
  • 下标参数 start 和 stop 都以 0 为底,也就是说,以 0 表示有序集第一个成员,以 1 表示有序集第二个成员,以此类推。
  • 你也可以使用负数下标,以 -1 表示最后一个成员, -2 表示倒数第二个成员,以此类推。
语法
redis 127.0.0.1:6379> ZRANGE key start stop [WITHSCORES]
返回值

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

实例
redis 127.0.0.1:6379> ZRANGE salary 0 -1 WITHSCORES             # 显示整个有序集成员
1) "jack"
2) "3500"
3) "tom"
4) "5000"
5) "boss"
6) "10086"

redis 127.0.0.1:6379> ZRANGE salary 1 2 WITHSCORES              # 显示有序集下标区间 1 至 2 的成员
1) "tom"
2) "5000"
3) "boss"
4) "10086"

redis 127.0.0.1:6379> ZRANGE salary 0 200000 WITHSCORES         # 测试 end 下标超出最大下标时的情况
1) "jack"
2) "3500"
3) "tom"
4) "5000"
5) "boss"
6) "10086"

redis > ZRANGE salary 200000 3000000 WITHSCORES                  # 测试当给定区间不存在于有序集时的情况
(empty list or set)

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

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

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

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

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

作用

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

语法
redis 127.0.0.1:6379> ZCOUNT key min max
返回值

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

实例
redis 127.0.0.1:6379> ZADD myzset 1 "hello"
(integer) 1
redis 127.0.0.1:6379> ZADD myzset 1 "foo"
(integer) 1
redis 127.0.0.1:6379> ZADD myzset 2 "world" 3 "bar"
(integer) 2
redis 127.0.0.1:6379> ZCOUNT myzset 1 3
(integer) 4

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

作用

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

语法
redis 127.0.0.1:6379> ZREMRANGEBYSCORE key min max
返回值

被移除成员的数量。

实例
redis 127.0.0.1:6379> ZRANGE salary 0 -1 WITHSCORES          # 显示有序集内所有成员及其 score 值
1) "tom"
2) "2000"
3) "peter"
4) "3500"
5) "jack"
6) "5000"

redis 127.0.0.1:6379> ZREMRANGEBYSCORE salary 1500 3500      # 移除所有薪水在 1500 到 3500 内的员工
(integer) 2

redis> ZRANGE salary 0 -1 WITHSCORES          # 剩下的有序集成员
1) "jack"
2) "5000"

集合间

zinterstore:交集

作用
  • Redis Zinterstore 命令计算给定的一个或多个有序集的交集,其中给定 key 的数量必须以 numkeys 参数指定,并将该交集(结果集)储存到 destination 。
  • 默认情况下,结果集中某个成员的分数值是所有给定集下该成员分数值之和。
语法
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.
实例
# 有序集 mid_test
redis 127.0.0.1:6379> ZADD mid_test 70 "Li Lei"
(integer) 1
redis 127.0.0.1:6379> ZADD mid_test 70 "Han Meimei"
(integer) 1
redis 127.0.0.1:6379> ZADD mid_test 99.5 "Tom"
(integer) 1

# 另一个有序集 fin_test
redis 127.0.0.1:6379> ZADD fin_test 88 "Li Lei"
(integer) 1
redis 127.0.0.1:6379> ZADD fin_test 75 "Han Meimei"
(integer) 1
redis 127.0.0.1:6379> ZADD fin_test 99.5 "Tom"
(integer) 1

# 交集
redis 127.0.0.1:6379> ZINTERSTORE sum_point 2 mid_test fin_test
(integer) 3

# 显示有序集内所有成员及其分数值
redis 127.0.0.1:6379> ZRANGE sum_point 0 -1 WITHSCORES     
1) "Han Meimei"
2) "145"
3) "Li Lei"
4) "158"
5) "Tom"
6) "199"

zunionstore:并集

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

内部编码

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

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

使用场景

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

  1. 添加用户赞数

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

zadd user:ranking:2016_03_15 mike 3

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

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

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

zrem user:ranking:2016_03_15 mike
  1. 展示获取赞数最多的十个用户
zrevrangebyrank user:ranking:2016_03_15 0 9
  1. 展示用户信息以及用户分数

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

hgetall user:info:tom zscore user:ranking:2016_03_15 mike zrank user:ranking:2016_03_15 mike
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值