API的理解和使用——有序集合
| 命令 | 功能 |
| zadd key score member [score member ... ] | 添加元素 |
| zcard key | 计算成员个数 |
| zscore key member | 计算某个成员分数 |
|
zrank key member zrevrank key member |
计算成员排名 |
| zrem key member [member ...] | 删除成员 |
| zincrby key increment member | 增长成员分数 |
|
zrange key start end [withscores] zrevrabge key start end [withscores] |
返回指定排名范围内的成员 |
|
zrangebyscore key min max [withscores] zrevrangebyscore key max min [withscores] |
返回指定分数范围内的成员 |
| zcount | 返回指定分数范围内成员个数 |
| zremrangebyrank key start end | 删除指定排名内的升序元素 |
| zremrangebyscore key min max | 删除指定分数范围内的成员 |
| zinterstore destination numkeys key [key ...] | 交集 |
| zunionstore destination numkeys key [key ...] | 并集 |
有序集合相对于哈希、列表、集合来说会有一点点陌生,但既然叫有序集合,那么它和集合必然有着联系,
它保留了集合不能有重复成员的特性,但不同的是,有序集合中的元素可以排序。
但是它和列表使用索引小标作为排序依据不同的是,它给每个元素设置一个分数(score)作为排序的依据。

有序集合提供了获取指定分数和元素范围查询、计算成员排名等功能,合理的利用有序集合,能帮助我们在实际开发中解决很多问题。
有序集合中的元素不能重复,但是score可以重复,就和一个班里的同学学号不能重复,但是考试成绩可以相同一样。
下面给出列表、集合、有序集合三者的异同点。
| 数据结构 | 是否允许重复元素 | 是否有序 | 有序实现方式 | 应用场景 |
| 列表 | 是 | 是 | 索引 | 时间轴、消息队列 |
| 集合 | 否 | 否 | 无 | 标签 |
| 有序集合 | 否 | 是 | score | 排行榜系统 |
下面按照集合内和集合外两个维度对有序集合的命令进行介绍。
先给出一个有序集合:NBA某一天的排名
| 胜差 | 球队 |
| 0 | BOS |
| 1.5 | CLE |
| 3.5 | TOR |
| 5 | WAS |
| 6.5 | DET |
| 7.5 | IND |
| 7.5 | NY |
| 8 | MIL |
1.集合内操作
(1)添加成员
命令:zadd key score member [score member ... ]
127.0.0.1:> zadd NBA:east BOS 1.5 CLE 3.5 TOR WAS 6.5 DET
(integer) #返回结果为成功添加成员个数
127.0.0.1:> zadd NBA:east 7.5 IND 7.5 NY MIL
(integer)
有关zadd命令有两点需要注意:
第一,Redis3.2为zadd命令添加了nx、xx、ch、incr4个选项:
- nx:member必须不存在,才可以设置成功,用于添加
- xx:member必须存在,才可以设置成功,用于更新
- ch:返回此次操作后,有序集合元素和分数发生变化的个数
- incr:对score做增加,相当于后面介绍的zincrby
第二,有序集合相比集合提供了排序字段,但是也产生了代价,zadd的时间复杂度为O(log(n)),sadd的时间复杂度为O(1)。
127.0.0.1:> zcard NBA:east
(integer)
(2)计算成员个数
命令:zcard key
与集合类型scard命令一样,返回集合的个数,zcard的时间复杂度为O(1)。
127.0.0.1:> zcard NBA:east
(integer)
(3)计算某个成员的分数
命令:zscore key member
返回某个成员的分数,注意与排名分开,如果成员不存在则返回nil:
127.0.0.1:> zscore NBA:east IND
"7.5"
127.0.0.1:> zscore NBA:east DET
"6.5"
(4)计算成员的排名
命令:
zrank key member
zrevrank key member
zrank是分数从低到高返回排名。zrevrank反之。
127.0.0.1:> zrank NBA:east CLE
(integer)
127.0.0.1:> zrank NBA:east BOS #从0开始
(integer)
127.0.0.1:> zrevrank NBA:east BOS
(integer)
127.0.0.1:> zrevrank NBA:east CLE
(integer)
(5)增加成员的分数
命令:zincrby key increment member
zincrby返回元素修改之后的分数:
127.0.0.1:> zscore NBA:east TOR
"3.5"
127.0.0.1:> zincrby NBA:east TOR #又输了场
"4.5"
(6)返回指定排名范围内的成员
命令:
zrange key start end [withscores]
zrevrange key start end [withscores]
有序集合是按照分值排名的,zrange是从低到高返回,zrevrange反之。
下面返回胜差最小,排名前三的,如果加上withscores选项,同时会返回成员分数:
127.0.0.1:> zrange NBA:east #取前三个
) "BOS"
) "CLE"
) "TOR"
127.0.0.1:> zrange NBA:east withscores #附带分数
) "BOS"
) ""
) "CLE"
) "1.5"
) "TOR"
) "4.5"
127.0.0.1:> zrevrange NBA:east withscores #反向取
) "MIL"
) ""
) "NY"
) "7.5"
) "IND"
) "7.5"
(7)返回指定分数范围内的成员
命令:
zrangebyscore key min max [withscores] [limit offset count]
zrevrangebyscore key max min [withscores] [limit offset count]
其中zrangebyscore按照分数从低到高返回,zrevrangebyscore反之。
127.0.0.1:> zrangebyscore NBA:east #正着取分数3-
) "TOR"
) "WAS"
127.0.0.1:> zrangebyscore NBA:east withscores
) "TOR"
) "4.5"
) "WAS"
) "" 127.0.0.1:> zrevrangebyscore NBA:east withscores
) "CLE"
) "1.5"
) "BOS" #反着取也就反着显示
) ""
同时min和max还支持开区间(小括号)和闭区间(中括号),-inf和+inf分别代表无限小和无限大:
127.0.0.1:> zrangebyscore NBA:east ( +inf withscores
) "DET"
) "6.5"
) "IND"
) "7.5"
) "NY"
) "7.5"
) "MIL"
) ""
(8)返回指定分数范围内的成员个数
命令:zcount key min max
127.0.0.1:> zcount NBA:east
(integer)
127.0.0.1:> zrangebyscore NBA:east
) "TOR"
) "WAS"
(9)删除成员
命令:zrem key member [member ... ]
127.0.0.1:> zrem NBA:east MIL
(integer)
(10)删除指定排名内的升序元素
命令:zremrangebyrank key start end
127.0.0.1:> zremrangebyrank NBA:east #按照排名删,包含两边,所以是3
(integer)
127.0.0.1:> zcard NBA:east
(integer)
(11)删除指定分数范围内的成员
命令:zremrangebyscore key min max
#删除大于八个胜场的球队
127.0.0.1:> zremrangebyscore NBA:east ( +inf
(integer)
2.集合间操作
将下面两个有序集合导入到Redis中。

127.0.0.1:> zadd user:ranking: kris mike frank tim martin tom
(integer)
127.0.0.1:> zadd user:ranking: james mike martin tom
(integer)
(1)交集
命令:
zinterstore destination numkeys key [key...] [weights weight [weight ... ]] [aggregate sum|min|max]
参数说明:
- destination:交集计算结果保存到这个键。
- numkeys:需要做交集计算键的个数。
- key [key ... ]:需要做交集计算的键。
- weights weight [weight ...]:每个键的权重,在做交集计算时,每个键中的每个member会将自己分数乘以这个权重,每个键的权重默认是1。
- aggregate sum|min|max:计算成员交集后,分值可以按照sum(和)、min(最小值)、max(最大值)做汇总,默认值是sum。
下面对两个集合取交集,weights和aggregate使用默认值:
127.0.0.1:> zinterstore user:ranking:1_inter_2 user:ranking: user:ranking:
(integer)
#查看结果
127.0.0.1:> zrange user:ranking:1_inter_2 - withscores
) "mike"
) ""
) "martin"
) ""
) "tom"
) "" #aggregate默认取和,权重为1.
如果想让user:ranking:2的权重变为0.5,并且集合效果使用max,可以执行如下操作:
127.0.0.1:> zinterstore user:ranking:1_inter_2 user:ranking: user:ranking: weights 0.5 aggregate max
(integer)
127.0.0.1:> zrange user:ranking:1_inter_2 - withscores
) "mike"
) ""
) "martin"
) "312.5"
) "tom"
) "" /
#再来一个例子
127.0.0.1:> zinterstore user:ranking:1_inter_2 user:ranking: user:ranking: weights 0.5 0.5 aggregate min
(integer)
127.0.0.1:> zrange user:ranking:1_inter_2 - withscores
) "mike"
) "38.5"
) "martin"
) ""
) "tom"
) "125.5"
(2)并集
命令:
zunionstore destination numkeys key [key ... ] [weights weight [weight ... ]] [aggregate sum|min|max]
该命令的所有参数和zinterstore是一致的,只不过是做并集计算。
下面对两个集合取并集,weights和aggregate使用默认配置
127.0.0.1:> zunionstore user:ranking:1_union_2 user:ranking: user:ranking:
(integer)
#相同元素相加,相异元素加进来成为一个新的元素
127.0.0.1:> zrange user:ranking:1_union_2 -
) "kris"
) "james"
) "mike"
) "frank"
) "tim"
) "martin"
) "tom" #值相加
127.0.0.1:> zrange user:ranking:1_union_2 - withscores
) "kris"
) ""
) "james"
) ""
) "mike"
) ""
) "frank"
) ""
) "tim"
) ""
) "martin"
) ""
) "tom"
) ""
下面会介绍这些命令的时间复杂度,开发人员在使用对应的命令进行开发时,不仅要考虑功能性,
还要了解相应的时间复杂度,防止由于使用不当造成应用方效率下降以及Redis阻塞。
| 命令 | 时间复杂度 |
| zadd key score member [score member ... ] | O(kxlog(n)),k是添加成员的个数,n是当前有序集合成员个数 |
| zcard key | O(1) |
| zscore key member | O(1) |
|
zrank key member zrevrank key member |
O(log(n)),n是当前有序集合成员的个数 |
| zrem key member [member ...] | O(k*log(n)),k是删除成员的个数,n是当前有序集合成员的个数 |
| zincrby key increment member | O(log(n)),n是当前有序集合成员个数 |
|
zrange key start end [withscores] zrevrabge key start end [withscores] |
O(log(n)+k),k是要获取的成员个数,n是当前有序集合成员的个数 |
|
zrangebyscore key min max [withscores] zrevrangebyscore key max min [withscores] |
O(log(n)+k),k是要获取的成员个数,n是当前有序集合成员的个数 |
| zcount | O(log(n)),n是当前有序集合成员个数 |
| zremrangebyrank key start end | O(log(n)+k),k是要删除的成员个数,n是当前有序集合成员的个数 |
| zremrangebyscore key min max | O(log(n)+k),k是要删除的成员个数,n是当前有序集合成员的个数 |
| zinterstore destination numkeys key [key ...] |
O(n*k)+O(m*log(m)),n是成员数最小的有序集合成员个数, k是有序集合的个数,m是结果集中成员个数 |
| zunionstore destination numkeys key [key ...] | O(n)+O(m*log(m)),n是所有有序集合成员个数和,m是结果集中成员个数 |
API的理解和使用——有序集合的更多相关文章
- 第二百九十九节,python操作redis缓存-SortSet有序集合类型,可以理解为有序列表
python操作redis缓存-SortSet有序集合类型,可以理解为有序列表 有序集合,在集合的基础上,为每元素排序:元素的排序需要根据另外一个值来进行比较,所以,对于有序集合,每一个元素有两个值, ...
- Redis 入门到分布式 (二)API的理解和使用
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 内容: 通用命令 单线程架构 数据结构和内部编码 一.常用的通用命令: keys 计算所有的 ...
- 《闲扯Redis十一》Redis 有序集合对象底层实现
一.前言 Redis 提供了5种数据类型:String(字符串).Hash(哈希).List(列表).Set(集合).Zset(有序集合),理解每种数据类型的特点对于redis的开发和运维非常重要. ...
- 2.API的理解和使用
标题 : 2.API的理解和使用 目录 : Redis 序号 : 2 zset的成员是唯一的,但分数(score)却可以重复. 有序集合的内部编码 1.ziplist(压缩列表):当有序集合的 ...
- Redis常用命令入门5:有序集合类型
有序集合类型 上节我们一起学习了集合类型,感受到了redis的强大.现在我们接着学Redis的最后一个类型——有序集合类型. 有序集合类型,大家从名字上应该就可以知道,实际上就是在集合类型上加了个有序 ...
- 15天玩转redis —— 第六篇 有序集合类型
今天我们说一下Redis中最后一个数据类型 “有序集合类型”,回首之前学过的几个数据结构,不知道你会不会由衷感叹,开源的世界真好,写这 些代码的好心人真的要一生平安哈,不管我们想没想的到的东西,在这个 ...
- [Effective JavaScript 笔记]第46条:使用数组而不要使用字典来存储有序集合
对象属性无序性 js对象是一个无序属性集合. var obj={}; obj.a=10; obj.b=30; 属性a和属性b并没有谁前谁后之说.for...in循环,先输出哪个属性都有可能.获取和设置 ...
- redis数据类型-有序集合
有序集合类型 在集合类型的基础上有序集合类型为集合中的每个元素都关联了一个分数,这使得我们不仅可以完成插入.删除和判断元素是否存在等集合类型支持的操作,还能够获得分数最高(或最低)的前N个元素.获得指 ...
- 高可用Redis(四):列表,集合与有序集合
1.列表类型 1.1 列表数据结构 左边为key,是字符串类型 右边为value,是一个有序的队列,与python的列表结构相同 可以在Redis中对列表的value进行如下操作 从左边添加元素 从右 ...
随机推荐
- java关于Timer schedule执行定时任务 1、在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等
1.在应用开发中,经常需要一些周期性的操作,比如每5分钟执行某一操作等.对于这样的操作最方便.高效的实现方式就是使用java.util.Timer工具类. private java.util.Time ...
- 字符串匹配算法系列一:KMP算法原理
本文主要参考了https://mp.weixin.qq.com/s/rbaPmBejID8-rYui35Snrg的表述,加上部分自己的理解 学习任何算法都要了解该算法解决什么问题?我们看看KMP算法主 ...
- 纯CSS实现的很酷的卡通肖像和眨眼动效
产品设计技术趋势 当前产品设计和开发的一个主要技术趋势除了响应式外, 还有尽量使用CSS/HTML5技术替代图片,这样能够获得非常好的设计扩展性和页面訪问性能. CSS卡通实例 以下就是一个英国WEB ...
- 好工具MyEclise2016 CI下载
地址:http://pan.baidu.com/s/1gfBw9Ab 安装后,点开crack目录,按步骤走. 下面是我安装成功的画面.
- 记一个发HTML格式邮件的问题
很早做了一个自动发邮件的程序,前一向发现Notes升级后反而CSS样式都没有了. 起初不以为意,反正格式数据在,客户也没说啥,后来觉得这样的态度要不得,小洞不补,大洞吃苦. 于是查查资料,发现浏览器里 ...
- tomcat内存、连接数优化
1.检測系统能够设置的内存大小 java -Xmx1024M -version(当中1024表示检測内存能否够调整到这个数) 2.设置tomcat内存 在tomcat_home/bin/catalin ...
- 又一次认识java(九) ---- 内部类
注意注意!! ! 前排提示!!.本篇文章过长,最好收藏下来慢慢看.假设你之前对内部类不是非常熟悉,一次性看完,大概你会懵逼. . . 1. 内部类概述 一个类的定义放在还有一个类的内部,这个类就叫做内 ...
- java个人感想
java与c++相比,摒弃了c++的指针,把c++中的stl封装成一个库,而且改变了当中的某些方法,使用方法也产生了非常多不同,读者在编程过程中须要自己细细体会 个人觉得三大框架基于前端+领域逻辑+数 ...
- 两个栈来实现一个队列的C++代码
利用两个栈来实现一个队列, 这个问题非经常见. 最关键的是要有好的思路, 至于实现, 那是非常easy的事情了. 在本文中, 也想说说自己的思路, 可是. 我认为用代码来表述思路更符合我的习惯. 也 ...
- Bootstrp--一个导航面板切换的实用例子
<!--导航区开始--> <ul class="nav nav-tabs nav-stacked" role="tablist"> &l ...