0

0

redis数据结构知识图文详解

WBOY

WBOY

发布时间:2022-04-01 13:31:13

|

3494人浏览过

|

来源于CSDN

转载

本篇文章给大家带来了关于redis的相关知识,其中主要介绍了关于数据结构的相关问题,包括了字符串、列表、哈希、有序集合等等相关内容,希望对大家有帮助。

redis数据结构知识图文详解

推荐学习:Redis学习教程

redis的数据结构:String(字符串)、List(列表)、hash(哈希)、Set(集合)、Shorted Set(有序集合)

底层数据结构:简单动态字符串、双向链表、压缩列表、哈希表、跳表、整数数组
在这里插入图片描述
1.哈希表:一个哈希表其实就是一个数组,数组中的每一个元素称为一个哈希桶。在这里插入图片描述
哈希冲突和rehash可能会带来操作阻塞。
redis解决哈希冲突的方法是链式哈希,而rehash是增加现有hash桶的数量。
在这里插入图片描述
rehash的操作步骤:1.给哈希表分配更大的空间,例如是当前hash表大小的两倍
2.把哈希表1中的数据重新映射并拷贝到hash表2上
3.释放哈希表1的空间
第二步涉及大量数据拷贝操作,如果一次性把哈希表1中的数据都迁移完,会造成线程阻塞,无法服务其他请求。为了避免这一问题,redis采用渐进式rehash
在这里插入图片描述
整数数组和双向链表的复杂度都是O(N)
压缩列表在表头有三个数据分别是列表长度、列表尾的偏移量和列表中entry个数
压缩列表在表尾还有一个元素zlend代表列表结束在这里插入图片描述
跳表:有序链表只能逐一查找元素,而跳表在链表的基础上增加了多级索引,通过索引位置的几次跳转实现数据的快速定位在这里插入图片描述
以下五种结构的时间复杂度
在这里插入图片描述

String类型

String类型并不适用于所有场景,它有一个明显的短板就是它在保存数据时所消耗的内存空间较多。因为String类型需要额外内存空间记录数据长度、空间使用等信息,这些信息也叫做元数据。
当保存的数据包含字符的时候,string会用简单动态字符串SDS结构体来保存
在这里插入图片描述
len是buf已用长度 alloc是buf实际分配长度
因为redis数据类型有很多,不同的数据类型有相同的元数据要记录,所以redis会用一个RedisObject结构体来统一记录这些元数据
在这里插入图片描述
当保存Long类型的时候,RedisObject的指针就直接赋值为整数数据了,这样就不用额外的指针再指向整数了,节省了指针的空间开销。
如果保存的字符串小于44字节,sds和元数据会被分配到一块连续的内存区域,被称为embstr编码
如果保存的字符串大于44字节,SDS和元数据会分开存放,被称为raw编码

在这里插入图片描述
另外redis会使用一个全局hash表保存所有键值对,hash表的每一项都是一个dictEntry的结构体,用来指向一个键值对,可以看到key+value+next会使用24字节,但是实际占用32字节,这是因为jemalloc 在分配内存时,会根据我们申请的字节数 N,找一个比 N 大,但是最接近 N 的 2 的幂次数作为分配的空间,这样可以减少频繁分配的次数。
在这里插入图片描述
用什么数据结构可以节省内存呢?
压缩列表:zlbytes代表列表长度,zltail代表列表尾偏移量,zllen代表列表中的entry个数,zlend代表列表结束,perv_len代表前一个entry长度,encoding代表编码方式,len代表自身长度,key是实际存储的数据。redis基于压缩列表实现了list、hash和Sorted Set

在这里插入图片描述
如何用集合类型保存单值的键值对?
在保存单值的键值对的时候,可以采用Hash的二级编码,就是把单值的数值拆分成两部分,前一部分作为Hash的key,后一部分作为Hash的value

以图片 ID 1101000060 和图片存储对象 ID 3302000080 为例,我们可以把图片 ID 的前 7 位(1101000)作为 Hash 类型的键,把图片 ID 的最后 3 位(060)和图片存储对象 ID 分别作为 Hash 类型值中的 key 和 value。127.0.0.1:6379> info memory# Memoryused_memory:1039120127.0.0.1:6379> hset 1101000 060 3302000080(integer) 1127.0.0.1:6379> info memory# Memoryused_memory:1039136

