前几天在看关于B/B+树的文章,看完之后知识点还是比较乱,所以写了这篇文章希望能够帮助自己梳理知识点。
好吧先明确一点,B树即是B-树,英文中b树写作B-tree,所以说B-树算是翻译产生的谬误。
为什么要使用B/B+树
在庞大的文件系统下,索引也会变得巨大无比,而相对内存来说,磁盘io效率却十分低下,所以尽可能的减少磁盘IO可以大幅度增加查找效率。我们发现,
同样的数据量下平衡多叉树的深度明显少于平衡二叉树,减少了IO次数。
举个栗子:有1M的数据需要进行查找,在二叉树下,需要进行log2(10^6)=20次的IO,而在m=100的多叉查找树下,仅需要log100(10^6)=4次的IO,效率提升十分明显。
什么是B树
首先给出B树的定义:
1.树中每个节点最多m个孩子(m>2)
2.若根节点不是叶子节点,则至少有2个孩子
3.所有叶子节点在同一层,没有孩子和指向孩子的指针
4.除根节点与叶子节点外,每个节点至少有[ceil(m/2)]个孩子。(ceil()为取上限函数)
5.每个非叶子节点包含有n个关键字信息:(n,P0,K1,P1,K2,P2,...,Kn,Pn)。
其中:
a)关键字的个数必须满足:[ceil(m/2)-1] ≤ n ≤ m-1
b)Ki(i=1...n)为关键字,且关键字按升序排列K(i-1) <Ki
c)Pi为指向子树的接点(指针),且指针P(i-1)指向的子树中所有节点的关键字小于Ki,大于K(i-1)。
2.若根节点不是叶子节点,则至少有2个孩子
3.所有叶子节点在同一层,没有孩子和指向孩子的指针
4.除根节点与叶子节点外,每个节点至少有[ceil(m/2)]个孩子。(ceil()为取上限函数)
5.每个非叶子节点包含有n个关键字信息:(n,P0,K1,P1,K2,P2,...,Kn,Pn)。
其中:
a)关键字的个数必须满足:[ceil(m/2)-1] ≤ n ≤ m-1
b)Ki(i=1...n)为关键字,且关键字按升序排列K(i-1) <Ki
c)Pi为指向子树的接点(指针),且指针P(i-1)指向的子树中所有节点的关键字小于Ki,大于K(i-1)。
如下图所示,为一棵B树
值得注意的是:当B树的M值变得比较大时,每个节点内的关键字也会增多,这时MySQL会在将节点内的所有关键字形成一棵
AVL树(自平衡的二叉树)红黑树。
B树的数据结构
定义
typedef struct BTNode{
int keynum; //实际关键字数量
struct BTNode *parent; //父节点
int key[m]; //每本书所拥有的关键字
Data KeyInfo[m]; //关键字信息 m个
struct BTNode *ptr[m+1]; //指向孩子节点的指针 m+1个
}BTNode;