MySQL中的数据结构(3):B+树(聚簇索引、非聚簇索引)

89 阅读3分钟

概念

B+树是一种基于B树的多路搜索树,主流的DBMS都支持B+树索引方式。

结构:

image.png B+树和B树的差异:

  1. 关键字数 = 孩子节点数(B树中 孩子节点数 = 关键字数+1);
  2. 非叶子节点的关键字同时会出现在子节点中,并且是子节点中所有关键字的极值(最大/最小);
  3. 非叶子节点仅用于索引,数据信息保存在叶子节点中;(B树中非叶子节点即保存索引也记录数据)
  4. 所有关键字都在叶子节点出现,叶子节点构成一个有序链表,本身按照关键字的大小从小到大顺序链接。

B+树的优点

B+树中间节点只用于索引,仅在叶子节点存储数据

查询效率稳定:尽管B+树非叶子节点也有数据信息,但只用于索引,B+树只有访问到叶子节点才能找到对应的数据,这样保证了每次查询都需要查到叶子节点,让查询效率保持稳定;

范围查询效率高: 叶子节点之间会有指针相连,而数据又是递增的,这使我们范围查找可以通过指针连接查找,而在B树中需要通过中序遍历才能实现范围查找。

B+树 分类

B+树在MySQL中的具体应用又分成了聚簇索引、非聚簇索引,它们的区别在于用于索引的字段是否为主键,设计的目的在于提高索引效率

聚簇索引

  • 依赖于主键,只能用主键来创建(若没设置主键会自动找一个非空、唯一的键,再没有的话系统会自己设置一个主键id来创建);

  • 通过主键值大小来排序存储的数据,并在页内(InnoDB引擎是以页存储数据的)形成一个单向链表;

  • 同一层次的页与页之间是双向链表的结构,不同层次之间的页与页是单向链表的结构;

  • 存储用户数据的节点叫 叶子节点,存储了完整的用户数据(所有的列的数据);

  • 在我们创建表时(用的InnDB引擎)会自动给我们创建;

  • 缺点

    • 插入速度依赖于插入顺序(若插入是中间值,其后面的数据都需要往回移一位给插入数据让位),一般设置主键自增;
    • 更新主键的代价很高,一般定义主键不可更新;

非聚簇索引(二级索引、联合索引)

  • 二级索引

    • 依靠 非主键的字段来创建B+树结构(搜索条件不为主键起作用);
    • B+树的结构与 聚簇索引基本一致,只是将排序、依赖的键换成了其他字段而非主键(一般是设置不为NULL的字段)
    • 叶子节点存储的用户数据不是完整的,只存了依赖的字段、主键这两个字段(便于节省空间,不然每一个索引都要创建一大堆完整数据)
    • 当找到目标数据时,会根据其存储的主键id去 回表(拿着主键id去聚簇索引中再查找一遍),查出完整的数据。
  • 联合索引

    • 依赖的字段不止一个:即搜索条件是多个字段的情况;

注意事项

  • 保证节点目录的唯一性:

    一般二级索引的索引(依赖)字段需要设置UNION,否则在目录页会出现多个相同的数据,导致出错;

  • 一页至少存储两条数据

  • 根页面的位置始终不变:最开始时只创建了一个根页面,然后添加数据,当根页面满了时会复制一个跟根页面结构相同的新页面来存储新数据或者作为目录页面;