当前位置: 首页 > news >正文

redis-zset数据类型的常见指令(sorted set)

当你想学zset数据类型的时候,说明你应该已经接触过list,set之类的数据类型,list是一个链表,且list中的元素是可以重复的,就像数组中的元素一致,但是set可以说是一个集合,并且set存的每一个元素都是唯一的,这就像我们学习过的set数据结构一样,可以是TreeSet,HashSet;

而我今天要说的是zset集合,set是无序的,zset是有序的,那zset是根据什么来排序的,在设计的时候就给zset的每一个元素member绑定了一个score分数,每一个member都有一个score,每一个score也都有一个member,可以通过member找到对应的score,也可以通过score找到对应的member,听起来像是key-value,但不是key-value,如果是key-value,通过key可以找到value,但是通过value,却不能找到key;

以上是一个抽象的概念,接下来用一张图来表示一下:

从上面这张图就可以看到每一个member都有一个score,可以理解成给这个member绑定一个score,表示这个member的某种属性的大小,联想到游戏的话可以说是一个玩家的战力等等,而且zset天生就是有序的,排序的依据是score,上面的图其实降序的,但是实际zset默认的排序是升序的;虽然member和score是成对出现的,但是终究member是主角,score只是辅助作用;这时候可能有人会有疑问,member不能重复,那score总可以重复的,是的,score是可以重复,那么既然排序依据是score,如果score一样,该如何排序的,总不能是根据先来后到的顺序,实际不是的,而且根据member字符的字典序来排序的;接下来就介绍一下如何使用zset吧;

1、zadd key [nx|xx] [gt|lt] [ch] [incr] score member [score member ....]

        我们可以来看一下官方文档对这个指令的介绍

如果是XX:只是更新已经存在的元素,不会添加新的元素,这个elements指的是member,也就是说如果member已经存在的话,我们就是去更新他的score,如果member不存在,也不会添加一个新的member-score;

如果是NX:只是添加新的元素,不会更新已经存在的元素;如果member不存在,就添加一个这个member-score,如果member存在,也不会更新他的score;

LT:只是更新已经存在的元素当这个新的score小于原来member的score;这个flag并不会阻止添加新的member-score;也就是这个指令只对已经存在的元素生效,如果元素不存在,这个LT并不会影响添加元素;

GT:只是更新已经存在的元素,当这个新的score大于原来member的score;这个flag并不会阻止添加新的member-score;也就是这个指令只对已经存在的元素生效,如果元素不存在,这个GT并不会影响添加元素;

如果这个指令不加上CH的话,返回值就是添加成功的member,因为有些member添加的时候肯定有些是已经存在的,所以返回值并不一定等于你添加的member-score的对数;CH(是change缩写)意思是加上ch就会改变指令的返回值的大小,会在原来的返回值的大小(添加成功的对数)的基础上加上socre被改变的个数,返回值的大小并不只是新添加的member的个数;

最后一个选择项:incr,其实值适用于只有一个score member的时候,会原来的score的基础上机上socre,作为该member新的元素;

2、zadd key incr value member

        给member的score加上value,value可以是小数,可以是负数,返回就是改变后的score 

3、zcard key

        返回key的member-score的对数,时间复杂度是O(1),原因是有一个变量存的就是key的member-score的对数;

4、zcount key mix max

        返回score在[mix,max]的个数,时间复杂度是O(logN),这个个数是如何得出来的呢?辉县根据mix去找到member的下标,再根据max去找到member的下标,根据两个下标就可以得到个数;

