16zset相关操作

蓝风9 蓝风9     2022-12-24     429

关键词:

前言

相关介绍主要围绕着如下的一些常用的命令, 来看看 zset 相关操作的具体 api 

如下常用的命令来自于我们常见的教程 : https://www.runoob.com/redis/redis-sorted-sets.html 

本文的相关代码 拷贝自 redis-6.2.0  

代码来自于 https://redis.io/ 
 

数据结构

当 zset 中的元素数量小于等于 zset_max_ziplist_entries(默认为 128), 并且每一个元素长度都小于等于 zset_max_ziplist_value(默认为 64) 的时候, 是基于 ziplist 来存储数据 

否则是基于 skiplist 来存储数据 

ZADD key score1 member1 [score2 member2]

这里可以看出的是 参数的数量要求大于等于 4 个, 可以传递 多个 score, member 对  

我们来看一下 zaddCommand 

搜显示 校验客户端输入的 options, 存储到 flags 里面, 接着 从 flags 中提取上下文所需要的标记到标记变量 

校验 score, member 是否是成对出现, 各个 flag 是否存在冲突的标记 

解析各个 score 数组, 确保格式正确 

如果 zset 不存在, 则创建给定的 zset, 并初始化到 db->dict 里面 

然后循环 score, member 对, 循环添加 score -> member 

返回给客户端 添加的元素的数量 

zset 中添加元素的具体的方式 

如果是 ziplist 的编码方式, 查询 ele 在 zset 中是否存在, 如果存在, 判断当前 score 和 newscore 是否满足 lt/gt 约束[确保 newscore 小于/大于 score], 先从 ziplist 中删除已有的 ele, score, 在新增 ele, newscore[新增元素按照score排序] 

    如果 zset 中不存在 ele, 则新增 ele, newscore 到 zset 里面 [新增元素按照score排序]  

如果是 skiplist 的编码方式, 直接基于 skiplist 的 api 来进行操作 

最终客户端这边展示的结果如下, zset 不存在, 符合 ziplist 的条件, 创建了基于一个 ziplist 的 zset, 最终添加了 三个元素 

ZCARD key - 执行 zcard zset

这里可以看出的是 参数的数量要求等于 2 个 

我们来看一下 zcardCommand 

获取 key 对应的 entry, 确保类型为 zset 

返回 value 中存储的元素的数量 

zsetLength 的具体实现如下, 获取的是 zset 里面的 score, member对 的数量 

最终客户端这边展示的结果如下, zset 中存在 [(60 -> chinese), (70 -> match), (80 -> english)], 总共是三个元素 

ZCOUNT key min max - 执行 zcount zset 60 70 

这里可以看出的是 参数的数量要求等于 4 个 

我们来看一下 zcountCommand 

获取 key 对应的 entry, 确保类型为 zset 

获取 min, max, 并确保类型正确 

如果是以 ziplist 编码, 找到第一个在 range 的元素, 如果没有 返回 0, 否则迭代元素 直到不再 range, 返回元素的数量 

如果是以 skiplist 编码, 找到第一个在 range 的元素, 如果没有 返回 0, 否则迭代元素 直到不再 range, 返回元素的数量 

最终客户端这边展示的结果如下, zset 中存在 [(60 -> chinese), (70 -> match), (80 -> english)], score 在 [60, 70] 区间的元素总共有两个 

ZINCRBY key increment member - 执行 zincry zset 20 chinese

这里可以看出的是 参数的数量要求等于 4 个 

zincrbyCommand 的实现是基于 zaddGenericCommand 来实现的, 请参见上面的 zadd 

最终客户端这边展示的结果如下, zset 中存在 [(60 -> chinese), (70 -> match), (80 -> english)], 我们给 chinese 增加了 20, chinese 的 score 为 80, 这里返回的即为 newscore 

ZINTERSTORE destination numkyes key [key] 

暂时先放在这里 

ZUNIONSTORE destinations numkeys key [key]

