mysql source skip_redis mysql 中的跳表(skip list) 查找树(btree)

跳表(skip list)数组和链表对比:数组支持随机访问,根据下标随机访问的时间复杂度是 O(1)数组的插入和删除操作效率不高,平均情况下的时间复杂度是 O(logN)链表随机访问性能没有数组好,平均情况下的时间复杂度是 O(logN)链表插入和删除操作只需要改变相邻节点的指针,时间复杂度是 O(1)二分查找底层依赖数组结构,跳表通过构建多级索引来提高查询效率,实现了基于链表结构的“二分查找”(...
摘要由CSDN通过智能技术生成

跳表(skip list)

27950a8a05da0471db139f42fb58fff6.png

数组和链表对比:

数组支持随机访问,根据下标随机访问的时间复杂度是 O(1)

数组的插入和删除操作效率不高,平均情况下的时间复杂度是 O(logN)

链表随机访问性能没有数组好,平均情况下的时间复杂度是 O(logN)

链表插入和删除操作只需要改变相邻节点的指针,时间复杂度是 O(1)

二分查找底层依赖数组结构,跳表通过构建多级索引来提高查询效率,实现了基于链表结构的“二分查找”(查找、删除、添加等操作都可以拥有对数时间复杂度)

跳表时间和空间复杂度:

查询操作的平均时间复杂度是 O(logN),最坏时间复杂度 O(N)

插入操作的平均时间复杂度是 O(logN),最坏时间复杂度 O(N)

删除操作的平均时间复杂度是 O(logN),最坏时间复杂度 O(N)

平均空间复杂度是 O(N),最坏空间复杂度 O(N logN)

跳表时间复杂度分析:

设原始链表有 N 个节点,每两个节点抽取一个节点作为上一级索引节点,这样第 k 层索引有 N/(2^k)个节点

设共有 h 级索引,最高一级索引有 2 个节点,结合上面的分析知道 N/2^h = 2,所以 h + 1 = log2(N)

加上原始链表这一层,整个跳表的高度是 log2(N)

查找某个数据时若每层需比较 m 个节点,总的时间复杂度是 log2(m*N),可简化为 O(logN)(m 是个常数)

跳表索引动态更新:

往跳表中插入数据时会选择性的将这个数据同步插入部分索引层中

由随机函数来确定需要插入哪些索引层级,这样在可以避免在插入大量数据后跳表查询性能退化

Redis 有序集合(Sorted Set)

Reids 有序集合支持的核心操作有:插入数据、查找数据、删除数据、根据 score 按照区间查找数据

Redis 有序集合的底层编码有两种实现,分别是 ziplist 和 skiplist,当有序集合的元素个数小于 zset-max-ziplist-entries 配置(默认128个),并且每个元素的值都小于 zset-max-ziplist-value 配置(默认64字节)时,Redis 会用 ziplist 来作为有序集合的内部实现,上述两个条件之一不满足时,Redis 启用 skiplist 作为有序集合的内部实现(转换过程是不可逆转,只能从小内存编码向大内存编码转换)

下面演示了先查看 redis 的默认配置,并演示了往 zset 中添加元素时由于元素大于 64 字节,Redis 内部存储结构由开始的 ziplist 转变为一个 dict 加一个 skiplist (dict 用来查询数据到分数的对应关系,而 skiplist 用来根据分数查询数据)

8f59fc0d75acc825f65dbe9d1d4fad9e.png

Redis 实现的跳跃表:

Redis 的跳跃表实现由 zskiplist 和 zskiplistNode 两个结构组成, 其中 zskiplist 用于保存跳跃表信息(比如表头节点、表尾节点、长度), 而 zskiplistNode 则用于表示跳跃表节点

每个跳跃表节点的层高都是 1 至 32 之间的随机数(程序根据幂定律生成,越大的数出现的概率越小)

在同一个跳跃表中,多个节点可以包含相同的分值,但每个节点的成员对象必须是唯一的

跳跃表中的节点按照分值大小进行排序, 当分值相同时, 节点按照成员对象的大小进行排序

原始链表层的每个节点有一个指向前继节点的指针,用于从表尾方向向表头方向迭代(当执行 ZREVRANGE 或 ZREVRANGEBYSCORE 等逆序处理有序集的命令时用到)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值