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

redis五种数据类型对应的底层数据结构

redis五种数据类型对应的底层数据结构

  • redis的五种数据类型
  • redis核心对象redisObject
    • type数据类型
    • encoding编码类型
    • ptr指针
  • redis五种数据类型对应的底层数据结构
    • String字符串类型
      • SDS
    • hash哈希类型
      • ziplist压缩列表
      • hashtable哈希表
    • list列表类型
      • ziplist压缩列表
      • linkedlist、quicklist
    • set集合类型
      • intset整数集合
      • hashtable哈希表
    • zset有序集合类型
      • ziplist压缩列表
      • skiplist跳跃表

redis是一种非关系型key-value内存数据库。

redis的五种数据类型

字符串:string;
哈希(也叫哈希表、字典,下文中统一称为哈希。):hash;
列表:list;
集合:set;
有序集合:sorted set。
在这里插入图片描述
这里的数据类型是针对于value来说的,key全是字符串类型。

redis的这些数据类型在底层都是使用核心对象redisObject表示的。

redis核心对象redisObject

redisObject对象有以下属性:
type、encoding、ptr、其它信息。

type数据类型

对应的是value五种数据类型。
字符串:REDIS_STRING;
哈希:REDIS_HASH;
列表:REDIS_LIST;
集合:REDIS_SET;
有序集合:REDIS_ZSET。

encoding编码类型

表示的value保存的编码。
在这里插入图片描述
要注意type和encoding不是一一对应的,是组合!
在这里插入图片描述

ptr指针

指向了实际保存value的数据结构。
在这里插入图片描述

redis五种数据类型对应的底层数据结构

String字符串类型

String类型的编码方式,即encoding有三种:int、embstr、raw。
value的值是整数,encoding为int,没有对应底层数据结构;
value长度小于32,encoding为embstr,长度大于,32编码为raw,embstr和raw都使用SDS数据结构存储。
在这里插入图片描述

SDS

SDS是简单动态字符串simple dynamic string的缩写。
SDS有三个属性:

struct sdshdr{
	int len; // 字符串长度
	int free; // 未使用的字节长度
	char buf[]; // 保存字符串的字节数组
}

c语言中的结构体struct,类似Java中的类class。

redis是c语言实现的,
c语言中的字符串类型不会记录自身长度,获取长度要通过遍历得到,时间复杂度是O(n),需要n次,(最多)
SDS只需读取len属性,时间复杂度是O(1),也就是最多1次;
SDS在修改前会根据free属性判断空间是否满足,不满足就会扩容,避免内存溢出;
SDS提供’空间预分配’和’惰性空间释放’两种策略,在分配空间时,分配的空间比实际需要的多,
避免频繁增加字符串长度导致多次扩容带来的成本升高,
当字符串收缩的时候,不会立即回收不使用的空间,等以后使用时释放。
在这里插入图片描述

hash哈希类型

哈希类型的编码方式有ziplist、ht两种,分别对应ziplist和hashtable两种底层数据结构,
当哈希对象的键值对数量小于512,并且所有键值对的长度都小于64字节时,使用压缩列表ziplist,否则使用hashtable。

ziplist压缩列表

压缩列表并不是说以某种算法压缩存储数据,它是一组连续的内存块,能够节省空间。

压缩列表的内存结构:
zlbytes:4个字节大小,是压缩列表占用内存的字节数;
zltail:4个字节大小,记录表尾节点距离起始地址的偏移量,用于快速定位到尾节点地址;
zllen:2个字节大小,压缩列表中的节点数;
entry:列表中的每一个元素;
zlend:压缩列表的特殊结束符号’0xFF’。
在这里插入图片描述
一个entry节点包含以下三部分:
previous_entry_ength:记录前一个节点entry的长度,可用于计算前一个节点的起始地址,因为它们的地址是连续的;
encoding:content的内容类型和长度;
content:每个节点的内容。
在这里插入图片描述

hashtable哈希表

hashtable和java中的hashmap相似。

list列表类型

redis3.2之前,列表类型使用ziplist、linkedlist两种底层数据结构存储,
当列表的长度小于512,并且所有元素的长度都小于64时,使用ziplist,否则使用linkedlist。
redis3.2以后,则统一使用quicklist。

ziplist压缩列表

上边说过了。

linkedlist、quicklist

linkedlist、quicklist是个双向链表,双向链表中的每个节点,分别持有对前一个和后一个节点的引用prev、next,
头结点的prev引用、尾结点的next引用分别指向null。
在这里插入图片描述

set集合类型

集合类型使用intset、hashtable这两种底层数据结构存储,
如果集合中的所有元素都可以转换成整数值,且长度小于512,使用intset,否则用hashtable。

intset整数集合

