『SQL』拜托,别再问我什么是 B+ 树了( 二 )
2、链表
双向链表支持顺序查找和逆序查找 , 如图下
本文插图
但显然不支持我们说的按某个值或区间的快速查找 , 另外我们知道表中的数据是要不断增加的 , 索引也是要及时插入更新的 , 链表显然也不支持数据的快速插入 , 所以能否在链表的基础上改造一下 , 让它支持快速查找 , 更新 , 删除 。 有一种结构刚好能满足我们的需求 , 这里引入跳表的概念 。
什么是跳表?简单地说 , 跳表是在链表之上加上多层索引构成的 。 如下图所示
本文插图
假设我们现在要查找区间 7- 13 的记录 , 再也不用从头开始查找了 , 只要在上图中的二级索引开始找即可 , 遍历三次即可找到链表的区间位置 , 时间复杂度是 O(logn) , 非常快 , 这样看来 , 跳表是能满足我们的需求的 , 实际上它的结构已经和 B+ 树非常接近了 , 只不过 B+ 树是从平衡二叉查找树演化而来的而已 , 接下来我们一步步来看下如何将平衡二叉查找树改造成 B+ 树 。
先来看看什么是平衡二叉查找树 , 平衡二叉查找树具有如下性质:
- 若左子树不空 , 则左子树上所有节点的值均小于它的根节点的值;
- 若右子树不空 , 则右子树上所有节点的值均大于或等于它的根节点的值;
- 每个非叶子节点的左右子树的高度之差的绝对值(平衡因子)最多为1 。
本文插图
从其特性就可以看到平衡二叉查找树查找节点的时间复杂度是 O(log2n)
现在我们将其改造成 B+ 树
本文插图
可以看到主要区别就是所有的节点值都在最后叶节点上用双向链表连接在了一起 , 仔细和跳表对比一下, 是不是很像 , 现在如果我们要找15 ~ 27 这个区间的数只要先找到 15 这个节点(时间复杂度 logn = 3 次)再从前往后遍历直到 27 这个节点即可 , 即可找到这区间的节点 , 这样它完美地支持了我们提的三个需求:快速查找值 , 区间 , 顺序逆序查找 。
假设有 1 亿个节点 , 每个节点要查询多少次呢 , 显然最多为 log21亿 = 27 次 , 如果这 1 亿个节点都在内存里 , 那 27 次显然不是问题 , 可以说是非常快了 , 但一个新的问题出现了 , 这 1 亿个节点在内存大小是多少呢 , 我们简单算一下 , 假设每个节点 16 byte , 则 1 亿个节点大概要占用 1.5G 内存!对于内存这么宝贵的资源来说是非常可怕的空间消耗 , 这还只是一个索引 , 一般我们都会在表中定义多个索引 , 或者库中定义多张表 , 这样的话内存很快就爆满了!所以在内存中完全装载一个 B+ 树索引显然是有问题的 , 如何解决呢 。
推荐阅读
- ■面试官求你了,别再问我HTTPS
- @原创 别再看不起千元机,这4款好评度高过旗舰,最低仅999起!
- 【婷小姐】原创 别再看不起千元机,这4款好评度高过旗舰,最低仅999起!
- 『手机大魔王』别再被骗了,iphone6S真不卡,能再战5年?网友:自欺欺人罢了
- 【比特币】挖出来的币都值钱吗?别再浪费时间了
- 『即时战略游戏』别再说玩游戏浪费时间,国外研究玩游戏能锻炼视觉反应力
- 卡顿@手机卡顿影响使用,原因不过就是这3点,别再傻傻换新机了!
- 手机:别再说5G手机贵 备好3000元就能拥有它们
- 「」别再浪费时间修图了!一键出片它不香吗?
- [用户]90后上珍爱网玩线上相亲了?让爸妈别再蹲相亲角了!