redis面试(四)ZSet数据结构

news2024/9/9 7:25:57

Sorted Set

有序集合ZSet,但是有序集合的英文明明是sorted sets。 那这个“Z”代表什么意思,这点官网没有解释,但是gitHub上有人问过,作者是这样回答的

Hello. Z is as in XYZ, so the idea is, sets with another dimension: the
order. It’s a far association… I know 😃

这句话的本意是:这里的Z就像XYZ中的Z一样,所以这个概念是,集合中还有另一个维度:顺序。这是一个遥远的关联…

在我理解来的话,这应该只是为了和原本的Sets集合做一个区分,Z代表的就是原本顺序之外的一个规则,就像XYZ中的Z一样,是二维平面之外,另一个维度的规则。

结构

在redis 7.0之前有两种编码:ziplist、skiplist
7.0之后是listpack、skiplist
主要区别就是ziplist和listpack

我们先来简单说一下两种格式:(如果了解跳表,可以直接跳转到 skiplist 看跳表的结构)

ziplist和listpack:都是一种压缩列表的实现,当保存的元素长度都小于64字节,同时数量小于128时,会使用该结构(可以认为就是有序列表 list )
与我们之前的理解list不同的地方是,他们占用的磁盘是连续的,没有节点之间的指针,而是将数据按照顺序一个个的排列。
那么查询的时候就要从第一个节点一个个的往后捋出来。虽然不会造成碎片空间,但这也是压缩列表的局限性。

ziplist

下面是这个ziplist列表的节点数据, 可以看到里面的属性 prevrawlensize,这个属性标记了前一个节点长度。

缺点就是 这个列表如果要更新第一个节点数据的话,可能会造成后面所有节点的长度数据全部更新。
(题外话:其实之前讲的redis的list结构中,每个节点Node里面都是一个ziplist,只不过我们只需要知道就可以了,在使用的时候不需要关心这些)

typedef struct zlentry {
    unsigned int prevrawlensize; /* 用于编码前一个节点字节长度*/
    unsigned int prevrawlen;     
    unsigned int lensize;        /* 用于编码此节点类型/长度的字节。
    								例如,字符串有1、2或5个字节标题。
    								整数总是使用一个字节。
    							*/
    unsigned int len;            /* 用于表示节点实际的字节。
									对于字符串,这只是字符串长度
									而对于整数,它是1、2、3、4、8或
									0,具体取决于数字范围。 
								*/
    unsigned int headersize;     /* prevrawlensize + lensize. */
    unsigned char encoding;      /* 设置为ZIP_STR_*或ZIP_INT_*,具体取决于节点编码。*/
    unsigned char *p;            /* 第一个节点的地址指针,prev-entry-len */
} zlentry;

listpack

listpack 列表最大的特点就是不再包含前一个节点的长度,那么在更新的时候就不会再造成连锁更新问题。
但是由于压缩列表本身的局限性,只能顺序查询,为了效率,在数据量超过64的时候,会变成跳表形式

typedef struct {
    /* 当使用string时,它具有长度(slen)。 */
    unsigned char *sval;
    uint32_t slen;
    /* 当使用integer时,“sval”为 NULL,lval 保存该值。*/
    long long lval;
} listpackEntry;

跳表zskiplist

跳表就是ZSets 有序列表的主要结构模式
skiplist 中也是包含两种结构,但是要注意,这里的两种结构是同时存在的 字典(dict)和跳跃表(zskiplist)存储方式。

dict就不说了,在上一章的Hash中说过,可以认为她就是一个k-v结构的数据。 里面的key是存储的数据,value是数据的score分数。
zskiplist:是一个具有跳跃节点能力的链表,给每个节点附加了一个level层级的属性,这个level会指向后面的 某一个节点,通过这个level层级可以直接越过中间的节点,减少查询的时间。
为了比较容易理解,这里画了一个示例图
在这里插入图片描述

L1、L2、L3… 这些就是每个节点的层级,规定了最高的层级是32层。 每个节点查询的时候,就可以通过高层直接跳跃到后面;
如果发现分数过大的话,可以通过低一些的层级少跳跃一些节点。

往里面放数据的时候,会给这个数据+分数封装为一个节点,然后给这个节点随机一个1~32范围内level的层高。
然后从头开始查询,通过level跳跃过N个节点,直接将节点放到对应的位置,然后给给每一层的level都添加一个指向下一个节点的指针。

