小白都能看懂的Redis数据类型-有序集合

缺乏、安全感 2023-09-26 10:12 108阅读 0赞

有序集合,首先它肯定是个集合,是集合那么对应的value不能重复。有序集合我们一般称之为zset,是在集合的基础上,给每个元素赋予了一个分数(score),然后使用这个分数进行排序,而且这个分数是可以重复的。

1 命令

1.1 集合内操作

1.1.1 添加元素

在有序集合内添加元素除了元素本身外还要设置分数
zadd key score member
以下例子向key为name的有序集合内添加了一个分数为1的元素luke

  1. 127.0.0.1:6379> zadd name 1 luke
  2. (integer) 1
  3. 复制代码

分数只能是数字
在3.2版本之后,给zadd命令添加了几个参数

  • nx 元素不存在的情况才能设置成功
  • xx 元素存在的情况下才能设置成功
  • ch 返回此次操作修改的分数和元素的个数
  • incr 增加score

1.1.2 计算元素个数

zcard key可以计算对应key内元素的的个数
下边例子我们向有序集合name内添加了四个元素,然后查询个数并返回

  1. 127.0.0.1:6379> zadd name 1 luke 2 a 3 b 4 d
  2. (integer) 4
  3. 127.0.0.1:6379> zcard name
  4. (integer) 4
  5. 复制代码

1.1.3 查询某元素分数

zscore key member可以查询ky内元素member的分数
比如我们查询name内luke的分数

  1. 127.0.0.1:6379> zscore name luke
  2. "1"
  3. 复制代码

1.1.4 查询元素排名

查询排名有两个命令
zrank key member顺序,从小到大
zrevrank key member逆序,从大到小
下面我们查询name内luke的排名

  1. 127.0.0.1:6379> zrank name luke
  2. (integer) 0
  3. 127.0.0.1:6379> zrevrank name luke
  4. (integer) 3
  5. 复制代码

当元素不存在的时候会返回nil

1.1.5 删除元素

zrem key member可以删除指定的元素

  1. 127.0.0.1:6379> zrem name d
  2. (integer) 1
  3. 复制代码

1.1.6 增加元素分数

当需要增加元素分数的时候,需要用到zincrby key score member
下边的例子给name内元素luke加了99分

  1. 127.0.0.1:6379> zincrby name 99 luke
  2. "100"
  3. 复制代码

返回的是该元素增加后的新分数

1.1.7 返回指定排名范围的元素

对于这个和之后的命令,我们创建一个新的有序列表

  1. 127.0.0.1:6379> zadd stu 1 a 2 b 3 c 4 d 5 e 6 f 7 g 8 h
  2. (integer) 8
  3. 复制代码

返回指定排名的元素需要用到以下两个命令
zrange key start end [withscore]顺序,从低到高
zrevrange key start end [withscore]逆序,从高到低
比如我们查询分数最低的三个元素

  1. 127.0.0.1:6379> zrange stu 0 2
  2. 1) "a"
  3. 2) "b"
  4. 3) "c"
  5. 复制代码

1.1.8 返回指定分数范围的元素

通过分数查询元素也对应的是两条命令
zrangebyscore key min max [withscores] [limit offset count]按照分数从高到底
zrevrangebyscore key min max [withscores] [limit offset count]按照分数从低到高

  1. 127.0.0.1:6379> zrangebyscore stu 2 4
  2. 1) "b"
  3. 2) "c"
  4. 3) "d"
  5. 复制代码

withscores可以返回元素和分数,下面的命令会返回stu下分数在2到4之间的元素和分值

  1. 127.0.0.1:6379> zrangebyscore stu 2 4 withscores
  2. 1) "b"
  3. 2) "2"
  4. 3) "c"
  5. 4) "3"
  6. 5) "d"
  7. 6) "4"
  8. 复制代码

limit offset count则限制返回的其实位置和个数,下边的命令会返回stu下分数在2到4之间且排序在第2个之后的两个元素的元素

  1. 127.0.0.1:6379> zrangebyscore stu 2 4 withscores limit 1 2
  2. 1) "c"
  3. 2) "3"
  4. 3) "d"
  5. 4) "4"
  6. 复制代码