暂时先放在这里 

ZLEXCOUNT key min max - 执行 zlexcount zset [c [e

这里可以看出的是 参数的数量要求等于 4 个 

我们来看一下 zlexcountCommand 

获取 key 对应的 entry, 确保类型为 zset 

获取 min, max, 并确保类型正确 

不管编码是 ziplist, skiplist 找到 min 所在的元素, 然后向后迭代 直到走出 (min, max) 区间[闭, 包取决于客户输入], 统计元素的数量 

注意 : 所有的 member 正序的情况下才有意义[规范上面限定的是 所有的 score 都相同的场景] 

zlexcount 文档上面的限定, 在所有的元素的 score 都相同的情况下使用, 查询语义上 在 min, max 区间的元素数量 

最终客户端这边展示的结果如下, zset 中存在 [(80 -> chinese), (70 -> match), (80 -> english)]

我们给 match 增加了 10, match 的 score 为 80 

此时 我们的几个元素 score 均相同, (socre, memeber) 默认是按照 member 字典序来进行的排序 

此时统计 大于等于 'c', 小于等于 'e' 的元素只有 "chinese" 一个 

此时统计 大于等于 'c', 小于等于 'f' 的元素只有 "chinese", "english" 两个 

ZRANGE key start stop [WITHSCORES] - 执行 zrange zset 60 70 

这里可以看出的是 参数的数量要求大于等于 4 个 

zrange, zrangeByLex, zrangeByScore, zRevRange, zRevRangeByLex, zRevRangeByScore 都是差不多, 这里只介绍一个 

我们来看一下 zrangeCommand 

解析参数 offset, limit, byScore, byLex, rev, withScores 等等 

根据 byRank/byScore/byOffset 分别将 min, max 解析到 (opt_start, opt_end), range, lexRange 里面 

获取 key 对应的 entry, 确保类型为 zset 

根据 byRank/byScore/byOffset 各自不同的实现来不同的处理 

byRank 的处理方式如下 

无论是 ziplist, 还是 skiplist, 其处理方式都是 现根据 start 获取第一个元素, 然后迭代 (end-start+1) 个元素 

byScore 的处理方式如下

无论是 ziplist, 还是 skiplist, 其处理方式都是 找到区间的第一个元素, 然后向前/后迭代直到迭代出 range 

byLex 和 byScore 实现方式类似, 这里不再赘述 

仅仅在 member 正序排列的时候有意义 

最终客户端这边展示的结果如下, zset 中存在 [(60 -> chinese), (70 -> match), (80 -> english)] 

然后 score 在 60, 70 区间的元素有 chinese, match 两个元素 

ZRANK key member - 执行 zrank zset match 

这里可以看出的是 参数的数量要求等于 3 个 

zrank, zrevrank 都是差不多, 这里只介绍一个 

我们来看一下 zrankCommand 

获取给定的元素的 排名 

无论是 ziplist 还是 quicklist, 来寻找 rank 都很简单 

最终客户端这边展示的结果如下, zset 中存在 [(60 -> chinese), (70 -> match), (80 -> english)], 我们查询的 match 顺序上来说是 第二位 

ZREM key member1 [member2] - 执行 zrem zset match 

这里可以看出的是 参数的数量要求大于等于 3 个 

我们来看一下 zremCommand 

获取 key 对应的 entry, 确保类型为 zset 

遍历 memberList 逐个删除 member, 如果最终集合元素删除光了, 移除 key 对应的 entry 

如果删除了 member, 更新 dirty, 发送 更新通知 

返回给客户端 删除的 member 的数量 

最终客户端这边展示的结果如下, zset 中存在 [(60 -> chinese), (70 -> match), (80 -> english)], 我们删除了 match, 服务端返回的是删除元素的数量, 删除了一个元素 

ZREMRANGEBYSCORE key min max - 执行 zremrangebyscore zset 0 30

这里可以看出的是 参数的数量要求等于 4 个 

zremrangebyscore, zremrangebylex, zremrangebyrank 都是差不多, 这里只介绍一个 

我们来看一下 zremRangeByScoreCommand 

和上面 zcount 的实现差不多, 首先是确认类型, 解析参数, 根据 byRank/byScore/byOffset 分别将 min, max 解析到 (start, end), range, lexRange 里面 

然后根据 range 来移除元素 

如果删除了元素, 更新 dirty, 发送 更新通知 

返回给客户端 删除的 member 的数量 

最终客户端这边展示的结果如下, zset 中存在 [(60 -> chinese), (80 -> english)], 我们删除的区间是 [0, 30] 不会删除任何元素 

ZSCORE key member - 执行 zscore zset chinese 

这里可以看出的是 参数的数量要求等于 3 个 

我们来看一下 zscoreCommand 

获取 key 对应的 entry, 确保类型为 zset 

根据元素 获取 score 

根据元素获取 score 

根据 ziplist, skiplist 不同的方式查询 member 对应的 entry 

填充对应的 score 到接受的对象上 

最终客户端这边展示的结果如下, zset 中存在 [(60 -> chinese), (80 -> english)], chinese 对应的 score 为 60 

ZSCAN key cursor [MATCH pattern] [COUNT count] - 执行 zscan zset 0 COUNT 1

这里可以看出的是 参数的数量要求大于等于 3 个 

zscan 这里同样是使用的 scanGenericCommand 

这的迭代类似于 11 key 相关操作 

不过对于这里编码为 ziplist 的情况 COUNT 这两个选项是没用的[这是一个很细的细节] 

迭代的是 zset 里面的所有的元素  

如果编码是 skiplist, zscan 是基于维护的一个额外的 dict 来进行 scan 的[这也是一个很细的细节] 

redisredis有序集合zset操作(简介|查询操作|增加操作|删除操作|修改操作)(代码片段)

文章目录一、有序集合Zset二、查询操作1、查询Zset所有数据2、查询Zset所有数据和评分3、查询指定评分范围的Zset数据4、查询指定评分范围的Zset数据并从大到小排序5、统计指定评分范围的Zset数据个数6、查询指定元素在Zset有序... 查看详情

zset类型以及其操作

sortedset类型sortedsets类型以及其操作zset是set的一格升级版本,它在set的基础上增加了一格顺序属性,这一属性在添加元素的同时可以指定,每次指定后,zset会自动重新按照新的值调整顺序。可以理解为有两列的mysql表,一列存储v... 查看详情

java操作redis(代码片段)

...Redis1环境准备1.1.引入依赖1.2.创建jedis对象1.3.事务2操作key相关API3操作String相关API4操作List相关API5操作Set的相关API6操作ZSet相关API7操作Hash相关API使用Java来操作Redis,Jedis是Redis官方推荐使用的Java连接redis的客户端。1环境准备1.1... 查看详情

redis数据结构操作相关命令(代码片段)

文章目录Redis数据结构操作相关命令Redis服务器相关命令keys查看字符串(string)操作命令列表(list)操作命令哈希(hash)操作命令集合(set)操作命令有序集合(zset)操作命令Redis数据结构操作相关命令redis提供5种string字符串list列表set集合zse... 查看详情

redis的数据类型及相关操作命令

redis基础内容——redis的数据类型及相关操作的Linux命令。所谓大厦千层基础承载,希望大家认真学习这一讲:一、redis的五大数据类型:1、String(字符串);2、List(列表);3、Set(集合);4、Hash(哈希,类似于Java里的M... 查看详情

redis使用bitmap、zset、hash、list等结构完成骚操作?

...set个数是否满足条件,若满足条件则触发报警;注意点:相关API:Redis实现延迟队列方法介绍基于Redis实现DelayQueue延迟队列设计方案相关API:SpringBoot2.x—使用Redis的bitmap实现布隆过滤器(Guava中BF算法)布隆过滤器:是专门用来检... 查看详情

zset

如何获取一个学生排行榜?要用到2个关键词 zrangebyscore(升序排列)   zrevrangebyscore(倒序排列)下面我们给定一个分数范围来升序或者倒序得到一个排行榜.192.168.1.175:6377>zrangebyscoretestset801501)"aaa"2)"bbb"3)"ccc"4)"ddd"5)"eee"19... 查看详情