具体实现结构如下:

typedef struct zskiplist {
	struct zskiplistNode *header, *tail;
	unsigned long length;
	int level;
} zskiplist;

typedef struct zskiplistNode {
	struct zskiplistLevel {
		struct zskiplistNode *forward;
		unsigned int span;
} level[];
struct zskiplistNode *backward;
double score;
robj *obj;
} zskiplistNode;

Sorted Set 为什么使用跳跃表,而不是红黑树?

主要有以下几个原因:

  • 跳表的性能和红黑树差不多。
  • 插入速度非常快速,因为不需要进行旋转等操作来维持平衡性
  • 跳表更容易实现和调试。

跳表中的dict是什么用处?

通过上面的数据结构不难发下,跳表只适合单位查询,排序处理。但是不适合查询分数,以及判断成员是否存在这种操作。
那么这时候dict就派上用场了,之前说过,dict的结构是key-value键值对。
比如我们的数据是 周杰伦 100分、孙燕姿 99分、许嵩 98分
那在跳表zskiplist 中的数据是
(level:[], score:100分, value:周杰伦)
(level:[], score:99分, value:孙燕姿)
(level:[], score:98分, value:许嵩)

而在字典项中的数据是
(key:周杰伦, score:100分)
(key:孙燕姿,value:99分)
(key:许嵩, value:98分)

要查询某个数据是否存在,或者是查询分数的话,直接从dict的数据结构中通过key来取出分数就可以了,不需要在列表中查询。
这也是一种为了效率,把数据冗余一份的策略

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1963372.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Selenium与WebDriver:Errno 8 Exec格式错误的多种解决方案

概述 在使用Selenium和WebDriver进行网页自动化时,可能会遇到各种错误。其中一个常见问题是执行格式错误(Errno 8 Exec format error)。这个错误通常在运行ChromeDriver时出现,错误提示涉及路径中的某个文件,如THIRD_…

WordPress建站教程:零基础新手小白如何B2B外贸建站

如果你想通过独立站拿询盘获取订单,那么必须先要有一个自己的网站,所以建站是你绕不过去的一件事。对于零基础的新手小白来说,如何从零开始搭建一个B2B外贸网站呢?本文将为你提供一份详细的WordPress建站教程,帮助你从…

NodeJS云观影应用系统-计算机毕业设计源码60580

摘 要 随着互联网与移动互联网迅速普及,网络上的电影娱乐信息数量相当庞大,人们对获取感兴趣的电影娱乐信息的需求越来越大,个性化的基于Vue框架实现云观影应用系统成为一个热门。然而电影信息的表示相当复杂,因此需要开发一个基于Vue框架实…

Navicat for MySQL 17 实现更明智的业务决策

5 月 12 日,Navicat 对现有产品进行了几项重大更新,包括 Navicat Premium、Navicat BI 和 Navicat Data Modeler。最受欢迎的 Navicat 工具之一,Navicat for MySQL,也得到了新的更新,获得了许多与 Navicat Premium 相同…

PostgreSQL——查询扫描介绍

顺序扫描 概述 顺序扫描(Sequential Scan)是PostgreSQL中一种基本的数据检索方式,它通过按顺序读取表中的所有页面来查找满足查询条件的记录。这种方式不依赖于索引,因此在某些情况下可能是唯一的选择,尤其是当表没有…

熵权法确定权重

熵权法(Entropy Weight Method, EWM)是一种在综合考虑各因素提供信息量基础上计算综合指标的数学方法,属于客观综合定权法,在确定权重时更有说服力。该方法主要根据各指标传递给决策者的信息量大小来确定权重。在信息论中&#xf…

AIGC diffusers文生图模型optimum量化使用案例

参考: https://github.com/huggingface/blog/blob/main/quanto-diffusers.md 安装 pip install optimum-quanto %pip install optimum使用 from optimum.quanto import freeze, qfloat8, quantize from diffusers import PixArtSigmaPipeline import torchpipeline = PixArt…

离线安装部署docker,内网离线安装部署docker,以及docker常用命令