而且这个命令还支持开区间(小括号)和闭区间(中括号),还有两个值-inf和 +inf,-inf表示无穷小,+inf表示无穷大
下边的例子返回了分数在2-4但不包括2的元素

  1. 127.0.0.1:6379> zrangebyscore stu (2 4
  2. 1) "c"
  3. 2) "d"
  4. 复制代码

1.1.9 返回指定分数范围的元素个数

zcount key min max可以返回指定分数区间内元素的个数

  1. 127.0.0.1:6379> zcount stu 1 3
  2. (integer) 3
  3. 复制代码

1.1.10 删除指定排名内的升序元素

需要删除指定排名范围内的升序元素我们可以使用zremrangebyrank key start end 这里是删除了按从小到大排列的第七和第八个元素,因为是从0开始的,所以第七是有元素的,第八为空,所以只删除了第七个元素

  1. 127.0.0.1:6379> zremrangebyrank stu 7 8
  2. (integer) 1
  3. 复制代码

1.1.11 删除指定分数范围的元素

zremrangebyscore key min max这个命令可以删除指定分数范围内的元素,同时也支持开区间和闭区间。

下边的例子就把所有大于5分的元素全删了

  1. 127.0.0.1:6379> zremrangebyscore stu (5 +inf
  2. (integer) 2
  3. 复制代码

1.2 集合操作

在集合操作的时候我们创建两个新的有序集合

  1. 127.0.0.1:6379> zadd user1 1 a 2 b 3 c 4 d
  2. (integer) 4
  3. 127.0.0.1:6379> zadd user2 5 b 6 c 7 d 8 e
  4. (integer) 4
  5. 复制代码

1.2.1 交集

求交集的命令是 zinterstore destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX],这个参数比较多我们一一解释

  • destination 也就是newkey,求过交集之后的新集合会以这个key保存
  • numkeys 需要做交集计算键的个数
  • key [key ...] 需要做交集计算的键
  • [WEIGHTS weight] 每个键的权重,在交集计算的时候,每个键中的每个元素的分值会乘以这个权重,默认是1
  • [AGGREGATE SUM|MIN|MAX] 计算过交集后,相同元素的的分值可以按照sum(和),min(最小值),max(最大值)做汇总,默认是sum

下面举个例子,对我们之前新建的两个集合做交集,并保存到新的key newkey里

  1. 127.0.0.1:6379> zinterstore newkey 2 user1 user2
  2. (integer) 3
  3. 127.0.0.1:6379> zrange newkey 0 -1 withscores
  4. 1) "b"
  5. 2) "7"
  6. 3) "c"
  7. 4) "9"
  8. 5) "d"
  9. 6) "11"
  10. 复制代码

1.2.2 并集

zunionstore destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]这个命令参数的含义与求交集时相同

  1. 127.0.0.1:6379> zunionstore newkey2 2 user1 user2
  2. (integer) 5
  3. 127.0.0.1:6379> zrange newkey2 0 -1 withscores
  4. 1) "a"
  5. 2) "1"
  6. 3) "b"
  7. 4) "7"
  8. 5) "e"
  9. 6) "8"
  10. 7) "c"
  11. 8) "9"
  12. 9) "d"
  13. 10) "11"
  14. 复制代码

2 内部编码

有序集合的内部编码有两种,ziplist和skiplist

2.1 ziplist

使用ziplist作为内部编码有两个条件

  1. 元素个数小于配置zset-max-ziplist-entries,默认为512
  2. 每个元素的大小小于zset-max-ziplist-value,默认时64字节

2.2 skiplist

当不满足上边的两个条件的时候,会使用skiplist作为内部编码的实现,相对于skiplist,ziplist占用空间更小

3 使用场景

使用最多的就是排行榜功能
比如掘金内按照点赞的数量进行排行
设置key并且按照点赞数量为score和文章id作为value的形式构建有序列表
当有新的文章增加的时候,则使用zadd添加
当某篇文章点赞数新增的时候则使用zincrby增加分值
若是有用户作弊刷赞,则可以使用zrem取消排行中的用户
此时我们可以使用zrevrange显示点赞量最多的几个用户

发表评论

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

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

相关阅读