整数集合中的元素有三个属性:
encoding:编码方式,有INTSET_ENC_INT16、INTSET_ENC_INT32、INTSET_ENC_INT64三种;
contents[]:元素内容;
length:元素内容长度。

整数集合中新增元素时,若是超出了长度,就会进行升级:
一、扩展数组contents的大小,并且数组的类型为新元素的类型;
二、将原来数组中的元素转为新元素的类型,并放到新的数组中;
三、整数集合在升级后就不会再降级,会一致保持升级后的状态。

hashtable哈希表

上边说过了。
有一点不同,
set中哈希表的value都是null,只用map的key实现集合。

zset有序集合类型

zset有序集合与集合相比,区别在于有序集合中的元素多了一个score属性,即排名的权重。
有序集合使用ziplist、skiplist这两种底层数据结构存储,
当集合长度小于128,并且所有的元素长度都小于64字节时,使用ziplist,否则使用skiplist。

ziplist压缩列表

上边说过了。

skiplist跳跃表

跳跃表是具有层次结构的链表。
它由很多层组成,每一层都是一个有序的链表,
由上到下每层节点数逐渐密集,最上层的节点最稀疏,跨度也最大,
下面这句话有点绕,但很重要:
每一层的每一个节点,都指向同一层下一位置的节点,和下一层同一位置的节点,
有点像mysql innodb的b+tree,支持范围查找,上层相当于索引层,下层是数据层,
bw是后退指针,在从下向上遍历的时候使用。
在这里插入图片描述

refs:
java技术爱好者:Redis的五种数据类型底层实现原理是什么
黎杜:最详细的Redis五种数据结构详解
溪午闻璐:Redis之跳跃表

相关文章:

  • Linux 必会基础语句 软硬连接区别 Linux文件类型
  • 【PAT甲级】1141 PAT Ranking of Institutions
  • JAVA基础(三十二)——反射之创建对象
  • java优秀毕业生推荐系统ssm
  • Group DETR
  • 设计模式 工厂方法模式
  • 自动控制原理7.3---z变换理论
  • 基于ISO14229协议的安全访问系列_1
  • 自动控制原理7.4---离散系统的数学模型
  • 【ELFK】之zookeeper
  • ALTERA FPGA IPCORE核之FIFO详细教程
  • 【ELK】日志分析系统概述及部署
  • MyBatis一对多查询,MyBatis中resultMap的使用,MyBatis中collection注意事项,MyBatis的级联搜索
  • STC15单片机-RS-485通信
  • 【JAVA-1】JDK、JRE安装及卸载,有手就会!
  • Java多线程(4):使用线程池执行定时任务
  • Node项目之评分系统(二)- 数据库设计
  • Spring Boot快速入门(一):Hello Spring Boot
  • WordPress 获取当前文章下的所有附件/获取指定ID文章的附件(图片、文件、视频)...
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 聚类分析——Kmeans
  • 开发基于以太坊智能合约的DApp
  • 力扣(LeetCode)56
  • 如何正确配置 Ubuntu 14.04 服务器?
  • 深入浏览器事件循环的本质
  • 实战:基于Spring Boot快速开发RESTful风格API接口
  • 主流的CSS水平和垂直居中技术大全
  • ​​​​​​​GitLab 之 GitLab-Runner 安装,配置与问题汇总
  • ​secrets --- 生成管理密码的安全随机数​
  • ​软考-高级-信息系统项目管理师教程 第四版【第19章-配置与变更管理-思维导图】​
  • ​香农与信息论三大定律
  • !!【OpenCV学习】计算两幅图像的重叠区域
  • !!java web学习笔记(一到五)
  • #laravel 通过手动安装依赖PHPExcel#
  • #我与Java虚拟机的故事#连载03:面试过的百度,滴滴,快手都问了这些问题
  • %3cli%3e连接html页面,html+canvas实现屏幕截取
  • (floyd+补集) poj 3275
  • (紀錄)[ASP.NET MVC][jQuery]-2 純手工打造屬於自己的 jQuery GridView (含完整程式碼下載)...
  • (一)Neo4j下载安装以及初次使用
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务
  • .NET BackgroundWorker
  • .Net CF下精确的计时器
  • .NET CLR基本术语
  • @Transactional类内部访问失效原因详解
  • @Transactional注解下,循环取序列的值,但得到的值都相同的问题
  • @Transient注解
  • [android] 请求码和结果码的作用
  • [BSGS算法]纯水斐波那契数列
  • [C++][数据结构][算法]单链式结构的深拷贝
  • [C和指针].(美)Kenneth.A.Reek(ED2000.COM)pdf
  • [hdu1561] The more, The Better 【树形DP】
  • [IE9] GPU硬件加速到底是实用创新还是噱头
  • [Linux] MySQL数据库之索引
  • [NISACTF 2022]level-up