【 redis】有序集合

1.有序集合的定义 

有序集合保留了集合不能有重复成员的特性,有序集合中的元素可以排序。
但是它和列表使用索引下表作为排序依据不同的是,它给每个元素设置
一个分数作为排序的依据。

有序集合中元素不能重复,但是score可以重复。

列表:可以重复,有序,有索引下表。应用场景:时间轴,消息队列。 
集合:不重复,无序,无下标。应用场景:标签,社交等 
有序集合:不重复,有序,有分值。应用场景:排行榜系统,社交等 。

2.集合的使用

(1)添加成员 
--返回添加个数
192.168.1.51:6379> zadd user:ranking 251 tom
(integer) 1
192.168.1.51:6379> zadd user:ranking 1 kris 91 mike 200 frank 220 tim 250 martin 
(integer) 5

redis3.2为zadd命令添加了 nx,xx,ch,incr 四个选项。
nx:member必须不存在,才可以设置成功,用于添加 。
xx:member必须存在,才可以设置成功,用于更新。
ch:返回此次操作后,有序集合元素和分数发生变化的个数。
incr:对score做增加,相当于zincrby 

有序集合相比集合提供了排序字段,但是也产生了代价。
(2)计算成员个数 
192.168.1.51:6379> zcard user:ranking
(integer) 6

(3)计算某个成员的分数 
192.168.1.51:6379> zscore user:ranking martin
"250"

(4)计算成员排名 
--第四名 
192.168.1.51:6379> zrank user:ranking martin
(integer) 4
192.168.1.51:6379> zrevrank user:ranking martin
(integer) 1

zrank是从分数从低到高返回排名,zrevrank从高到低。
(5)删除成员
--删除martin
192.168.1.51:6379> zrem user:ranking martin
(integer) 1
(6)增加成员分数
--给tom增加9分,变成了260分。
192.168.1.51:6379> zincrby user:ranking 9 tom
"260"
(7)返回指定排名成员。
--从低到高返回成绩最低的三个成员。
192.168.1.51:6379> zrange user:ranking 0 2 withscores
1) "kris"
2) "1"
3) "mike"
4) "91"
5) "frank"
6) "200"
--从高到低显示成绩最好的三个人。
192.168.1.51:6379> zrevrange user:ranking 0 2 
1) "tom"
2) "tim"
3) "frank"
192.168.1.51:6379> zrevrange user:ranking 0 2 withscores
1) "tom"
2) "260"
3) "tim"
4) "220"
5) "frank"
6) "200"

(8)返回指定分数范围的成员 
--200到221分之间的人。
192.168.1.51:6379> zrangebyscore user:ranking 200 221 withscores
1) "frank"
2) "200"
3) "tim"
4) "220"
--从高到低未输出值。可能存在bug;
192.168.1.51:6379> zrevrangebyscore user:ranking 200 221 withscores
(empty list or set)

同时min和max还支持开区间(小括号)和闭区间(中括号),
-inf和+inf 分别代表无限小和无限大。

--从小到大去200到无穷大的值。
192.168.1.51:6379> zrangebyscore user:ranking (200 +inf withscores
1) "tim"
2) "220"
3) "tom"
4) "260"
--没有小括号就是闭区间,有小括号就是开区间。
192.168.1.51:6379> zrangebyscore user:ranking 200 +inf withscores
1) "frank"
2) "200"
3) "tim"
4) "220"
5) "tom"
6) "260"

(9)返回指定分数范围成员个数 
--200到300分之间的人数。
192.168.1.51:6379> zcount user:ranking 200 300
(integer) 3

(10)删除指定排名内的升序元素 
zremrangebyrank user:ranking 0 2 
--删除前三名 
192.168.1.51:6379> zremrangebyrank user:ranking 0 2
(integer) 3
(11)删除指定分数范围的成员 
--删除大于250的。
192.168.1.51:6379> zremrangebyscore user:ranking (250 +inf
(integer) 1

3.集合间的操作。

zadd user:ranking:1 1 kris 91 mike 200 frank 220 tim 250 martin 251 tom 
zadd user:ranking:2 8 james 77 mike 625 martin 888 tom 

(1)交集 
zinterstore destination numkeys key [key] [weight weight] [aggregate sum|min|max]

destination:交集计算结果保存到这个键。
numkeys:有几个键做交集计算。
key:需要做交集的键 
weight:每个键的权重,在做交集计算时,每个键中的每个member会将自己的分数乘以这个权重,
每个键的权重默认是1;
aggregate sum|min|max:计算成员交集后分值可以按照sum,min,max做汇总。默认是sum;

--user:ranking:2 的权重是0.5,使用max聚合。
192.168.1.51:6379> zinterstore user:ranking:1_inter_2 2 user:ranking:1 user:ranking:2 weights 1 0.5 aggregate max
(integer) 3

192.168.1.51:6379> zrange user:ranking:1_inter_2 0 -1 withscores
1) "mike"
2) "91"
3) "martin"
4) "312.5"
5) "tom"
6) "444"

--按照默认的权重1,做sum聚合。
192.168.1.51:6379> zinterstore user:ranking:1_inter_2_1 2 user:ranking:1 user:ranking:2
(integer) 3

192.168.1.51:6379> zrange user:ranking:1_inter_2_1 0 -1 withscores
1) "mike"
2) "168"
3) "martin"
4) "875"
5) "tom"
6) "1139"

(2)并集 
192.168.1.51:6379> zunionstore user:ranking:1_union_2 2 user:ranking:1 user:ranking:2 
(integer) 7
--2个键做并集,结束后,sum求和。
192.168.1.51:6379> zrange user:ranking:1_union_2 0 -1 withscores
 1) "kris"
 2) "1"
 3) "james"
 4) "8"
 5) "mike"
 6) "168"
 7) "frank"
 8) "200"
 9) "tim"
10) "220"
11) "martin"
12) "875"
13) "tom"
14) "1139"  --这里重复值做了求和处理。

开发时需要注意时间复杂度,防止由于使用不当造成的应用程序效率
下降以及redis阻塞。

4.内部编码 

有序集合类型内部编码有两种
ziplist(压缩列表):当有序集合的元素个数小于zset-max-ziplist-entries
(默认128个),同时每个元素的值都小于zset-max-ziplist-value 配置(默认64字节)
时,redis会用ziplist来作为有序集合的内部实现,ziplist可以有效减少内存的使用。

skiplist(跳跃表):当ziplist条件不满足时,有序集合使用skiplist作为内部实现。
因为此时ziplist的读写效率会下降。 

当元素个数少于128个,内部编码为ziplist;
元素个数大于128个时,内部编码为skiplist; 
当某个元素的个数大于64字节时,内部编码也会变成skiplist; 

5.有序集合的使用场景。

有序集合比较典型的使用场景就是排行榜系统。例如视频网站需要对用户上传的视频
做排行榜,榜单的维度可能是多个方面的:按时间,按照播放量,按照获得的赞数。

(1)mike获得三个赞。
192.168.1.7:6379> zadd user:ranking:20240619 3 mike 
(integer) 1
(2)又获得一个赞。
--累计四个赞了。
192.168.1.7:6379> zincrby user:ranking:20240619 1 mike
"4"
(3)展示获取赞数最多的10个用户 
--按照从大到小排序。
192.168.1.7:6379> zrevrangebyscore user:ranking:20240619 9 0
1) "mike"

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值