首页 > 数据库 >redis原理之底层数据结构-跳表

redis原理之底层数据结构-跳表

时间:2024-07-23 23:26:36浏览次数:10  
标签:存储 元素 redis 链表 跳表 数据结构 节点

1.什么是跳表

1.1 链表及其不足

链表是在程序设计中最常见的数据结构之一,它通过指针将多个链表节点连接起来,这样就可以将逻辑上同一类的数据存储到不连续的内存空间上。链表结构如下:

但是链表有一个问题,就是当链表需要查询一个元素的时候,需要从链表头部开始遍历,时间复杂度为o(n)。

2.1 跳表的诞生

针对查询链表的时间复杂度为o(n)的问题,我们可以学习B+树,给链表加上索引,采用二分查找的思想查找元素。但是二分查找是有一个前提,就是要求元素是有序的,所以我们在插入元素的时候,维护好节点的顺序。

如果元素过多,我们还可以给目录增加目录:

所以跳表由如下几部分组成。

头节点

层级:每个节点可以增加多个节点,这个曾经在跳表中一般是随机增加的,主要是为了增加搜索的速度,最多可以有32个层级。

尾节点:一般是空

所以跳表在查找元素target的时候,首先从最高层目录开始遍历,找到第一个大于target的元素e,证明target元素一定在e的左边。

2.redis对跳表的实现

redis中跳表定义的结构如下:

typedef struct zskiplistNode {
    //跳表存储的元素
    sds ele;
    //跳表存储的分数
    double score;
    //指向上一个节点的前向指针,方便从后向前遍历
    struct zskiplistNode *backward;
    //后向指针,是一个包含0-32的指针数组
    struct zskiplistLevel {
        //后向指针
        struct zskiplistNode *forward;
        //跨度
        unsigned long span;
    } level[];
} zskiplistNode;

typedef struct zskiplist {
    //跳表头节点
    struct zskiplistNode *header, *tail;
    //跳表的节点个数
    unsigned long length;
    //跳表的最大等级为多少
    int level;
} zskiplist;

可以看出redis为了结局自身结构的问题,增加了以下两个特性:

1.redis为了解决从尾部遍历元素的需求,所以在调表的节点之间加上了一个后向指针。
2.为了解决查询某个元素rank的需求,在不同层级节点之间维护了跨度。

所以redis的跳表结构如下

3.红黑树、跳表、B+树的区别以及使用场景

3.1 红黑树

红黑树,查询时间为o(logn)在插入元素的时候,需要通过自旋或者染色等操作来维持树结构的平衡,所以插入的时候相对耗时,并且插入元素可能影响的节点比较多。java中Map的为了解决hash冲突以及linux中对epoll的实现采用了红黑树。

3.2 B+树

B+树,紧凑,适合磁盘存储。b+树相当于一个节点拥有多个子节点,每个节点能够存储多个键值对。在查询数据的时候,能够减少磁盘随机IO的次数。但是b+树插入数据的时候,
需要进行页分裂等操作,所以插入相对耗时。mysql的底层就采用B+树存储。

3.3 跳表

跳表,适合内存存储。跳表的目录层级可能很高,但是查询也是o(log(n))的时间复杂度,而且跳表插入速度快,适合内存存储。这也是为什么redis选择跳表存储的原因。

标签:存储,元素,redis,链表,跳表,数据结构,节点
From: https://blog.csdn.net/zhifou123456/article/details/140576738

相关文章

  • 《Java初阶数据结构》----3.<线性表---LinkedList与链表>
    目录前言一、链表的简介1.1链表的概念1.2链表的八种结构 重点掌握两种1.3单链表的常见方法三、单链表的模拟实现四、LinkedList的模拟实现(双链表)4.1 什么是LinkedList4.2LinkedList的使用五、ArrayList和LinkedList的区别 前言   大家好,我目前在学习......
  • redis的使用场景和持久化方式
    redis的使用场景热点数据的缓存。热点:频繁读取的数据。限时任务的操作:短信验证码。完成session共享的问题完成分布式锁。redis的持久化方式什么是持久化:把内存中的数据存储到磁盘的过程,同时也可以把磁盘中的数据加载到内存中。redis持久化分为两种:RDB和AOFRDB:什......
  • redis的集群模式
    为什么使用redis提高并发性和可用性提供了三种集群模式:第一种:主从模式概念:redis主从模式表示一个主节点跟若干个从节点。主节点负责读和写操作,而从节点只负责读操作,主节点的数据会自动同步到从节点上。如何搭建操作模式结构图为了操作方便可以在一台Linux上运行......
  • Redis(REmote DIctionary Server)基础
    Redis(REmoteDIctionaryServer)基础Redis是一个开放源代码(BSD许可)的内存数据结构存储,用作数据库、缓存和消息代理。它支持字符串、哈希、列表、集合、带范围查询的排序集合、位图、超日志、带半径查询和流的地理空间索引等数据结构。Redis具有内置的复制、Lua脚本、LRU收回、......
  • Spring Boot 如何引入redis并实际运用
    1.增加依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>2.程序入口初始化Beanimportorg.springframework.w......
  • 数据结构----队列中的链式队列
     目录 链式队列       1.1逻辑结构:线性结构       1.2存储结构:链式存储      1.3链式队列的操作:                        (1)创建一个空的队列                (2)入列     ......
  • Redis-10大数据类型理解与测试
    Redis10大数据类型我要打10个1.redis字符串(String)2.redis列表(List)3.redis哈希表(Hash)4.redis集合(Set)5.redis有序集合(ZSet)6redis地理空间(GEO)7.redis基数统计(HyperLogLog)8.redis位图(bitmap)9.redis位域(bitfield)10.redis流(Stream)官网地址Redis键(key)常......
  • [转]从SQLite到Redis:探索C++与多种数据库的交互之道
    转自:【C++风云录】从SQLite到Redis:探索C++与多种数据库的交互之道开启数据库之旅:通过C++与各种数据库交互,事半功倍1.SQLite1.1简介SQLite是一个嵌入式关系型数据库管理系统,提供了一个轻量级的C++接口。它是一个开源的软件库,无需配置服务器或安装管理工具,可以直接在程序中使......
  • 从零开始学数据结构系列之第四章《prim算法(普里姆算法)总代码》
    文章目录回顾初始化寻找最小权值算法主体总代码往期回顾回顾我们用这张图来进行算法讲解初始化/**vex-存储顶点*weight-存储权值*/typedefstructEdge{charvex;intweight;}Edge;/**开辟数组大小得空间,大小具体为vexNum的个数*......
  • Redis常见面试题汇总
    1.Redis中的底层数据结构String(字符串、整数或浮点数):String是Redis最基本的数据类型,一个key对应一个value,value的最大值为512MString类型是二进制安全的(原理在2),意味着redis可以包含任何数据,如图片、视频(可以转换为二进制编码)和序列化对象List(列表):redis列表是简单的字符......