InnoDB的B+树


InnoDB的B+树

B+树

特性

在叶子节点一层,所有记录的主键按照从小到大的顺序排列,并且形成了一个双向链表。叶子节点的每一个Key指向一条记录。
非叶子节点取的是叶子节点里面Key的最小值。这意味着所有 非叶子节点的Key都是冗余的叶子节点。同一层的非叶子节点也互相串 联,形成了一个双向链表。

逻辑结构


基于B+树的特性,会发现对于offset这种特性,其实是用不到索引的。比如每页显示10条数据,要展示第101页,通常会写成select xxx where xxx limit 1000, 10,从offset = 1000的位置开始取10条。 虽然只取了10条数据,但实际上数据库要把前面的1000条数据都遍 历才能知道 offset =1000的位置在哪。对于这种情况,合理的办法是不 要用offset,而是把offset = 1000的位置换算成某个max_id,然后用where 语句实现

物理结构

InnoDB默认定义的块大小是16KB,通过innodb_page_size参数指定
无论叶子节点,还是非叶子节点,都会装在 Page里
如果用来装非叶子节点,一个Page大概 可以装1000个Key(16K,假设Key是64位整数,8个字节,再加上各种 其他字段),意味着B+树有1000个分叉;如果用来装叶子节点,一个 Page大概可以装200条记录(记录和索引放在一起存储,假设一条记录大概100个字节)

三层B+:


第二层1000200
第三层1000
1000200 = 2亿条记录,总容量16K1000*1000 = 16GB

B+树演变过程

最早的二叉查找树

二叉树的特点是左侧的子节点的值都比父节点小,右侧的子节点的值都比父节点大。
这样查找从顶节点开始查找,这样不会超过数的高度的次数,就能查找到指定的值,效率比全表扫描是要高。

平衡二叉树

如果id字段里的值是有顺序的,可能就会生成下面这样的二叉树

导致这种情况的原因是树的不平衡,可以改进为在节点插入的过程中,保持二叉树的平衡,即每个节点的左右子树的高度差不能超过1。

B树

平衡二叉树每个节点只存储一个键值,当数据量特别的大的时候,树的高度也很高
从磁盘读取数据时是每次读取一个页的数据,如果每次读取只读取一个键值,也是对磁盘的浪费
所以B树的改进:
每个节点(页)存储了更多的键值(key)和数据(data)
每个节点拥有更多的子节点,并不只是二叉树了。

B+树

B树也有缺点:

  1. 每个页里面存储了key和data,data占了大量数据,每个页大小是固定,导致一页只能放少量的key
  2. 数据不是按顺序存储的,当范围查找、排序查找、去重查找的时候,需要读取多个级别的多个页,效率比较低。
    B+树的改进:
  3. 非叶子节点只存key不存数据,所有数据都存在叶子节点,所以数据是按顺序存储的,使得范围查找、排序查找更加方便。
  4. B+树的页之间用双向链表连接,数据间用单项链表链接

    参考:https://blog.csdn.net/qq_41999455/article/details/106138619

  目录