zset

概述

  • Redis有序集合zset与普通集合set非常相似,是一个没有重复元素的字符串集合。
  • 不同之处是有序集合的每个成员都关联了一个评分(score),这个评分(score)被用来按照从最低分到最高分的方式排序集合中的成员。集合的成员是唯一的,但是评分是可以重复的 。
  • 因为元素是有序的, 所以你也可以很快的根据评分(score)或者次序来获取一个范围的元素。
  • 访问有序集合的中间元素也是非常快的,因此你能够使用有序集合作为一个没有重复成员的智能列表。
  • 此外,有序集合中的元素是按顺序获取的(因此它们不是按请求排序的,顺序是用于表示有序集合的数据结构的特性)。它们根据以下规则排序:
    • 如果 A 和 B 是具有不同分数的两个元素, 如果 A.score 是 > B.score,则 A > B。
    • 如果 A 和 B 的分数完全相同,则 A > B 如果 A 字符串按字典顺序大于 B 字符串。A 和 B 字符串不能相等,因为排序集只有唯一元素。

常用命令

  • 将一个或多个 member 元素及其 score 值加入到有序集 key 当中。
zadd  key score1 value1 score2 value2...

如果指定添加的成员已经是有序集合里面的成员,则会更新改成员的分数(scrore)并更新到正确的排序位置。如果key不存在,将会创建一个新的有序集合(sorted set)并将分数/成员(score/member)对添加到有序集合,就像原来存在一个空的有序集合一样。如果key存在,但是类型不是有序集合,将会返回一个错误应答。

  • 返回有序集 key 中,下标在 之间的元素
zrange key start stop  
#带withscores,可以让分数一起和值返回到结果集。
zrange key start stop withscores
#查询全部元素
zrange key 0 -1
参数start和stop都是从0开始的索引。
可以是负数,表示从有序集合的末尾的偏移量,其中-1是有序集合的最后一个元素,依次类推。
start和stop都是全包含的区间。
超出范围的索引不会产生错误。 如果start参数的值大于有序集合中的最大索引,或者start > stop,将会返回一个空列表。 如果stop的值大于有序集合的末尾,Redis会将其视为有序集合的最后一个元素。
  • 返回有序集 key 中,所有 score 值介于 min 和 max 之间的成员。
zrangebyscore key min max [withscores]
#加上withscores,返回结果就加上score
#如果不希望包含min或max,可以在前面加左括号
zrangebyscore key (min (max
#分页
zrangebyscore key min max limit offset count

包括分数等于max或者min的元素。
元素被认为是从低分到高分排序的。
具有相同分数的元素按字典序排列。
最小值可以用-inf代替表示最小值 ;最大值可以用+inf代替表示最大值

  • 返回有序集 key 中,所有 score 值介于 max和 min 之间
zrevrangebyscore key max min [withscores] 
#分页
zrevrangebyscore key max min limit offset count

包括分数等于max或者min的元素。
元素被认为是从高分到低分排序的。
具有相同分数的元素按字典序倒序排列。
最小值可以用-inf代替表示最小值 ;最大值可以用+inf代替表示最大值

  • 为有序集合key指定元素的score加上增量
zincrby key increment member

如果key中不存在member,就在key中添加一个member,score是increment(就好像它之前的score是0.0)。如果key不存在,就创建一个只含有指定member成员的有序集合。
当key不是有序集类型时,返回一个错误。
score值必须是字符串表示的整数值或双精度浮点数,并且能接受double精度的浮点数。也有可能给一个负数来减少score的值。

  • 删除该集合下,指定值的元素
zrem key member1,member2......

返回的是从有序集合中删除的成员个数,不包括不存在的成员。
当key存在,但是其不是有序集合类型,就返回一个错误。

  • 返回有序集key中,score值在min和max之间(默认包括score值等于min或max)的成员。
zcount key min max
  • 返回key的有序集元素个数。
zcard key
  • 返回该值在集合中的排名,从0开始。
#从小到大
zrank key member
#从大到小
zrevrank key member
  • 删除并返回有序集合key中的最多count个具有最高得分的成员。
zpopmax key count

如未指定,count的默认值为1。指定一个大于有序集合的基数的count不会产生错误。 当返回多个元素时候,得分最高的元素将是第一个元素,然后是分数较低的元素。

  • 删除并返回有序集合key中的最高得分的成员。
bzpopmax key1,key2... timeout
当key有多个时,返回第一个非空集合的score最大的元素,key,score;
当集合列表都为空时,阻塞连接,timeout设为0表示永久阻塞,否则超过timeout就返回nil;
  • 删除并返回有序集合key中的最多count个具有最低得分的成员。
zpopmin key count

count默认值与zpopmax一样是1,只是当返回多个元素时候,得分最低的元素将是第一个元素,然后是分数较高的元素。

  • 删除并返回有序集合key中的最低得分的成员。
bzpopmin key1,key2... timeout
当key有多个时,返回第一个非空集合的score最小的元素,key,score;
当集合列表都为空时,阻塞连接,timeout设为0表示永久阻塞,否则超过timeout就返回nil;
  • 获取有序集合中指定成员之间的成员数量。
zlexcount zset [minMember [maxMember
#minMember 在有序集合中分数排名较小的成员
#maxMember在有序集合中分数排名较大的成员
成员名称前需要加 [ 符号作为开头, [ 符号与成员之间不能有空格
可以使用 - 和 + 表示得分最小值和最大值
min 和 max 不能反, max 放前面 min放后面会导致返回结果为0
计算成员之间的成员数量时,参数 min 和 max 的位置也计算在内。

演示

# 往有序集合zset中添加元素
127.0.0.1:6379> zadd zset 1 a 2 b 3 c 4 d 5 e
(integer) 5
# 获取有序集合zset中全部元素
127.0.0.1:6379> zrange zset 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
# 返回有序集合zset中所有score介于1~3的元素,从小到大
127.0.0.1:6379> zrangebyscore zset 1 3 withscores
1) "a"
2) "1"
3) "b"
4) "2"
5) "c"
6) "3"
# 返回有序集合zset中所有score介于1~3的元素,从大到小
127.0.0.1:6379> zrevrangebyscore zset 3 1 withscores
1) "c"
2) "3"
3) "b"
4) "2"
5) "a"
6) "1"
# 为有序集合zset的a元素的score加上增量10
127.0.0.1:6379> zincrby zset 10 a
#返回增加后的score
"11"
127.0.0.1:6379> zrange zset 0 -1
1) "b"
2) "c"
3) "d"
4) "e"
5) "a"
127.0.0.1:6379> zrangebyscore zset -inf +inf withscores
 1) "b"
 2) "2"
 3) "c"
 4) "3"
 5) "d"
 6) "4"
 7) "e"
 8) "5"
 9) "a"
