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

六、Redis五种常用数据结构-zset

zsetRedis的有序集合数据类型,但是其和set一样是不能重复的。但是相比于set其又是有序的。set的每个数据都有一个double类型的分数,zset正是根据这个分数来进行数据间的排序从小到大。有序集合中的元素是唯一的,但是分数(score)是可以重复的。每个zset集合最多可以存放232-1个数据。zset常被用于排行榜功能。

1、常用命令

  • zadd key score1 member1 [score2 member2]:向有序集合中添加一个或多个数据,或者更新已存在成员的分数(member会先删除在重新插入)。
  • zcard key:获取集合的数据个数。
  • zcount key min max:计算集合中在指定分数区间内的数据个数。
  • zincrby key increment member:在集合指定成员的分数加上增量increment。increment为负数表示减去相应的值。
  • zinterstore destination numberkeys key [key…]:计算给定的一个或者多个集合的交集,并将结果存储到destination中。结果集中某个成员的分数是所有给定的集合该成员所有分数的和。
  • zlexcount key min max:在有序集合中计算指定字典区间内的成员数量。
  • zrange key start end[withscores]:通过索引区间返回指定区间内的成员。
  • zrangebylex key min max[limit offset count]:通过字典区间返回有序集合的成员。
  • zrangebyscore key min max[withscores][limit]:通过分数返回集合中的成员。
  • zrank key member:返回有序集合中指定成员的索引。
  • zrem key member [memeber…]:删除集合中一个或者多个成员。
  • zremrangebylex key min max:移出集合中指定字典区间内的所有成员。
  • zremrangebyrank key start stop:移出有序集合中给定的排名区间内的所有成员。
  • zrevrange key start end[withscores]:返回指定索引区间内的成员,分数从高到低。
  • zrevrangebyscore key max min[withscores]:返回集合中指定分数区间内的成员,分数从高到低。
  • zrevrank key member:返回集合中指定成员的排名。0表示最高。
  • zscore key member:返回集合中指定成员的分数。
  • zunionstore destination numberkeys key [key…]:计算给定的一个或者多个集合的并集,并存储在destination中。
  • zscan key cursor[match pattern][COUNT count]:迭代集合的元素。

2、底层实现

zset的底层实现有两种,ziplistdict+skiplist

2.1、ziplist

2.1.1、使用条件
  1. 集合中元素数量小于128个。
  2. 每个元素的长度小于64字节。

以上两个条件有任何一个不满足,就会使用dict+skiplist的结构存储数据。
每个集合元素使用紧挨着的两个压缩列表节点保存,第一个节点保存元素的成员,第二个保存元素的分数。
image.png

2.1.2、ziplist结构

见Hash中的ziplist

2.2、dict+skiplist

2.2.1、介绍
  • dict用来存储valuescore的映射关系,这样就可以在O(1)时间内找到对应valuescore值。
  • skiplist按照从小到大的顺序存储分数。
  • skiplist每个元素的值都是[score,value]对。
2.2.2、zset结构
typedf struct zset{//字典,键为value,值为scoredict* dict;//跳表,按分值进行排序zskiplist *zsl;
}zset;
typedf struct zskiplist{//头节点struct zskiplistNode *header;//尾节点struct zskiplistNode *tail;//跳表中的元素个数unsigned long length;//目前表内节点最高的层数int level;
}zskiplist;

zskiplist的示意图如下:
image.png

typedf struct zskiplistNode{//具体的数据sds ele;//分数double size;//后退指针struct zskiplistNode *backward;struct zskiplistLevel{//前进指针struct zskiplistNode *forward;/跨服unsigned int span;}level[]; //层数数组  最大32
}zskiplistNode;

skiplistNode的示意图如下:
image.png

2.2.3、skiplist-跳表

跳表skiplistRedis中的使用场景只有一个,那就是作为zset的底层结构实现。跳表可以保证增、删、查的时间复杂度为O(logN),其余一般的链表结构的时间复杂度为O(n)相比,性能上有不少的提升。但是唯一美中不足的是跳表需要占用更多的空间,其实这就是一种空间换时间的思想。跳表的结构如下:
image.png
Redis中的跳表的实现有点类似于Kafka中的稀疏索引。
Kafka中进行持久化的时候,会生成两个文件,一个是xxxxxx.log,一个是xxxxxx.index,其中log文件中以链表的方式保存着消息。而index文件中则保存着这些消息的索引,或者说是偏移量,但又不是每一条消息的索引都在index文件中。index中的索引是稀疏的,比如log文件中的索引是0-10000,那么index文件中存储的索引可能是100,500,700,1000,5000,6500,每个索引中都保存着对应log文件中消息的具体位置。如图:
image.png
当要访问899这个索引的消息时,先去index文件中查找,找到了700到1000的这个区间,根据700这个索引去log文件中找到700这个索引的消息,然后顺着700这个消息顺序往下找,直到找到899这个索引的消息。从这个实现中,我们看到Kafka并没有对log文件进行全部的遍历,而是先通过index中的稀疏索引,找到一个大概的位置,然后顺序遍历。
image.png
Redis的跳表的实现方式与上面的类似,不过Kafka的稀疏索引只有一层,而Redis的稀疏索引是多层。如图:
image.png
所有的元素都会在L0层的链表中,根据分数进行排序,同时会有一部分节点被抽取到L1层,作为一个稀疏索引,同样L1层的索引也有一定的机会被抽取到L2层,以此类推,Redis允许跳表中一个节点最高有**64层,**一个跳表中最多存储264 个元素。

