4.2 最主流的索引查找算法:B+树的诞生之路



上节的索引组织表,具体是使用什么索引算法,把数据给组织起来。

即,需要什么数据结构,便于搜索这条索引里的数值。

一、本章内容

介绍主流的索引查找算法,最终引出主角:B+树。

二、主流的索引查找算法

2.1 6个

  • 线性查找:Array数组、Linked List链表。从头开始,一个一个找。
  • 二分查找:可以视为线性查找的升级。即可以使用线性查找的数据结构,但是查找算法不一样
  • 二叉树:效率更高,但是存在平衡问题。
  • 平衡二叉树:解决了平衡问题。不足:以上所有四种,一个节点只能存放1个数据,磁盘利用率低。
  • B 树:一个节点只能存放不只一条数据。但是也存在平衡问题。
  • B+ 树:解决了上面的平衡问题。B+ 树,可以理解为B树、线性查找的结合。

2.2 线性查找 Linear Search

1.原理

本质:一个一个查找。

2.试验

优质网站,动图演示,演示原理:

Google浏览器: usfca,数据可视化,就能搜到以下大学(旧金山大学),创建的数据结构可视化平台:

一个框代表的是一行数据,显示出来的只是id。比如数据的主键是48,id是48.

线性查找,id为282的数据:从左开始,逐个比较:

2.3 二分查找 Binary Search

1.原理

虽然N很大,但是前面加个log,最终结果就会减小的非常小。

这样,就算你N数据量剧增,logN也不会增加太多。

上图来自:https://www.zhihu.com/tardis/landing/yidian/ans/148670878

不足:必须知道和获得这段数据的中点位置。但有时拿不到:比如磁盘随机读写时,一个表中的100万个id数据,并不是连续读写的,因为磁盘是碎片化的。

2.试验

因为上节的线性查找,效率低。所以,诞生了二分查找。

2.4 二叉树 Binary Tree

基于上节二分查找树的不足,所以又诞生了二叉树。

1.原理

  • 时间复杂度,跟二分查找一样。天然的被根节点分成了左右两个子树,前一半、后一半。即,满树,跟二分查找效率相同。
  • 缺陷:不平衡

    在如下试验部分:新增的数据,id越来越大时,会变成一个链表,即退化成线性查找O(N)。树的优势丧失。

2.试验

二叉树,搜索是从最上面的根节点开始的。

比如:查询id为10:

二叉树的不平衡的缺陷,导致退化为链表:

当插入的数据,越来越大时:

2.5 平衡二叉树 AVL Tree

1.原理

  • 能通过左旋、右旋,确保树永远平衡,不会让树的一边特别长,退化成链表

2.试验

分别插入id为1、2、3:

自动的左旋:

再插入id为4:

再插入id为5:

因为右子树特别长,所以左旋如下:

左旋的规律:

加上叶子节点,

如果是2个,没问题;

如果是3个,那么就左旋,把中间那个节点,提起来。

三、B 树

接下来,介绍B树、B+树是怎么诞生的。这是为后续介绍B+树应用在InnoDB存储引擎,做铺垫。

3.1 平衡二叉树的致命缺陷

平衡二叉树,各方面性能优良。为什么数据库没有用它作为索引的数据结构呢?

致命缺陷:1个节点,只能包含1条数据。

因为硬盘,都有一个最小读写单位。

比如:机械磁盘:最小是512B

SSD:最小是4K。

如果一般,数据库中普通的1条数据都很小。你存储的东西往往不足上述最小单位,要么你和别的数据凑一块,放进去;要么就只放小小的你。

这会导致前者更混乱复杂,不容易查找,后者浪费空间。

3.2 B Tree的定义

1.

基于不足,在平衡二叉树基础上,所以就诞生了一种新的数据结构:B Tree。

1个节点,能放多个数据。

好处:

  • 硬盘利用率高:可以把id为1-10的数据,全部放在1个节点上。这样就能占满硬盘的最小存储单位(实际是,成为最小单位的倍数)。
  • 一次就能存储多数据,能减小硬盘的读写频率。之前是1次读1行,现在是1次读10行。

B Tree中的B是什么意思?

B是发明人的姓,跟二叉树Binary Tree没有任何关系。

有人说这个B是平衡,我的理解不是。因为B Tree是在平衡二叉树 AVL Tree基础上进化而来,后者就已经是平衡的了。:)

3.3 B Tree的特点:AVL Tree+线性结构

  • 根节点有2条数据,有3个指针(下面的0003前面还有一个小数据结构,用于指向的)
  • 在节点内,是单链表,线性查找
  • 在节点外部,是树,是对数阶

原则:树的高度,能降低就降低。每个节点存放的数据,越多越好。

就算是SSD硬盘,其速度也是远低于内存的。

所以应该是从硬盘上把这个节点的所有数据全部取出来,放到内存,进行遍历。而不是直接在硬盘里,遍历去找。

3.4 B Tree的缺陷:范围操作效率低

范围操作,太麻烦,效率很低。

查找一段数据,5-9,即5、6、7、8、9,每次都要回根节点来查找:

数据库中有大量的范围查找:

  • 查找10岁-18岁之间的人
  • 查找身高在1.5m-1.6m之间的人

四、B+树

4.1 特点(B树+链表)

1.改进

(1)所有的数据,都集中放("落")在了最下面的叶子节点里

除了叶子,上面的都是索引(指针),提供寻找功能

(2)叶子节点之间,用箭头形成了链表

即线性表,可以保证范围查询时,效率极高

2.图示

比如,还是查找一段数据,5-9,即5、6、7、8、9,不用每次都要回根节点来查找,只需要通过线性遍历的方式就能快速找到后面的连续数据:

图:

五、小结

重点不是B+树的更新、删除等操作,而是B+树,这个新技术,是怎么发展而来的。

只有了解一个技术的前因后果,才能在以后的创新上有自己的见解。
  • 不只是InnoDB,MyISAM,PostgreSQL,或是NoSQL数据库,都是以B+树为基础的

很多时候,都会说从0到1的创新:其实,这很少。

大部分的创新,是1+1>2

B+ 树,就是典型的例子。因为结合了二叉树、B树、线性表,取其所长。

声明:Jerry's Blog|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - 4.2 最主流的索引查找算法:B+树的诞生之路


Follow excellence, and success will chase you.