Hash类型有两种底层实现结构:1.压缩列表 2.Hash表
hash列表存在两个阀值,一旦超过这两个阀值就会从压缩列表转换为Hash表
hash-max-ziplist-entries表示用压缩列表保存时哈希列表集合中最大元素个数
hash-max-ziplist-value表示用压缩列表保存时哈希集合单个元素的最大长度

凡人网络购物系统jsp版(JspShop)
凡人网络购物系统jsp版(JspShop)

基于jsp+javabean+access(mysql)三层结构的动态购物网站,v1.2包含v1.0中未公开的数据库连接 的java源文件 一,网站前台功能: 产品二级分类展示:一级分类--二级分类--产品列表--详细介绍(名称,图片,市场价,会员价,是否推荐,功能介绍等) 产品搜索:关键字模糊搜索 定购产品:选择商品--确认定购--填写收货人信息--选择付款方式--订单号自动生成(限登录用户)

下载

集合统计模式
1.聚合统计
2.排序统计
3.二值状态统计
4.基数统计

redis的三种扩展数据类型

1.Bitmap:
2.HyperLogLog
3.GEO:
面向LBS应用的GEO数据类型
GEO的底层结构是根据Sorted Set来实现的,Sorted Set可以根据元素的权重排序,支持范围查询在这里插入图片描述
sorted Set的权重分数是一个浮点数(float类型),而经纬度是两个数,需要用GeoHash 编码
GeoHash编码是通过“二分区间,区间编码”的方式进行的。
先把经度和纬度换算成编码的格式,然后再进行交叉
在这里插入图片描述
实际上交叉的目的是下图所示的概念,交叉后实际上就可以定位到二维空间上的一个方格中,我们使用 Sorted Set 范围查询得到的相近编码值,在实际的地理空间上,也是相邻的方格,例如1110011101和1111011101是空间位置相邻的
在这里插入图片描述
但是会存在编码相邻,但是方格实际不相邻的情况。所以为了避免这种情况发生我们可以同时查询给定经纬度周围4个或者8个方格在这里插入图片描述

如何操作GEO类型?
在使用GEO类型时,我们经常使用到的两个命令分别时GEOADD和GEORADIUS
GEOADD:用于把一组经纬度信息和相对应的一个ID记录到GEO类型集合中。
使用方法:假设车辆ID是33,经纬度位置是(116.034579,39.030452),我们可以用一个 GEO 集合保存所有车辆的经纬度,集合 key 是 cars:locations。只需要执行以下命令就可以把ID号为33的车辆的当前经纬度位置存入到GEO中。

GEOADD cars:locations 116.034579 39.030452 33

GEORADIUS:根据输入经纬度的位置,查询以这个经纬度为中心一定范围内的其他元素

如何自定义数据类型?

redis的基本对象结构包含type、encoding、lru和refcount、*ptr
在这里插入图片描述
开发一个名字叫NewTypeObject的数据结构,具体有以下四个步骤在这里插入图片描述

如何在redis中保存时间序列数据?

1.基于Hash和Sorted Set保存:为什么要基于两种数据结构进行查询呢?
Hash类型可以实现单键的快速查询,这就满足了时间序列单键查询需求在这里插入图片描述
但是hash类型有一个短板就是不支持范围查询,为了支持时间戳范围查询我们需要通过Sorted Set,因为它根据元素的权重分数来排序的,在这里插入图片描述
那么我们怎么保证这两个操作的原子性呢?
需要通过MULTI和EXEC两个命令:
MULTI表示开始,收到这个命令redis就会将命令放入到队列中
EXEC表示结束,收到这个命令就会开始执行队列中的命令在这里插入图片描述
但是如果采用hash和Sorted Set则只支持范围查询而不支持聚合计算。如果在客户端做聚合计算,会导致大量的网络传输。所以可以在redis上通过RedisTimeSeries进行聚合计算。

推荐学习:Redis学习教程

相关专题

更多
数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

298

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

216

2025.10.31

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

313

2023.08.02

css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

554

2024.04.28

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

95

2025.10.23

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

252

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

206

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1437

2023.10.24

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

177

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
进程与SOCKET
进程与SOCKET

共6课时 | 0.3万人学习

Redis+MySQL数据库面试教程
Redis+MySQL数据库面试教程

共72课时 | 6.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号