redisredis有序集合zset操作(zset有序集合数据结构|普通链表|跳跃表)

文章目录一、Zset有序集合数据结构二、跳跃表1、普通链表2、跳跃表一、Zset有序集合数据结构有序集合Zset的底层数据结构类似于Java的Map数据结构Map<String,Double>,Zset中的元素是Map集合中的键;元素关联的评分是Map集合中的值,Zs... 查看详情

七天玩转redis|day5java操作redis(代码片段)

...准备2.1、引入依赖2.2、创建jedis对象3、常用API3.1、操作key相关API3.2、操作String相关API3.3、操作List相关API3.4、操作Set的相关API3.5、操作ZSet相关API3.6、操作Hash相关API1、Redis的Java客户端Redis的Java客户端也有很多:https://redis.io/clients# 查看详情

2018.9.16redis边学习边总结

...型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持 查看详情

powerpivotpowerbi相关组件下载安装(附操作截图)

加载方式:com加载项加载方法:点击Excel界面【文件】→【选项】→【加载项】→【COM加载项】→【转到】     Excel2013加载PowerViewExcel216PowerQuery不需要加载,在数据标签下: 16加载完成界面 PowerPivot说明... 查看详情

redis数据类型—zset(代码片段)

...有序集合叫做zsets,这是因为在redis中,有序集合相关的操作指令都是以z开头的)命令赋值语法:ZADDkeyscore1member1[score2member2]:向有序集合添加一个或多个成员,或者更新已存在成员的分数取值语法:ZCARDkey:... 查看详情