10) "11"
# 删除有序集合zset的a元素
127.0.0.1:6379> zrem zset a
#返回1表示删除成功
(integer) 1
127.0.0.1:6379> zrange zset 0 -1
1) "b"
2) "c"
3) "d"
4) "e"
# 获取指定score范围([1,5])内元素个数
127.0.0.1:6379> zcount zset 1 5
(integer) 4
# 获取有序集合zset元素个数
127.0.0.1:6379> zcard zset
(integer) 4
# 获取有序集合zset中c元素的排名(从0开始,从小到大)
127.0.0.1:6379> zrank zset c
(integer) 1
# 获取有序集合zset中c元素的排名(从0开始,从大到小)
127.0.0.1:6379> zrevrank zset c
(integer) 2
# 获取并删除有序集合zset score最大的元素
127.0.0.1:6379> zpopmax zset
1) "e"
2) "5"
127.0.0.1:6379> zrange zset 0 -1
1) "b"
2) "c"
3) "d"
# 获取并删除有序集合zset score最小的元素
127.0.0.1:6379> zpopmin zset
1) "b"
2) "2"
127.0.0.1:6379> zrange zset 0 -1
1) "c"
2) "d"
# 获取zset全部元素,score从小到大
127.0.0.1:6379> zrange zset 0 -1 withscores
1) "c"
2) "3"
3) "d"
4) "4"
127.0.0.1:6379> zadd zset 1 a 2 b 5 e
(integer) 3
127.0.0.1:6379> zrange zset 0 -1 withscores
 1) "a"
 2) "1"
 3) "b"
 4) "2"
 5) "c"
 6) "3"
 7) "d"
 8) "4"
 9) "e"
10) "5"
# 获取zset全部元素,score从大到小
127.0.0.1:6379> zrevrange zset 0 -1 withscores
 1) "e"
 2) "5"
 3) "d"
 4) "4"
 5) "c"
 6) "3"
 7) "b"
 8) "2"
 9) "a"
10) "1"
# 获取zset集合中元素a~c之间成员数量(包括a、c)
127.0.0.1:6379> zlexcount zset [a [c
(integer) 3
#按score从小到大顺序获取zset集合全部元素
127.0.0.1:6379> zrangebyscore zset -inf +inf withscores
 1) "a"
 2) "1"
 3) "b"
 4) "2"
 5) "c"
 6) "3"
 7) "d"
 8) "4"
 9) "e"
10) "5"
#按score从大到小顺序获取zset集合全部元素
127.0.0.1:6379> zrevrangebyscore zset +inf -inf withscores
 1) "e"
 2) "5"
 3) "d"
 4) "4"
 5) "c"
 6) "3"
 7) "b"
 8) "2"
 9) "a"
10) "1"
#按score从大到小顺序获取zset集合元素,并分页下标从0开始,元素数量为3
127.0.0.1:6379> zrevrangebyscore zset +inf -inf withscores limit 0 3
1) "e"  #下标0
2) "5"
3) "d"	#下标1
4) "4"
5) "c"	#下标2
6) "3"
#按score从大到小顺序获取zset集合元素,并分页下标从3开始,元素数量为3
127.0.0.1:6379> zrevrangebyscore zset +inf -inf withscores limit 3 3
1) "b"	#下标3
2) "2"
3) "a"	#下标4
4) "1"

数据结构

Sorted Set(zset)是Redis提供的一个非常特别的数据结构,一方面它等价于Java的数据结构Map<String, Double>,可以给每一个元素value赋予一个权重score,另一方面它又类似于TreeSet,内部的元素会按照权重score进行排序,可以得到每个元素的名次,还可以通过score的范围来获取元素的列表。
zset底层使用了两个数据结构
(1)hash,hash的作用就是关联元素value和权重score,保障元素value的唯一性,可以通过元素value找到相应的score值。
(2)跳跃表,跳跃表的目的在于给元素value排序,根据score的范围获取元素列表。

案例

如何实现博客访问量排行榜?

127.0.0.1:6379> zadd blogs 1000 blog:1 2000 blog:2 3000 blog:3
(integer) 3
127.0.0.1:6379> zrevrangebyscore blogs +inf -inf withscores
1) "blog:3"
2) "3000"
3) "blog:2"
4) "2000"
5) "blog:1"
6) "1000"
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