为什么Innodb选择B+树索引

1,241 阅读3分钟

B+树结构 and 为什么

数据结构演示网页,可以通过网页观察数据结构的生成,更直观的理解

索引结构默认使用B+树,而不是二叉树,红黑树,b树,哈希

为什么?

什么是索引

索引就是一种单独的数据结构,用来对数据库的数据进行快速检索的数据结构,他针对某个表中的一列或者多列。

简单的说就相当于图书的目录,你可以根据目录快速找到自己想要的内容

二叉树

每个根节点最多有两个子节点

二叉搜索树 -- 左子树小于父节点,右子树大于父节点,二分搜索的结构化

最好情况 -- logN

最坏情况 -- n

红黑树

自平衡的二叉搜索树

特性:

  • 每个节点都是黑色或者红色的
  • 根节点是黑色的
  • 如果一个节点是红色,他的子节点一定是黑色
  • 从一个节点到该节点所有叶子节点的路径上包含相同数据的黑色节点
  • 所有叶子节点都是黑色的(叶子节点的值为null)

即使红黑树 也是一个二叉树,随着数据量的增多,红黑树的层级会越来越深,检索速度会越来越慢

B-树

红黑树是一个二叉树,那B树就是一个多叉树,B树每个节点有多个分支,即多叉树

image-20220914113546000.png

特点:

  • 在B树中,所有叶子结点和非叶子节点都会储存数据!!
  • n阶的B树只能储存n-1个key, n个指针
  • 一旦节点储存的数量达到n,就会发生裂变,中间元素向上分裂

B+树

B+树是B树的一个变种

image-20220914113732685.png

和B树的区别:

  • 只有叶子结点才会储存数据!!
  • 非叶子节点只会储存索引
  • 叶子节点之间会形成一个链表,这个链表的所有元素都是有序排列的

Mysql的B+树

Mysql对经典的B+树进行了优化,在原有的基础上,增加了指向相邻叶子节点的指针,把一个单向的链表变成了双向链表,这样就更方便查找了

这种结构可以很方便进行范围查找和排序查找

B+树只有叶子结点储存数据

image-20220914141738839.png

为什么使用B+树

需要结合Innodb的逻辑储存结构来说,B+树和B-树的节点都储存在一个页上面,页的大小是固定的

image-20220914142805900.png

  • 表空间
  • 区 -- 一个区有64页, 大小1M
  • 页 -- 一页大小16k ,16 * 1024
  • 行 -- 数据是按行进行存放的

为什么使用B+树

  • 和二叉树相比。B+树层级更低,索引效率高

  • 和B树相比。B树和B+树的索引的叶子节点都是储存在一个页上面的,而页的大小是固定的。

    • B+树的非叶子结点只存储键值和指针,而B树连带数据一起存储。这样就导致相同大小的页,使用B树的键值和指针会变少,就会增加树的高度,增加IO次数,导致性能降低
  • 和哈希相比,B+树支持范围查找,排序查找,而哈希不支持

思考题:

假设:一行数据大小为1k,一页可以储存16行这样的数据。Innodb的指针占用6个字节的空间,键值采用BigInt,查8个字节的空间,问能储存多少数据

索引由键值和指针组成,n个键,n+1个指针

n*8 + (n+1) * 6 = 16 * 1024 , 计算得出 n = 1170

高度为2:

​ 1171 * 16 = 18736

高度为3

​ 1171 * 1171 * 16 = 21,939,856