当前位置:网站首页>请说下redis命令的时间复杂度??(实际问的是redis底层结构)
请说下redis命令的时间复杂度??(实际问的是redis底层结构)
2022-06-29 15:01:00 【码农编程进阶笔记】
redis本身是开源的C语言编写的k-v存储系统,他支持String、List、Set、ZSet、hash五种数据结构,每种数据结构底层是如何实现的?其数据结构为什么?
1. String
1.1 结论
底层结构:指针+字符数组时间复杂度:O(1)
1.2 表格
1.3 底层原理
Redis是C语言开发的,但在C语言中并没有字符串类型,只能使用指针和字符数组的形式来保存一个字符串。所以Redis设计了一个简单的动态字符串(SDS [Simple Dynamic String])来作为底层实现。
struct sdshdr{
//记录buf数组中已使用的字节的长度
int len;
//记录buf数组中剩余空间的长度
int free;
//字节数组,用于存储字符串
char buf[];
}- 获取字符串长度的时间复杂的为O(1),因为len保存的是当前字符串长度。
- SDS会自动进行扩容,SDS拼接之后,若此时len小于1MB,则会多分配与len相同的未使用空间,使用free表示;若ken大于1MB,则会多分配1MB空间。
- 惰性释放,当字符串进行缩短之后,程序不会立即回收空间,而是记录在free中,以便后序拼接的使用。
2. LIST
2.1 结论
底层结构:双向链表时间复杂度:查询效率为O(n)。但是访问两端元素的时间复杂度O(1)
lRange时间复杂度O(n);lpop时间复杂度O(1);lpush key value1 value2 value3... valueN从list的左边添加一个或者多个元素 时间复杂度O(1~n);
2.2 表格
2.3 底层原理
底层结构:quicklist
一个链表结构可以有序的存储多个字符串,拥有例如:lpush、lpop、rush、rpop等操作。在3.2版本之前,列表使用ziplist和linkedlist来实现。而在3.2版本之后,重新引入了一个quicklist的数据结构,列表的底层是由quicklist实现的,它结合了ziplist和linkedlist的优点。按照原文的解释是:【A doubly linked list of ziplist】。存。
在老版本中,当列表对象同时满足一下两个条件时,列表将使用ziplist编码:
- 列表对象保存的所有字符串元素长度都小于64字节;
- 列表对象保存的元素数量小于512个;
当有一个条件不满足时将进行一次转码,使用linkedlist。
ziplist
ziplist是一个经过特殊编码的双向链表,它设计的目的是为了提高存储的效率。一个普通的双向链表,链表中每一项都占用独立的一块内存,各项之间用地址指针(或引用)连接起来,但是这种方式会造成大量的内存碎片,而且地址指针也会占用额外的内存。
ziplist却是将表中每一项存放在前后连续的地址空间内,一个ziplist整体占用一大块内存。它是一个表(list),但其实不是一个链表(linked list)
- ziplist作用:节省内存;
- ziplist特点:数据存放在前后连续的地址空间内;
linkedlist
双向列表,插入和删除的效率高,但是查询的效率确实O(n)
quicklist
【A doubly linked list of ziplist】ziplist组成的双向链表。它宏观上就是一个链表结构,只不过每一个节点都是以ziplist来存储数据,而ziplist中又包含多个entry。也可以说quicklist节点保存的是一片数据
- 整体上quicklist是一个双向链表结构,和普通的链表操作一样,它的插入删除效率高,但是查询效率确实O(n),不过,这样链表访问两端的元素的时间复杂度都是O(1),故对list操作多数都是poll和push。
- 每个quicklist节点就是一个ziplist,具有压缩列表的特性。
在redis.conf配置文件中,有两个参数可以优化:
- list-max-ziplist-size表示每个quicklist节点的字节大小,默认为-2,表示8kb。
- list-compress-depth:表示quicklist节点是否要压缩,0表示永不压缩。
3.HASH
3.1 结论
底层结构:ziplist或者hashtable时间复杂度:O(1)
3.2 表格
3.3 原理
redis的散列可以存储多个键值对之间的映射。hash底层的数据结构实现其实有两种:
- 一种是ziplist(将键与值都压入链表中),当存储的数据超过配置的阈值时就会转化为hashtable结构,这种转换比较耗费时间,我们应该尽量避免这种转化操作,同时满足一下两个条件时才会使用这种结构:
- 当键的个数小于hash-max-ziplist-entries(默认512)
- 当所有值都小于hash-max-ziplist-value (默认64)
- 另一种就是hashtable,这种结构的时间复杂度为O(1),但是会消耗比较多的内存空间。
4. SET
4.1 结论
底层结构:整数集合(intset)或者字典(hashtable)时间复杂度:O(1)
4.2 表格
4.3 原理
typedef struct intset{
//编码方式
uint32_t encoding;
//元素数量
uint32_t length;
//存储元素的数组
int8_t contents[];
}整数集合中的每个元素都是contents数组的一个数组项,各个项在数组中按值的大小进行有序排列,并且不包含重复的项。contents数组中的元素类型由encoding决定,没当加入新元素时,如果元素的编码大于contents数组元素的编码,则数组元素会整体升级,注意不会发生降级。
5. ZSET
底层结构:ziplist或者skiplist(跳表)时间复杂度:O(log(n))
5.1 什么是跳表
力扣——1206. 设计跳表
跳表设计思路和链表相似,跳表中有很多层,每一层是一个短的链表。在第一层的作用下,增删查的时间复杂度不超过O(n)。跳表的每一个操作平均时间复杂度为 O(log(n)),空间复杂度是 O(n)。
跳跃表是一种有序的数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的。跳表的期望空间复杂度为O(n)O(n),跳表的查询,插入和删除操作的期望时间复杂度都为O(logn)O(logn)。
Redis内部数据结构详解之跳跃表(skiplist)
跳表是一种随机化数据结构,基于并联的链表。
5.2 常用命令时间复杂度
边栏推荐
猜你喜欢

三角函数对应在平面坐标上画圆

Lumiprobe 活性染料丨氨基染料:花青5胺

CKS CKA CKAD 将终端更改为远程桌面

What should phpcms do when it sends an upgrade request to the official website when it opens the background home page?

MCS: discrete random variables - geometric distribution

使用自定义注解实现Redis分布式锁

Solution to the problem that the assembly drawing cannot be recognized after the storage position of SolidWorks part drawing is changed

const用法精讲

MCS: discrete random variable - binomial distribution

Unity C# 基础复习27——委托示例(P448)
随机推荐
Draw a slash on a plane coordinate
Lumiprobe 活性染料丨杂染料:BDP FL 神经酰胺
Const usage
Informatics Olympiad all in one 2061: trapezoidal area
MCS: discrete random variable Poisson distribution
CKS CKA CKAD 将终端更改为远程桌面
极化SAR地表分类
bash汇总线上日志
打造一个 API 快速开发平台,牛逼!
华为软件测试笔试真题之变态逻辑推理题【二】华为爆火面试题
Jet hydrogen technology rushes to the scientific innovation board: SAIC Group is the major shareholder to raise 1.06 billion yuan
ROS notes (10) - Launch file startup
深度学习遥感数据集
真正的软件测试人员 =“半个产品+半个开发”?
使用自定义注解实现Redis分布式锁
在shop工程中,实现一个菜单(增删改查)
MCS:多元随机变量——多项式分布
高分三号卫星(GF-3)简介
For example, the visual appeal of the live broadcast of NBA Finals can be seen like this?
第九章 APP项目测试(4) 测试工具