Redis学习笔记之有序集合

本文涉及的产品
云原生内存数据库 Tair,内存型 2GB
云数据库 Redis 版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: Redis学习笔记之有序集合

有序集合相对于哈希、列表、集合来说会有一点点陌生,但既然叫有序集合,那么它和集合必然有着联系,它保留了集合不能有重复成员的特性,但不同的是,有序集合中的成员可以排序。但是它和列表使用索引下标作为排序依据不同的是,它给每个成员设置一个分数(score)作为排序的依据。

1. 集合内

(1) 添加成员

zadd key [NX|XX] [CH] [INCR] score member [score member ..

下面操作向有序集合zset:1添加用户tom和他的分数251:

192.168.211.131:6379> zadd zset:1 251 tom
(integer) 1

返回结果代表成功添加成员的个数:

192.168.211.131:6379> zadd zset:1 91 mike 200 frank
(integer) 2

(2) 计算成员个数

zcard key

例如下面操作返回有序集合zset:1的成员数为3,和集合类型的scard命令一样,zcard的时间复杂度为O(1)。

192.168.211.131:6379> zcard zset:1
(integer) 3

(3) 计算某个成员的分数

zscore key member

mike的分数为91,如果成员不存在则返回nil:

192.168.211.131:6379> zscore zset:1 mike
"91"
192.168.211.131:6379> zscore zset:1 jim
(nil)

(4) 计算成员的排名

zrank key member
zrevrank key member

zrank是从分数从低到高返回排名,zrevrank反之。例如下面操作中,tom在zrank和zrevrank分别排名第和第(排名从0开始计算):

192.168.211.131:6379> zrank zset:1 tom

(integer) 2
192.168.211.131:6379> zrevrank zset:1 tom
(integer) 0

(5) 删除成员

zrem key member [member ...]

下面操作将成员mike从有序集合zset:1中删除:

192.168.211.131:6379> zrem zset:1 mike

(integer) 1

(6) 增加成员的分数

zincrby key increment member

下面操作给tom增加了9分,分数变成了260分:

192.168.211.131:6379> zincrby zset:1 9 tom
"260"

(7) 返回指定排名范围的成员

zrange key start stop [WITHSCORES]
zrevrange key start stop [WITHSCORES]

有序集合是按照分值排名的,zrange是从低到高返回,zrevrange反之。下面代码返回排名最低的三个成员,如果加上withscores选项,同时会返回成员的分数:

192.168.211.131:6379> zrange zset:1 0 2 withscores
1) "frank"
2) "200"
3) "tom"
4) "260"
192.168.211.131:6379> zrevrange zset:1 0 2 withscores
1) "tom"
2) "260"
3) "frank"
4) "200

(8) 返回指定分数范围的成员

zrangebyscore key min max [WITHSCORES] [LIMIT offset count]
zrevrangebyscore key max min [WITHSCORES] [LIMIT offset count]

其中zrangebyscore按照分数从低到高返回,zrevrangebyscore反之。
例如下面操作从低到高返回200到221分的成员,withscores选项会同时返回每个成员的分数。[limit offset count]选项可以限制输出的起始位置和个数:

192.168.211.131:6379> zrangebyscore zset:1 200 221 withscores
1) "frank"
2) "200"
3) "tim"
4) "210"
192.168.211.131:6379> zrevrangebyscore zset:1 221 200 withscores
1) "tim"
) "210"
3) "frank"
4) "200"

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

192.168.211.131:6379> zrangebyscore zset:1 (200 +inf withscores
1) "tim"
2) "210"
3) "tom"
4) "260"

(9) 返回指定分数范围成员个数

zcount key min max

下面操作返回200到221分的成员的个数:

192.168.211.131:6379> zcount zset:1 200 260
(integer) 3

(10) 删除指定排名内的升序元素

zremrangebyrank key start stop

下面操作删除第0到第2名的成员(排名从0开始):

192.168.211.131:6379> zremrangebyrank zset:1 0 2
(integer) 3

(11) 删除指定分数范围的成员

zremrangebyscore key min max

下面操作将250分以上的成员全部删除,返回结果为成功删除的个数:

192.168.211.131:6379> zremrangebyscore zset:1 (250 +inf
(integer) 1

2. 集合间的操作

创建2个有序集合:

192.168.211.131:6379> zadd zset:1 1 kris 91 mike 200 frank 220 tim 250 martin 251 tom
(integer) 6
192.168.211.131:6379> zadd zset:2 8 james 77 mike 625 martin 888 tom
(integer) 4

(1) 交集

zinterstore destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]

这个命令参数较多,下面分别进行说明:

  • destination:交集计算结果保存到这个键。
  • numkeys:需要做交集计算键的个数。
  • key [key ...]:需要做交集计算的键。
  • WEIGHTS weight:每个键的权重,在做交集计算时,每个键中的每个member会将自己分数乘以这个权重,每个键的权重默认是1。
  • aggregate sum|min|max:计算成员交集后,分值可以按照sum(和)、min(最小值)、max(最大值)做汇总,默认是sum。
    下面操作对zset:1和zset:2做交集,weights和aggregate使用了默认配置,可以看到目标键zset:1_inter_2对分值做了sum操作:

