前言:
大家好,我是良辰丫,数据库索引背后的数据结构是什么呢?我们学过索引的大多数人都知道是B+树,但是为什么使用B+树作为索引的数据结构呢
?这是一道常见的面试题,接下来我们就一起开启对索引背后的数据结构的探索.
个人主页:良辰针不戳
所属专栏:数据库
励志语句:生活也许会让我们遍体鳞伤,但最终这些伤口会成为我们一辈子的财富。
期待大家三连,关注,点赞,收藏。
作者能力有限,可能也会出错,欢迎大家指正。
愿与君为伴,共探Java汪洋大海。
首先我们要明白,索引是为了加快查找速率.然而呢?数据存储在磁盘中,但从磁盘读取数据会有大量的IO操作,因此呢?这样的效率是非常低的,因此,我们需要减少对IO的访问次数.
有那么多的数据结构,为什么偏偏选择了B+树呢?是数据库创始人对B+树眼缘好嘛,显然呢,B+树肯定有他们其它数据结构没有的优点/font>
哈希表大致结构图如下.
- 使用哈希表的目的是尽可能的散列,因此要使用一定的哈希算法来避免哈希冲突.
- 哈希表存储的数据是无序的,当需要进行范围查找的时候,只能一个个遍历,效率非常低.
比如普通二叉树,二叉搜索树,AVL树,红黑树等树,最多只能有两个分支,随着数据的增加,树的高度越来越高,查找数据的效率也会越来越低,因此不适合作为索引.
B树也叫B-树(而不是B减数哦),B数可以认为是一颗N叉搜索树,我们先来简单看一下B树的结构图.
当节点中B树的子树多了,节点保存key就多了(数据就多了),这就意味着与二叉树相比,B树比二叉树的高度低很多.树的高度越高,访问磁盘的次数就越多,效率就越低.
简单分析一下B树的特点.
- 把每个节点分区间,p分成了左右两个区别.
- p的左区间又根据C,G,L分为四个区间.
- 每一个节点都存着数据,比如查找数据Q,Q在P右边的区间,我们就要在P的右边查找,Q的值又在T的左边,所以我们从T的左区间进行查找.
- 因此,比起,二叉树,B树极大的提高了查找效率.
B+树又在B树的基础上做了改进
B+树的特点 :
主要:整棵树的所有数据都包含在叶子节点上.
- 一个节点,可以存储N个key,N个key划分出了N个区间.
- 每个节点的key的值都会在子节点中也存在,同时该key是子节点的最大值.
- B+树的叶子节点,是是首尾相连,类似于一个链表.
- 由于叶子节点是完整的数据集合,所以叶子节点存放所有的数据,非叶子节点,只存key值本身.
- 当前一个节点保存更多的key,最终树的高度是相对更矮的,查询的时候减少了IO的访问(特指对硬盘的访问)速度(这里的特点和B树是一样的).
- 所有的查询结果最终都会落到叶子节点上(查询任何一个数据,经过IO访问次数是一样的).这个稳定是很关键的,能让程序员对执行效率有一个更准确的评估.
- B+树所有的叶子节点构成链表,此时比较方便的进行范围查找.例如,要查找某个范围,不用从上往下找所谓的数据,在叶子节点顺着单链表就可以找到所谓的范围,非常高效.
- 由于数据都在叶子节点上,非叶子节点只存储key,这样导致非叶子节点占用空间是比较小的,这些非叶子节点就可能在内存中缓存(或者是缓存的一部分),又进一步减少了IO的次数.
各种各样的树存放各种各样的数据,是通过数据的比较后存放的,数字,字符串,日期等信息都是可以进行比较的.
数据库中一张张的表是按照怎样的数据结构的方式组织的,具体是哪种结构,取决于你的表里没有索引.(暂不考虑)
若一个表id是主键索引,但是name属性又有一个索引.
- 此时表的结构还是按照id为主键,构建出B+树通过叶子节点组织所有的数据行.
- 针对name这一列,会构建另一个B+树,但是这个B+树的叶子节点就不再存储这一行的完整数据,而是存主键id是啥.
- 如果你根据name来查询,查到叶子节点得到的只是主键id,此时,还需要再通过主键id去主键的B+树里面再查一次 . 查了2次B+树.
(上述的过程称为"回表",用户自身感知不到)
后序:
这篇文章我们一起接触了一道常见的面试题,数据库索引背后的数据结构
,希望小小的文章可以帮到大家,此文的B+树我们重点去理解原理,我以后还会在数据结构的专栏里面用代码的方式更深刻的带大家去深入学习B+树,我们下一篇文章再见.