2.2.4、跳表-增、删、查

首先假定有这么一个跳表,这里只展示分数:
image.png
如果要查找分数为66的元素,首先在L2层的索引查找。很明显。66位于25和85之间:
image.png
然后根据获得的区间,去对应的L1的区间查找,得到一个更精确的区间:
image.png
最终根据更精确的区间,去L0层顺序遍历,即可找到要查找的元素:
image.png
上述即是对跳表原理的一个描述。
这种跳表的实现,其实和二分查找的思路接近,只是一方面因为二分查找法只能适用与数组,而无法用于链表,所以为了让链表有二分查找类似的效率,就以空间换时间来达到目的。
跳表因为是一个根据分数权重进行排序的列表,可以在很多场景中使用,比如排行榜,搜索排序等。

相关文章:

六、Redis五种常用数据结构-zset

zset是Redis的有序集合数据类型,但是其和set一样是不能重复的。但是相比于set其又是有序的。set的每个数据都有一个double类型的分数,zset正是根据这个分数来进行数据间的排序从小到大。有序集合中的元素是唯一的,但是分数(score)是可以重复的…...

FPGA第一篇,FPGA现场可编程门阵列,从0开始掌握可编程硬件开发(FPGA入门指南)

简介:FPGA全称Field-Programmable Gate Array,是一种可编程逻辑器件,它通过可编程的逻辑单元和可编程的连接网络实现了灵活的硬件实现。与固定功能的集成电路(ASIC)相比,FPGA具有更高的灵活性和可重新配置性…...

C#实现简单音乐文件解析播放——Windows程序设计作业2

1. 作业内容 编写一个C#程序,要求实现常见音乐文件的播放功能,具体要求如下:     1). 播放MP3文件: 程序应能够读取MP3文件,并播放其中的音频。     2). 播放OGG文件: 应能够播放ogg文件。     …...

Python数据爬取超简单入门

## 什么是网络爬虫? 网络爬虫是一种自动浏览器程序,能够自动地从互联网获取数据。爬虫的主要任务是访问网页,分析网页内容,然后提取所需的信息。爬虫广泛应用于数据收集、数据分析、网页内容监控等领域。 ## 爬虫的基本步骤 1.…...

Dreamweaver 2021 for Mac 激活版:网页设计工具

在追求卓越的网页设计道路上,Dreamweaver 2021 for Mac无疑是您的梦幻之选。这款专为Mac用户打造的网页设计工具,集强大的功能与出色的用户体验于一身。 Dreamweaver 2021支持多种网页标准和技术,让您能够轻松创建符合现代网页设计的作品。其…...

【Git】Git学习-15:分支简介和基本操作

学习视频链接:【GeekHour】一小时Git教程_哔哩哔哩_bilibili​编辑https://www.bilibili.com/video/BV1HM411377j/?vd_source95dda35ac10d1ae6785cc7006f365780https://www.bilibili.com/video/BV1HM411377j/?vd_source95dda35ac10d1ae6785cc7006f365780 git bran…...

浏览器提示网站“不安全”原因及解决方法

是否经常会遇到访问的网站被浏览器提示访问不安全?那么,浏览器提示网站不安全通常有哪些原因又该如何处理这种不安全提醒,以下总结了几个原因及相应的处理办法: 一、网站管理者原因排查及处理办法: 1、网站没有部署S…...

Jmeter详细学习思路和教程

目录 1、JMeter环境准备 1.1、介绍 1.2、与LoadRunner比较 1.3、前提条件 1.4、安装配置 2、JMeter脚本 2.1、测试计划 2.2、线程组 2.3、Sampler 2.4、HTTP请求 2.5、查看结果树 2.6、HTTP Cookie管理器 2.7、HTTP信息头管理器 2.8、响应断言 2.9、参数化 3、JM…...

钉钉开放平台创建企业内部H5微应用或者小程序

