Mysql采用B+树作为索引
- B+Tree是一种自平衡的树形数据结构。B+Tree是B树的一种变种。B+树的叶子结点存储所有的数据,而内部节点(叶节点)仅用于索引。
- 所有的数据都存储在叶子节点,内部索引(叶节点)只存索引
- 叶子结点之间使用指针项链形成双向链表
- 所有的叶子结点都在同一层级,树的高度是平衡的。通过自平衡自机制,B+树保证查找、插入、删除的时间复杂度为O(log N) 。
B+tree结构
-
根节点(Root Node)
- 根结点存储索引信息,指向叶子结点。根结点只有一个叶子结点时,即是根结点也是叶子结点。
-
非叶子节点(内部节点)(Internal Node)
- 内部节点只存储索引,不存储数据。
-
叶子节点(Leaf Node)
- 叶子结点存储真实用户数据
- 通过父指针连接到上级节点,还可以通过叶子指针形成一个双向链表
BTree结构
- B树是一种多路平衡搜索树。
- 每个节点最多有m个子节点
- 每个非叶子结点至少有[m/2]个字节点(除了根结点)
- 每个节点最多有m-1个键
- 所有叶子结点在同一层。所有节点键值递增
二叉树(遵循BST)
- 要知道二叉树的结构是每个字节点只有两个,并且左子树永远小于右子树。
- 但是要知道,如果一直插入比之前大的数据,那么二叉树就会退化成为链表。
自平衡二叉树
- 为了防止二叉树退化成为链表的情况,就提出的自平衡二叉树。
- 条件约束:每个节点的左子树和右子树的高度差不能超过1。其实就是为了防止二叉树长歪变成链表。这里涉及到平衡因子。平衡因子 = 左子树 - 右子树
平衡因子
平衡因子 状态
0 左子树与右子树一样高
1 左子树比右子树高1
-1 右子树比左子树高1
每个节点的左子树和右子树的高度的差绝对值不超过1
|height(left subtree) - height(right subtree)| <= 1
如果在插入和删除时发生了高度差超过1,就会发生自动旋转调整结构
以上就是一些树的结构,接下来看看为什么使用B+Tree作为innodb存储引擎的索引数据结构
- 要知道我们的数据是存储在磁盘的,读取的时候自然会产生磁盘I/O开销。
- 先看看二叉树(自平衡),二叉树的高度理论上可以达到很高的一个地步,这就意味着磁盘I/O操作次数多,影响效率。如果一个数的高度是为10,需要查找的数据又在第五层的节点上,这就意味着需要磁盘5次的I/O操作。
- 来看看B树,他解决了树的高度问题,转而将树的高度变矮,字节点个存放M个字节点(M>2),降低树的高度,这样就可以减少磁盘I/O。但是,B树的每个节点都包含(数据+索引),大多数情况下用户存储的数据远远超过索引数据,这就需要花费更多的磁盘I/O操作次数取读取有用的索引。
- 为什么使用B+Tree,他和B树不同的点在:他只在叶子节点才会进行存储数据,非叶子节点存储索引,高度和BTree差不多。而且B+Tree叶子节点之间使用指针连接起来,形成一个双向链表,这样就可以进行范围性查找。而且只有叶子节点存放数据,非叶子节点存放索引,这样一页可以存放更多的索引(key)。
总结:其实就一步一步演变出来得到一个最优解方案。