006.Redis基本数据结构五:有序集合(待完善)

  • 2020 年 3 月 26 日
  • 筆記

1. 有序集合简介

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

2. 常用命令

# (1) 添加元素:ZADD key [NX|XX] [CH] [INCR] score value  # NX:value必须不存在才可以添加成功  # XX:value必须存在才可以添加成功,用于更新  # CH:返回score或者value发生变化的个数  # INCR:score  # 返回添加成功的个数  beh07:6379> ZADD students 100 tom  (integer) 1  beh07:6379> ZADD students 98 tony  (integer) 1  beh07:6379> ZADD students CH 77 bob 88 tom  (integer) 2  # 在原来score的基础上+87,返回增加之后的分值  beh07:6379> ZADD students INCR 87 jack  "174"    # (2) 统计元素个数  beh07:6379> ZCARD students  (integer) 4    # (3) 获取元素分值  beh07:6379> ZSCORE students tom  "88"    # (4) 计算排名  # 获取[m,n]位排序后的元素,[0,-1]代表获取全部元素,默认是使用score升序排序  beh07:6379> ZRANGE students 0 -1  1) "bob"  2) "tom"  3) "tony"  4) "jack"  # 获取[m,n]位排序后的元素,[0,-1]代表获取全部元素,降序排序,withscores参数可以返回分数  beh07:6379> ZREVRANGE students 0 2 WITHSCORES  1) "jack"  2) "174"  3) "tony"  4) "98"  5) "tom"  6) "88"  # 获取指定value的排名(升序,从0开始)  beh07:6379> ZRANK students tom  (integer) 1  # 获取指定vaue的排名(降序,从0开始)  beh07:6379> ZREVRANK students tom  (integer) 2    # (5) 删除元素  beh07:6379> ZREM students jack  (integer) 1    # (6) 增加分数  beh07:6379> ZSCORE students tom  "88"  beh07:6379> ZINCRBY students 12 tom  "100"    # (7) 返回指定排名范围的成员  # 返回倒数前3名  beh07:6379> zrange students 0 2 withscores  1) "Eirene"  2) "92"  3) "Habiba"  4) "93"  5) "Isoke"  6) "94"  # 返回前3名  beh07:6379> zrevrange students 0 2 withscores  1) "tom"  2) "100"  3) "Miki"  4) "99"  5) "tony"  6) "98"    # (8) 返回指定分数范围的成员  # zrangebyscore key min max [withscores] [limit offset count]  # zrevrangebyscore key min max [withscores] [limit offset count]  # zrangebyscore升序,zrevrangebyscore降序  # 指定的范围min和max都会包括到输出范围,[min, max]  # [limit offset count]用于限制输出的起始位置和个数  beh07:6379> zrangebyscore students 95 99 withscores   1) "Jayne"   2) "95"   3) "Joy"   4) "96"   5) "Kirima"   6) "97"   7) "Laura"   8) "98"   9) "tony"  10) "98"  11) "Miki"  12) "99"  # +inf:正无穷,-inf:负无穷  beh07:6379> zrangebyscore students 95 +inf withscores   1) "Jayne"   2) "95"   3) "Joy"   4) "96"   5) "Kirima"   6) "97"   7) "Laura"   8) "98"   9) "tony"  10) "98"  11) "Miki"  12) "99"  13) "tom"  14) "100"  beh07:6379> zrangebyscore students -inf 90 withscores  1) "bob"  2) "77"  3) "Allen"  4) "90"  # 从第4名开始输出2个结果(第一名索引为0)  beh07:6379> zrangebyscore students -inf +inf withscores limit 3 2  1) "Eirene"  2) "92"  3) "Habiba"  4) "93"  # 支持开区间,'('代表开区间,默认是闭区间  beh07:6379> zrangebyscore students (90 93 withscores  1) "Danica"  2) "91"  3) "Eirene"  4) "92"  5) "Habiba"  6) "93"  beh07:6379> zrangebyscore students 90 (93 withscores  1) "Allen"  2) "90"  3) "Danica"  4) "91"  5) "Eirene"  6) "92"  beh07:6379> zrangebyscore students (90 (93 withscores  1) "Danica"  2) "91"  3) "Eirene"  4) "92"    # (9) 返回指定分数范围内的成员个数  beh07:6379> zcount students 90 100  (integer) 12    # (10) 删除指定排名内的成员  # 升序排序,删除前3名  beh07:6379> zremrangebyrank students 0 2  (integer) 3    # (11) 删除指定分数范围内的成员  beh07:6379> zremrangebyscore students 95 99  (integer) 6    # (12) 删除指定值的元素  beh07:6379> zrem students tom  (integer) 1

3. 集合间操作

准备测试数据:

beh07:6379> zadd user1 67 Allen 88 Mike 98 Candy 97 Ella 99 Hebe 56 Wawa  (integer) 6  beh07:6379> zadd user2 73 Bob 82 Mike 43 Hebe 77 Wawa  (integer) 4
# (1) 交集  # 对集合user1和user2做交集,结果保存到user_inter1集合中  # 数字2的意思做交集的集合的个数,zinterstore user_inter_tmp n user1 user2 ... usern  beh07:6379> zinterstore user_inter1 2 user1 user2  (integer) 3  # 可以看到对于相同的value的分数做了加法  beh07:6379> zrange user_inter1 0 -1 withscores  1) "Wawa"  2) "133"  3) "Hebe"  4) "142"  5) "Mike"  6) "170"  # 指定权重,默认为1  beh07:6379> zinterstore user_inter2 2 user1 user2 WEIGHTS 1 0.5 AGGREGATE max  (integer) 3  # 最终分数的计算过程 score = max(user1.value.score * 1, user2.value.score * 0.5)  # 支持的聚合操作有max/min/sum,默认使用sum  beh07:6379> zrange user_inter2 0 -1 withscores  1) "Wawa"  2) "56"  3) "Mike"  4) "88"  5) "Hebe"  6) "99"    # (2) 并集  # zunionstore的参数用法与zinterstore相同  beh07:6379> zunionstore user_union1 2 user1 user2  (integer) 7  beh07:6379> zrange user_union1 0 -1 withscores   1) "Allen"   2) "67"   3) "Bob"   4) "73"   5) "Ella"   6) "97"   7) "Candy"   8) "98"   9) "Wawa"  10) "133"  11) "Hebe"  12) "142"  13) "Mike"  14) "170"  beh07:6379> zunionstore user_union2 2 user1 user2 WEIGHTS 1 0.5 AGGREGATE MIN  (integer) 7  beh07:6379> zrange user_union2 0 -1 withscores   1) "Hebe"   2) "21.5"   3) "Bob"   4) "36.5"   5) "Wawa"   6) "38.5"   7) "Mike"   8) "41"   9) "Allen"  10) "67"  11) "Ella"  12) "97"  13) "Candy"  14) "98"

4. 内部编码

相关参数:

zset-max-ziplist-entries 128  zset-max-ziplist-value 64

当有序集合中的元素个数小于zset-max-ziplist-entries配置的值同时每个元素的大小不超过64字节时,使用ziplist作为底层实现,否则使用skiplist作为底层实现

beh07:6379> zadd zset1 1 tom  (integer) 1  beh07:6379> object encoding zset1  "ziplist"    beh07:6379> zadd zset2 1 'ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ'  (integer) 1  beh07:6379> object encoding zset2  "skiplist"

(2) skiplist底层结构

待完善!