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

3550 篇文章 121 订阅

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

1 命令

1.1 集合内操作

1.1.1 添加元素

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

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

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

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

1.1.2 计算元素个数

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

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

1.1.3 查询某元素分数

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

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

1.1.4 查询元素排名

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

127.0.0.1:6379> zrank name luke
(integer) 0
127.0.0.1:6379> zrevrank name luke
(integer) 3
复制代码

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

1.1.5 删除元素

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

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

1.1.6 增加元素分数

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

127.0.0.1:6379> zincrby name 99 luke
"100"
复制代码

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1.2 集合操作

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

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

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里

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

1.2.2 并集

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

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

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显示点赞量最多的几个用户

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值