前言: 在当今企业数字化转型的浪潮中,创建企业内部H5微应用或小程序已成为提升工作效率和促进内部沟通的重要举措。发话不多说本文将介绍如何利用钉钉平台快速创建这些应用,让企业内部的工作更加便捷高效。 步骤 1.在浏览器打开链接…...

Linux中每当执行‘mount’命令(或其他命令)时,自动激活执行脚本:输入密码,才可以执行mount

要实现这个功能,可以通过创建一个自定义的mount命令的包装器(wrapper)来完成。这个包装器脚本会首先提示用户输入密码,如果密码正确,则执行实际的mount命令。以下是创建这样一个包装器的步骤: 创建一个名为…...

【网络协议】----IPv6协议报文、地址分类

【网络协议】----IPv6协议简介 【网络协议】----IPv6协议简介IPv6特点IPv4 和 IPv6报文结构IPv6报文格式-拓展报头 IPv6地址分类IPv6地址表示IPv6单播地址可聚合全球单播地址链路本地地址唯一本地地址特殊地址补充 接口标识(主机位)生成方法通过EUI-64规…...

Llama改进之——SwiGLU激活函数

引言 今天介绍LLAMA模型引入的关于激活函数的改进——SwiGLU1,该激活函数取得了不错的效果,得到了广泛地应用。 SwiGLU是GLU的一种变体,其中包含了GLU和Swish激活函数。 GLU GLU(Gated Linear Units,门控线性单元)2引入了两个不同的线性层…...

在数据分析中所需要运用到的概率论知识

数据分析 前言一、总体二、样本三、统计抽样抽取的基本准则 四、随机抽样抽签法随机数法 五、分层抽样六、整群抽样七、系统抽样八、统计参数常用的分布函数参数 九、样本统计量十、样本均值和样本方差十一、描述样本集中位置的统计量样本均值样本中位数样本众数 十二、描述样本…...

韩顺平0基础学Java——第6天

p87-p109 运算符(第四章) 四种进制 二进制用0b或0B开头 十进制略 八进制用0开头 十六进制0x或0X开头,其中的A—F不区分大小写 10转2:将这个数不断除以2,直到商为0,然后把每步得到的余数倒过来&#…...

react18子组件设置接收默认值和值类型验证

父组件传值 import ChildCom from ./components/ChildCom export default function Person {return(<div><ChildCom name"alan-ben" age{18} score{[98, 97, 100]} /></div>) } 子组件接收并验证类型 import React from react import PropTypes…...

Java 高级面试问题及答案(二)

Java高级面试问题及答案 1. 在Java中&#xff0c;什么是强引用、软引用、弱引用和虚引用&#xff0c;它们有什么区别&#xff1f; 答案&#xff1a; 在Java中&#xff0c;引用类型决定了对象的生命周期&#xff0c;主要有以下四种&#xff1a; 强引用&#xff1a;最常见的引…...

数据统计:词频统计、词表生成、排序及计数、词云图生成

文章目录 &#x1f4da;输入及输出&#x1f4da;代码实现 &#x1f4da;输入及输出 输入&#xff1a;读取一个input.txt&#xff0c;其中包含单词及其对应的TED打卡号。 输出 output.txt&#xff1a;包含按频率降序排列的每个单词及其计数&#xff08;这里直接用于后续的词云…...

W801学习笔记二十四:NES模拟器游戏

之前已经实现了NES模拟器玩游戏。W801学习笔记九&#xff1a;HLK-W801制作学习机/NES游戏机(模拟器) 现在要在新版本掌机中移植过来。 1、把NES文件都拷贝到SD卡中。 这回不会受内存大小限制了。我这里拷贝了4个&#xff0c;还可以拷贝更多。 2、应用初始化中&#xff0c;加载…...

ECMAScript 6简介

ECMAScript 6简介 发布日期目标ECMAScript 和 JavaScript 的关系ES6 与 ECMAScript 2015 的关系 ESx标准 命名规则 ECMAScript 的历史 1. ECMAScript 6简介 1.1. 发布日期 ECMAScript 6.0&#xff08;以下简称 ES6&#xff09;是 JavaScript 语言的下一代标准&#xff0c;已…...

第1个数据库:编号,文本,时间,

写一个数据库 编号 文本 时间1 第一个文本 有100万条数据 -- 创建一个名为texts的表格来存储数据 CREATE TABLE texts ( id INTEGER PRIMARY KEY, text TEXT, time TIMESTAMP DEFAULT CURRENT_TIMESTAMP);-- 插入数据INSERT INTO texts (text) VALUES (第一个文…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例

一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时&#xff0c;你可能需要保留重要的数据&#xff0c;例如通讯录。好在&#xff0c;将通讯录从 iPhone 转移到 Android 手机非常简单&#xff0c;你可以从本文中学习 6 种可靠的方法&#xff0c;确保随时保持连接&#xff0c;不错过任何信息。 第 1…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...