192.168.211.131:6379> zinterstore zset:1_inter_2 2 zset:1 zset:2
(integer) 3
192.168.211.131:6379> zrange zset:1_inter_2 0 -1 withscores
1) "mike"
2) "168"
3) "martin"
4) "875"
5) "tom"
6) "1139"

如果想让zset:2的权重变为0.5,并且聚合效果使用max,可以执行如下操作:

192.168.211.131:6379> zinterstore zset:1_inter_2 2 zset:1 zset:2 weights 1 0.5 aggregate max
(integer) 3
192.168.211.131:6379> zrange zset:1_inter_2 0 -1 withscores
1) "mike"
2) "91"
3) "martin"
4) "312.5"
5) "tom"
6) "444"

(2) 并集

zunionstore destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]

该命令的所有参数和zinterstore是一致的,只不过是做并集计算,例如下面操作是计算zset:1和zset:2的并集,weights和aggregate使用了默认配置,可以看到目标键zset:1_inter_2对分值做了sum操作:

192.168.211.131:6379> zunionstore zset:1_inter_2 2 zset:1 zset:2
(integer) 7
192.168.211.131:6379> zrange zset:1_inter_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实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
3月前
|
存储 NoSQL Redis
Redis系列学习文章分享---第十六篇(Redis原理1篇--Redis数据结构-动态字符串,insert,Dict,ZipList,QuickList,SkipList,RedisObject)
Redis系列学习文章分享---第十六篇(Redis原理1篇--Redis数据结构-动态字符串,insert,Dict,ZipList,QuickList,SkipList,RedisObject)
71 1
|
3月前
|
NoSQL Java Redis
Redis系列学习文章分享---第十八篇(Redis原理篇--网络模型,通讯协议,内存回收)
Redis系列学习文章分享---第十八篇(Redis原理篇--网络模型,通讯协议,内存回收)
63 0
|
3月前
|
存储 消息中间件 缓存
Redis系列学习文章分享---第十七篇(Redis原理篇--数据结构,网络模型)
Redis系列学习文章分享---第十七篇(Redis原理篇--数据结构,网络模型)
70 0
|
3月前
|
存储 NoSQL 算法
Redis系列学习文章分享---第十篇(Redis快速入门之附近商铺+用户签到+UV统计)
Redis系列学习文章分享---第十篇(Redis快速入门之附近商铺+用户签到+UV统计)
29 0
|
3月前
|
存储 NoSQL Redis
Redis系列学习文章分享---第九篇(Redis快速入门之好友关注--关注和取关 -共同关注 -Feed流实现方案分析 -推送到粉丝收件箱 -滚动分页查询)
Redis系列学习文章分享---第九篇(Redis快速入门之好友关注--关注和取关 -共同关注 -Feed流实现方案分析 -推送到粉丝收件箱 -滚动分页查询)
36 0
|
3月前
|
消息中间件 负载均衡 NoSQL
Redis系列学习文章分享---第七篇(Redis快速入门之消息队列--List实现消息队列 Pubsub实现消息队列 stream的单消费模式 stream的消费者组模式 基于stream消息队列)
Redis系列学习文章分享---第七篇(Redis快速入门之消息队列--List实现消息队列 Pubsub实现消息队列 stream的单消费模式 stream的消费者组模式 基于stream消息队列)
45 0
|
3月前
|
消息中间件 NoSQL Java
Redis系列学习文章分享---第六篇(Redis实战篇--Redis分布式锁+实现思路+误删问题+原子性+lua脚本+Redisson功能介绍+可重入锁+WatchDog机制+multiLock)
Redis系列学习文章分享---第六篇(Redis实战篇--Redis分布式锁+实现思路+误删问题+原子性+lua脚本+Redisson功能介绍+可重入锁+WatchDog机制+multiLock)
200 0
|
30天前
|
缓存 NoSQL 关系型数据库
Redis学习总结
Redis学习总结
31 1
|
3月前
|
存储 NoSQL 安全
Redis系列学习文章分享---第十五篇(Redis最佳实践--设计优雅的key+合适的数据结构+持久化如何配置+慢查询问题解决)
Redis系列学习文章分享---第十五篇(Redis最佳实践--设计优雅的key+合适的数据结构+持久化如何配置+慢查询问题解决)
62 1
|
3月前
|
缓存 负载均衡 NoSQL
Redis系列学习文章分享---第十四篇(Redis多级缓存--封装Http请求+向tomcat发送http请求+根据商品id对tomcat集群负载均衡)
Redis系列学习文章分享---第十四篇(Redis多级缓存--封装Http请求+向tomcat发送http请求+根据商品id对tomcat集群负载均衡)
64 1