Redis学习笔记之有序集合

本文涉及的产品
云数据库 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
相关文章
|
2月前
|
存储 NoSQL Java
【Redis系列】那有序集合为什么要同时使用字典和跳跃表
面试官问:那有序集合为什么要同时使用字典和跳跃表来实现?我:这个设计主要是考虑了性能因素。1. 如果单纯使用字典,查询的效率很高是O(1),但执行类似ZRANGE、ZRNK时,排序性能低。每次排序需要在内存上对字典进行排序一次,同时消耗了额外的O(n)内存空间
34 2
【Redis系列】那有序集合为什么要同时使用字典和跳跃表
|
5月前
|
存储 NoSQL Linux
小白带你学习linux的Redis基础(三十二)
小白带你学习linux的Redis基础(三十二)
76 0
|
4月前
|
存储 NoSQL Redis
redis源码学习
redis源码学习
|
5月前
|
存储 NoSQL Ubuntu
在Ubuntu上安装Redis并学习使用get、set和keys命令
在Ubuntu上安装Redis并学习使用get、set和keys命令
|
6月前
|
缓存 NoSQL Redis
【Redis 系列】redis 学习十六,redis 字典(map) 及其核心编码结构
【Redis 系列】redis 学习十六,redis 字典(map) 及其核心编码结构
|
6月前
|
NoSQL 算法 Redis
【Redis 系列】redis 学习十四,sorted_set 初步探究梳理
【Redis 系列】redis 学习十四,sorted_set 初步探究梳理
|
6月前
|
存储 NoSQL Redis
【Redis 系列】redis 学习十五,redis sds数据结构和底层设计原理
【Redis 系列】redis 学习十五,redis sds数据结构和底层设计原理
|
4月前
|
NoSQL 中间件 API
分布式锁【数据库乐观锁实现的分布式锁、Zookeeper分布式锁原理、Redis实现的分布式锁】(三)-全面详解(学习总结---从入门到深化)(下)
分布式锁【数据库乐观锁实现的分布式锁、Zookeeper分布式锁原理、Redis实现的分布式锁】(三)-全面详解(学习总结---从入门到深化)
86 2
|
4月前
|
NoSQL Java API
分布式锁【数据库乐观锁实现的分布式锁、Zookeeper分布式锁原理、Redis实现的分布式锁】(三)-全面详解(学习总结---从入门到深化)(上)
分布式锁【数据库乐观锁实现的分布式锁、Zookeeper分布式锁原理、Redis实现的分布式锁】(三)-全面详解(学习总结---从入门到深化)
75 0
|
6月前
|
存储 NoSQL 算法
[Redis 系列]redis 学习 17,redis 存储结构原理 1
[Redis 系列]redis 学习 17,redis 存储结构原理 1