1.下载docker的离线安装包 链接: https://pan.baidu.com/s/1beDBIYw-8IjJj5syGnHiZA 提取码: 8888 复制这段内容后打开百度网盘手机App,操作更方便哦 2.将二进制文件:docker-20.10.19.tgz 拖入服务器目录/home/admin/解压 tar -zxvf docker-20.10.19.…

喜讯 华焰天下荣获绿色低碳诚信企业、碳中和承诺示范单位、信用评价 AAA 级信用企业等系列证书

在推动可持续发展和构建诚信商业环境的道路上,华焰天下再次传来令人振奋的消息!近日,华焰天下凭借其在绿色低碳领域的卓越表现、坚定不移的碳中和承诺以及高度可靠的信用体系,成功荣获绿色低碳诚信企业、碳中和承诺示范单位、信用…

无人机技术已应用至地理测绘,Infortrend存储助力测绘数据

--高扩展保存海量无人机数据,高性能支持快速调取建模,数据安全也有免费的备份功能,实实在在好用的存储设备。

智能合约中approve函数详解

场景 这段时间很多小伙伴加我、都咨询到了一个类似的业务场景、 如下: 1、第一步业务里面调用授权函数approve 、给指定address2、第二步是由授权的address调用transferFrom转移给指定的接受地址。 案例DEMO如下(这里test2肯定是会执行失败的&#xff…

C语言典型例题19

《C程序设计教程(第四版)——谭浩强》 例题2.7 检查浮点型数据的舍去误差 C语言知识: 浮点数在C语言用有两个类型,有float和double类型,其中double类型的数据精度更高 解题思路: 可以将一个double类型的…

城市运管服平台:智慧城市的神经中枢

“城市运行管理服务平台”(简称“城市运管服平台”)作为现代城市治理的智慧核心,正以前所未有的方式重塑着城市管理与服务的面貌。本文旨在深度解析城市运管服平台的内涵、运作机制及其对推动智慧城市发展的重要意义。 城市运管服平台&#…

视频超压缩保持质量 ffmpeg

参考: https://x.com/mortenjust/status/1817991110544744764 基于 FFMpeg 的 H264 压缩标准,实现压缩 90% 的视频大小 在线体验地址: https://tools.rotato.app/compress ffmpeg命令执行 ffmpeg -i "C:\Users\loong\Downloads\屏幕录…

Vidu视频生成工具全球上线,注册即刻体验

生数科技,这家成立于2023年3月的年轻企业,其核心团队成员来自清华大学人工智能研究院。首席科学家朱军教授,曾在贝叶斯机器学习和多模态大模型领域取得多项原创性成果。Vidu的核心技术U-ViT架构,是全球首个将Diffusion与Transform…

# mongodb_基础到进阶 -- MongoDB 快速上手(四)

mongodb_基础到进阶 – MongoDB 快速上手(四) 一、MongoDB :文章评论 需求&表结构&技术选型 1、文章评论:需求分析 1)参考某头条的文章评论业务,文章示例参考:早晨空腹喝水&#xff…

功能强大的图片/pdf识别成文字的工具Umi-OCR

一、工具概述 操作系统:支持windows、Linux使用方法:图形化、命令行、http接口 二、功能特性 三、部署方式 1、windows 下载地址:Umi-OCR_文字识别工具 2、linux 推荐使用docker部署 》下载 Dockerfile mkdir Umi-OCR-Docker cd Umi-OC…

Overlay网络

Overlay 介绍 Overlay网络是将已有的物理网络(Underlay网络)作为基础,在其上建立叠加的逻辑网络,实现网络资源的虚拟化。 传统网络带来了以下一些问题: ● 虚拟机规模受 网络规格限制在传统二层网络环境下&#xff0…

某“新一线城市“前端面试,纯纯被恶心到了

一.起因 在boss上刷到的一个小小厂,收大四全年实习生(web前端),因为离家乡比较近,而且双非一本的学历以及入坑的时间没有太长(前端部分不到一年),想去那里看看形势,要求是笔试面试,当场给是否录用结果&…

WPS@文字文档插入的表格,对单元格填充底纹颜色时,有字的地方就填充不上 ,空白。

背景 在创建的WPS文字文档中,插入了一个表格,对表格的某些单元格需要填充底纹颜色 问题 问题如标题,“文字文档插入的表格,对单元格填充底纹颜色时,有字的地方就填充不上 ,空白”,直观如下图 解…