目录

一、zset数据结构

二、Redis的zset

三、详细操作

基础操作(zadd、zcrad、zcount)

排序操作(zrange 、zrevrange )

根据分数显示元素(zrangebyscore)

删除操作(zrem、zremrangebyrank、zremrangebyscore)


一、zset数据结构

相比于set,sorted set 增加了一个权重参数 score,使得集合中的元素能够按 score 进行有序排列,还可以通过 score 的范围来获取元素的列表。

zset有两种不同的实现,分别是zipList和skipList。

zipList:
满足以下两个条件:

  • [score,value]键值对数量少于128个;
  • 每个元素的长度小于64字节;

skipList:
不满足以上两个条件时使用跳表(组合了hash和skipList)

  • hash用来存储value到score的映射,这样就可以在O(1)时间内找到value对应的分数;
  • skipList按照从小到大的顺序存储分数;
  • skipList每个元素的值都是[score,value]对
     

二、Redis的zset

Redis 中 zset 不是单一结构完成,是跳表和哈希表共同完成。

实现方式:Redis sorted set的内部使用HashMap和跳跃表(skipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,而跳跃表里存放的是所有的成员,排序依据是HashMap里存的score,使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。

使用zipList的示意图如下所示:

Redis 常用数据类型之 zset_php

使用跳表时的示意图:

Redis 常用数据类型之 zset_List_02

hash用于记录权重

ps:跳表介绍可以参考如下文章 

Redis 跳跃表的原理和实现_redis跳表原理_击水三千里的博客

三、详细操作

基础操作(zadd、zcrad、zcount)

127.0.0.1:6379> zadd books 49 java 79 springboot 80 python 50 php        # 添加元素
(integer) 4
127.0.0.1:6379> zadd books 30 java2
(integer) 1
127.0.0.1:6379> zcard books                                              # 查看数量
(integer) 5
127.0.0.1:6379> zcount books 0 3                                         # 根据分数显示指定的元素,有没有分数在 0 到 3 的数据,这里就返回 0
(integer) 0
127.0.0.1:6379> zcount books 0 70                                        # 返回分数在 0 到 70 之间的数据
(integer) 3
127.0.0.1:6379>

排序操作(zrange 、zrevrange )

127.0.0.1:6379>zrange books 0 -1                                        # 顺序查询集合中的成员
1) "java2"
2) "java"
3) "php"
4) "springboot"
5) "python"
127.0.0.1:6379> zrevrange books 0 -1                                     # 倒序查看集合中的成员
1) "python"
2) "springboot"
3) "php"
4) "java"
5) "java2"
127.0.0.1:6379>

根据分数显示元素(zrangebyscore)

这里有一个内置值 inf,表示无穷,  -inf 表示负无穷, +inf 表示正无穷

127.0.0.1:6379> zrangebyscore books -inf +inf                # 显示元素从大到小排序
1) "java2"
2) "java"
3) "php"
4) "springboot"
5) "python"
127.0.0.1:6379> zrangebyscore books -inf +inf withscores     # 显示元素从大到小,并且附带成绩
 1) "java2"
 2) "30"
 3) "java"
 4) "49"
 5) "php"
 6) "50"
 7) "springboot"
 8) "79"
 9) "python"
10) "80"
127.0.0.1:6379> zrangebyscore books -inf 50 withscores        # 显示元素 <= 50 的那部分
1) "java2"
2) "30"
3) "java"
4) "49"
5) "php"
6) "50"
127.0.0.1:6379>

删除操作(zrem、zremrangebyrank、zremrangebyscore)

127.0.0.1:6379> zrem books java                    # 删除指定元素
(integer) 1
127.0.0.1:6379> zrange books 0 -1
1) "java2"
2) "php"
3) "springboot"
4) "python"
127.0.0.1:6379> zremrangebyrank books 0 -1         # 根据数组下标删除指定的元素
(integer) 4
127.0.0.1:6379> zrange books 0 -1
(empty list or set)
127.0.0.1:6379>
127.0.0.1:6379> zadd mysort 10 key1 20 key2 30 key3 40 key4            #  重新添加集合元素
(integer) 4
127.0.0.1:6379> zadd mysort 10 key5 30 key6
(integer) 2
127.0.0.1:6379> zrange mysort 0 -1                                     # 查看集合中的元素
1) "key1"
2) "key5"
3) "key2"
4) "key3"
5) "key6"
6) "key4"
127.0.0.1:6379> zremrangebyrank mysort 0 2                            # 根据数组的下标来删除元素
(integer) 3
127.0.0.1:6379> zrange mysort 0 -1
1) "key3"
2) "key6"
3) "key4"
127.0.0.1:6379> zrangebyscore mysort -inf +inf WITHSCORES
1) "key3"
2) "30"
3) "key6"
4) "30"
5) "key4"
6) "40"
127.0.0.1:6379> zremrangebyscore mysort 0 1                         # 根据分数来删除,但是此时没有分数满足 0 到 1 删除的结果就为 0
(integer) 0
127.0.0.1:6379> zrange mysort 0 -1                                  # 再次查看
1) "key3"
2) "key6"
3) "key4"
127.0.0.1:6379> zremrangebyscore mysort 0 35                        # 再次根据分数来删除
(integer) 2
127.0.0.1:6379> zrange mysort 0 -1
1) "key4"
127.0.0.1:6379>