redis(07)-zset实现简单限流

...只需要保证它是唯一的就可以了。因为这几个连续的Redis操作都是针对同一个key的,使用pipeline可以显著提升Redis存取效率。但这种方案也有缺点,因为它要记录时间窗口内所有的行为记录,如果这个量很大,比如限定60s内操作不... 查看详情

redis--数据库常用命令大全(代码片段)

文章目录Redis特点Redis数据库相关指令1.数据库操作指令2.操作key相关指令3.String类型1.内存存储模型2.常用操作命令4.List类型1.内存存储模型2.常用操作指令5.Set类型1.内存存储模型2.常用命令6.ZSet类型1.内存模型2.常用命令7.hash类型1.... 查看详情

redisset类型和zset类型

...通过hshatable实现的,对集合可以进行取交集、并集、差集操作。1、sadd方法:插入元素,如:saddset1aaa:不允许元素重复。  smembersset1:查看元素;2、srem方法:删除set集合元素;3、spop方法:随机返回删除的key;4、sdiff方法:返... 查看详情

(3)zset实现延时队列(2)

...luascripting将zrangebyscore和zrem 挪到服务器端进行原子化操作https://blog.csdn.net/qpatience/article/details/90718133 查看详情

热搜排序实现——redis有序集合zset

...解析。完整方案,需要包括前端分词,排除停止词,挖掘相关的词后再进行热搜词的入库和搜索。RedisZincrby命令对有序集合中指定成员的分数加上增量increment当key不存在,或分数不是key的成员时,ZINCRBYkeyincrementmember等同于ZADDkeyi... 查看详情

linuxsocekt相关操作代码(代码片段)

内容来自于:https://www.nowcoder.com/courses/cover/live/504便于复习。1、字节序判断时候小端字节序还是大端字节序小端字节序:数字高位在内存高地址存放,低位在内存低地址存放大端字节序:与小端相反#include<stdio.h... 查看详情