前言
在数据结构中我们学的适合搜索查询的数据结构有二叉搜索树和哈希表,但是当二叉搜索树的高度比较深的时候,每一次的查询和比较都会产生磁盘IO;此时搜索的效率其实并不是很高。
而哈希表的时间复杂度确实可以达到O(1),但是只能查询一个值相等的比较,如果在数据库中进行一个模糊查询或者是范围查询,显然哈希表遮掩个的数据结构也是不合适的。
所以针对数据库的索引,采用的是特定的数据结构:B+ 树,是为数据库量身定做的数据结构,掌握B+树这个数据结构,先了解B+树的前身,B树(也称B-树(是B树,不是B减树))。
1.B树
本质就是一颗N叉搜索树。
了解B树,首先要了解二叉搜索树是啥,N叉搜索树就是在二叉搜索树的基础上,每个节点存放了多组key值,在查找搜索的时候就比二叉树高效了很多。
B树的优点:
相比较二叉搜索树,B树每个节点都存放了很多个key值,并且多了很多个叉(节点的子树多了),也就是说在同样多的key的个数下,B树的高度就比二叉搜索树的高度低了很多,树的高度很高就意味着搜索的效率很低,树的高度越高,在进行查询比较的时候访问磁盘的次数就越多。所以B树的优点很明显:提高了搜索效率。
如图:
2.B+树:
B+树就是数据库索引中的背后的数据结构,B+树就是为了数据库索引而量身定做的数据结构,B树就是在B树的基础上又做出改进,它也是一颗N叉搜索树。
如图:
上图就是B+树,相比较B树,它的根节点有一个最大值的范围,所以下面的子树中最大值没有超过这个20的。 每个key值都会保存在子节点中存在。
B+树的特点:
1. 一个节点可以存储N个key值,N个key值划分出N个区间。(B树是划分出了N+1个区间)。 |
2. 每个节点中的key值,都会在子节点中再次保存一次,(同时key值就是子节点中的最大值)。 |
3. B+树的叶子节点是首尾相连的,类似一个链表。 |
4. 叶子节点就是完整的数据集合,只在叶子节点中存储数据的每一行的数据。而对于非叶子节点,只是存储key值本身即可。 |
B+树的优势:
1. 当前的一个节点保存了很多个key值,最终的树的高度比较矮,查询的时候减少了IO(读写硬盘的次数)访问次数。 | 因为内存空间是有限的,如果数据库中每一行的数据都要保存在内存中不显示,所以每一行的数据是保存在硬盘上的。而非叶子节点只是保存了key值,此时占用的空间就是比较小的,所以此时就可以把key值保存在内存上一部分,当查询每一行的数据时,根据这个key值所分的范围就很小了,此时在去访问硬盘即可。 |
2. 所有的查询最终都会落到叶子节点上,(也就是说每一次查询数据的时候经过的IO访问次数都是一样的),会很稳定。 | 不会说像B树一样,这次查询的数据在搜索树的第3层,下一次在树的第30层,(稳定是很关键的,稳定能够让程序员对于程序的执行效率有一个更准确的评估)。(非叶子节点只是存储了key值(比如id号)不会存储每一行对应的数据)。 |
3. B+树的所有的叶子节点构成了一个类似链表的结构,此时方便进范围查询。 | 比如要查询id是7 到 15 的同学,只要在内存中找到阿这个id从然后访问磁盘直接从7这个id号遍历到15,中间结果就是所求的结果。 |
4. 非叶子节点 就可能在内存中(/缓存一部分),又进一步减少了IO访问次数。 | 由于每一行的数据都是在叶子节点上,而非叶子节点只是存储key的值,也就是说非叶子节点占用的空间是比较小的。 |