值得一提的是,我们可以给min或者max加上一个(),用来把区间变成开区间,如果要去掉min,在min前加上一个( ,也就是zcount key ( min max,区间就变成了(min,max];有趣的是如果你要去掉max,就不是在max后面加上一个),而且是在max前加上一个( ,也就zcount key (min (max;我们都说一个语法如果要让人容易学的话,就要符合直观的感受,但是显然这个就有点让人难以接受,但是一想又还好,加上( 就是开区间嘛;

5、zrange key start end [withscores]

        只是就是去查下标是start到end的member,并返回member,如果加上withscores,就会把member的score也一起返回;为什么说是下标的呢?因为我们知道zset其实是有顺序的,是会按照score排序的,所以redis也会他们一个下标,作为排名,可以理解是排名的

6、 zrevrange key start end [withscores]

        这个指令的作用实际和zrange一致,只是range是按照升序的返回,而zrevrange是按照升序返回的,仅此而且;

7、zrangebyscore key min max [withscores]

        相信从zrangebyscore可以看出来就是按照给的min,max作为分数范围去获取这个分数范围的member,甚至返回他的score;返回的顺序就是按照降序的顺序,也就是按照redis实现的zset默认的排序顺序;

8、zpopmax key [count]

        这个指令指查找key中的score最大的count个member,删除之后并且返回member以及score,如果有指定count,那就是删除count个,如果没有,就是默认删除并返回一个;

9、bzpopmax key [key ...] timeout

        这个指令是带有阻塞等待功能的删除并返回最大的socre的元素,timeout就是等待的时间,整数的话就是秒,如果是小数,那就表示毫秒;他可以一次性的监听一个甚至多个key,如果监听的多个key都没有元素,就会一直等待,直到有一个key中有member,就停止等待,并且立即删除这个元素,并且返回member以及score;

既然有出队的最大的元素,那就有出队最小的元素的指令,比如zpopmin,以及带有阻塞功能的bzpopmin,用法以及功能跟zpopmax,bzpopmax一致;

10、zrank key member

        rank是排名的意思,这个指令就是去获取member的排名,下标,根据默认的升序,最小的0;

11、zrevrank key member

        这个指令就是按照降序的方式去获取member的下标,也及时排名,如果他是最大的,返回的就是0,以此类推;

12、zscore key member

        这个指令就是去获取member的score,获取member的score,时间复杂度是O(logN),但是redis在实现的时候就考虑到这个点会被频繁使用,所以就针对这个指令进行优化,牺牲空间复杂度来提高时间复杂度,时间复杂度达到了O(1);

13、zrem key member [member]

        可以一次性的删除一个或者多个member,返回成功删除的个数,时间复杂度就是O(logN*M),M指的是删除的个数,logN是查找并删除一个的时间复杂度;

14、zremrangebyrank key start end

        这个是根据排名的范围去删除member,下标可以是负数,也可以是超越长度的数,redis并不是你的排名给你的不合法而报错,而是会尽可能的正确的处理你给的排名;

15、zincrby key value member

        这个指令主要是对member对应的score进行加减操作,如果value是正数,那就是加操作,如果是负数,那就是减操作,返回值就是加减后的socre;并且支持双精度浮点数,可以加减小数;如果操作的member不存在,那就会以value和member去创建一个新的member score这样一个pair;

16、ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE <SUM | MIN | MAX>]

注意zinter,zunion,zdiff这个命令是从redis6.2才开始有的,而zinterstore等这几个是从redis5就支持的,zinterstore是求交集,是将结果保存到另一个key中;zunionstore是求交集,是将结果保存到另一个key中;zdiffstore是求交集,是将结果保存到另一个key中;接下来就主要讲一个zinterstore,其他两个指令的用法是一致的,就不做赘述;

交集,并集,差集计算都会产生一个结果,destination就是用存这个结果集的zset;

numkeys是一个整数,用来表示有几个zset参与交集运算,也就是后面跟的key的个数,很多人可能有疑问,为什么要有这样一个整数来表示呢?难不成是因为有多个key吗?但是我们前面所学到的指令也有相当多是有多个key参与运算的,为什么其他的就不用有numkeys这样一个整数来表示呢?关于这个问题,redis官方也是做出了解释:

他是这么说的:要强制提供一个numkeys在多个输入的key和其他参数之前;实际目的就是为了知道到底有多少个key参与运算,有这个numkeys就不会把后面的其他参数当做key参与运算,虽然后面的参数不一定有,但是一但有就会而且没有这个numkeys就会出错,所以一定要加上这个numkeys;其实说到这里,大家可能会联想到两个知识点,一个是http协议的content-length,这个用来记录的是正文的长度,http协议主要分为四个部分,首行、请求头(键值对)、空行、正文,如果没有content-length正确记录正文的长度,那就看会出现“粘包问题”;http协议是使用tcp协议的进行传输的,从http3.0开始才开始使用udp协议进行传输,而tcp协议就是使用字节流进行传输的,所以只要是使用字节流这样的IO方式进行传输的,就一定会出现“粘包问题”,所以一定要有方法去避免这样的问题;

weights在这里的意思是:权重,用途就是“综合考虑”,就是说一个元素是重要的,但是相比较其他的元素就没有那么重要的,所以重要的我们就给更大的权重值,比较不重要的就给一个不那么大的权重值;这里参与运算的集合都是有序集合,特殊的就是每一个member都有一个score,这里的权重就相当与一个系数,每一个score都会乘上这个系数,来参与运算;

AGGREGATE <SUM | MIN | MAX>:经过权重计算之后,每一个key都会有一个不同的score,比如求的是交集,那么两个key都会有一个相同的member,可能member的score就不一样,那我们要如何决定要用那个score来当做要存入的key的score呢?如果是sum,那就是表示两个key的score相加当做存入的key的score,如果是min,那就是用最小的score,如果是max,那就是用比较大的score,这里还是比较好理解的;

这么说的话还是比较抽象的,可能会觉得很难,但是实际并不难,接下来就真正的结合例子来说明一下

先使用一个最简单的指令来看一下效果:zinterstore key3  2 key1 key2

可以看到求交集后的key的score是他们的score的和,也就说如果不指定AGGREGATE,那就是默认sum;

接下来我们加上权重参数,并指定要min(可以是小数)

key1的所有socre都乘上2,key2的所有socre都乘上3,难免key1的score就是20,40,60,key2的score就是45,75,90,又要求取小的,所以结果就是20,40,60;

结合以上的两个例子,相信已经理解这个指令所有参数的意思了;

这个指令的时间复杂度是:O(N*K)+O(M+logM),N指的是最短的zset的长度,K是参与运算的zset的个数,M指的是要结果集的个数;

http://www.dtcms.com/a/442427.html

相关文章:

  • 触摸未来2025.10.04:当神经网络拥有了内在记忆……
  • 生成对抗网络(GANs)深度解析:从原理、变体到前沿应用
  • 项目1:get_rga_thread线程和low_camera_venc_thread线程获取低分辨率VENC码流数据
  • 哪个网站做简历好musik wordpress视频
  • 【Linux】Linux管道与进程池深度解析:从原理到实战
  • Kotlin 协程之 Flow 操作符大全
  • python高级01——linux基础命令
  • 发帖那个网站好 做装修的怎么优化关键词排名优化
  • 分类信息网站建设价格西安公司注册网站
  • 数据要素X_第三批“数据要素×”典型案例——科技创新领域【附全文阅读】
  • 安装nginx时,yum 不从stable源安装
  • ui做标注的网站平面设计素材怎么找
  • 向量数据库的几个核心概念
  • 设计方案的步骤seo学习网站
  • 常熟网站制作设计长沙房产
  • 【OpenCV】图像处理入门:从基础到实战技巧
  • 站群系统破解版急切网头像在线制作图片
  • 快速排序的深入优化探讨
  • HTTP~
  • AI-调查研究-94-具身智能 机器人算法真机验证全流程解析:测试平台、部署方案与接口对接
  • leetcode 37 解数独
  • 105、23种设计模式之策略模式(14/23)
  • BLE 蓝牙连接参数详解
  • 手机版做我女朋友网站域名申请时间需要多久
  • 【ROS2学习笔记】URDF 机器人建模
  • 哈尔滨多语言网站建设jsp源码做网站
  • 【Linux学习笔记】线程概念和控制(三)
  • 第2集:技术选型的智慧:Flask vs FastAPI,GLM-4 vs GPT
  • 做pc端网站行业现状网站 建设设计方案
  • 【c++】初识STL和string类