B-树
数据库索引为什么要使用树结构存储呢?
这个还不简单,树的查询效率高,而且可以保持有序。
既然这样,为什么索引没有使用二叉查找树来实现呢?
这就不明白了,明明二叉查找树时间复杂度是O(logN),性能已经足够高了,难道B树可以比它更快?
其实从算法逻辑来讲,二叉树查找树的查找速度和比较次数都是最小的,但是我们不得不考虑一个现实问题:磁盘IO ;数据索引是存储在磁盘上的,当数据量比较大的时候,索引的大小可能有几个G甚至更多。
当我们利用索引查询的时候,能把整个索引全部加载到内存吗?显然不可能。能做的只有逐一加载每个磁盘页,这里的磁盘页对应索引树的节点。
在二叉查找树里,磁盘的IO次数等于索引树的高度。
既然如此,为了减少磁盘的IO次数,我们就需要把原本“瘦高”的树结构变成“矮胖”,这是B-树的特征之一。
B-树是一种多路平衡查找树,它的每一个节点最多包含k个孩子,k被称为B树的阶。
k的大小取决于磁盘页的大小。
下面来具体介绍以下B-树(Balance Tree),一个m阶的B树具有如下几个特征:
根节点至少有两个子女;
每个中间节点都包含k-1个元素和k个孩子,其中m/2<=k<=m;
每一个叶子节点都包含k-1个元素,其中m/2<=k<=m;
所有叶子节点都位于同一层;
每个节点中的元素从小到大排列,节点当中k-1个元素正好是k个孩子包含的元素的值域划分。
下面以3阶的B-树为例,来看看B-树的具体结构。
【 9 】
/ \
/ \
【2 6】 【12】
/ | \ / \
/ | \ / \
/ | \ / \
1 【3 5】 8 11 【13 15】
这棵树中,重点看【2 6】节点,该节点有两个元素2和6,又有三个孩子1,【3 5】和8。
其中1小于元素2,6之间,8大于【3 5】,正好符合刚刚所列的几条特征。
演示下B-树的查询过程,假如我们要查询数值为5的节点。
第一次IO,查到 9,比较9
第二次IO,查到 【2 6】 比较2,