• B+树索引(5)之索引注意事项


    B+树索引(5)之索引注意事项

    在前面的文章中我们可以聊了很多索引相关知识,具体内容详情可以参考

    B+树索引(4)之索引分类

    B+树索引(3)之索引推导优化

    B+树索引(2)之索引的推导

    B+树索引(1)之为什么需要索引

    但随着深入学习我们知道索引并不只是B+树那么简单,而是一个复杂的结构,所以今天来聊聊索引的注意事项。

    根目录固定不变

    之前的文章画B+树索引为了推导方便每次都是先画叶子节点,然后一层一层的画目录项数据页,直到最后画根节点,也就是从下往上画,结构如下

    那是不是说先有叶子节点,再有根节点呢?显然并不是,在InnoDB存储引擎中,是先有根节点再有叶子节点,具体操作过程如下

    • 每当为一个表创建一个B+树索引的时候,就会创建一个根节点,最开始创建时数据表并没有数据,那么根节点为空。

    • 当在表中插入一条用户数据,这时会先把用户数据插入到根节点中

    • 当根节点数据页可用空间不足,那么就会将根节点数据复制到一个新数据页暂且将其命名为a,然后将数据页a页分裂操作(因为新数据页不够存放根节点数据和新插入数据),得到另一个数据页b,根节点到这时才会升级为目录项数据页。

    • 后续用户数据插入,就会根据索引类型得到排序值(聚簇索引为主键值,二级索引为指定列值),确定插入数据页a还是数据页b,完成插入。

    根节点数据页从索引创建起就存在了,后续都不会改变,因为这个数据页的页号会被记录到某个地方,后续根据索引搜索都会用到这个页号,访问索引。

    二级索引的记录唯一性

    在之前文章索引分类中谈到二级索引就是给非主键列创建一个B+树,例如存在如下测试表

    mysql> CREATE TABLE index_test(
        ->     c1 INT,
        ->     c2 INT,
        ->     c3 CHAR(1),
        ->     PRIMARY KEY(c1)
        -> ) ROW_FORMAT = Compact;
    Query OK, 0 rows affected (0.01 sec)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    给非主键c2列创建索引,索引结构如下所示

    二级索引和主键索引有如下区别

    • 叶子节点数据页:主键索引存放的是完整用户记录,而二级索引存放的是c2列(非主键列)以及主键c1的值。

    • 数据页之间排序和记录之间排序:按照c2列排序不再按照主键列排序。

    • 目录项数据页:存放的是c2列值和数据页页号,不再是主键值和数据页页号。

    看到这里不知道大家有没有这样的疑问,目录项数据页存放的是c2列值和数据页页号,但是c2列值不能保证唯一性(非主键,非唯一性)那么如下情况InnoDB如何确定叶子节点呢?

    数据页8中c2值为7的有两个,如果这时需要插入一条记录,87b这时InnoDB根本无法确定插入到哪一个数据页,显然目录项数据页只存放c2列值和数据页页号是不够的,还需要主键值来确定唯一性,所以完整的二级索引结构应该如下所示

    这样就可以得出87b这条记录正确存放的位置应该是页6。

    一个数据页最少存放的记录数

    InnoDB规定一个数据页最少存放两条记录!

  • 相关阅读:
    【JAVA-Day15】Java 的 do-while 循环语句
    Flutter与Native通信原理剖析与实践
    Python GIL
    安装驱动提示错误“文件的哈希值不在指定的目录文件中”的解决方法
    WEB前端代码书写规范
    自定义数据类型:结构体、枚举、联合
    关于项目采购管理,这些你需要知道
    Elixir-Tuples
    正版软件|WonderFox Photo Watermark 图片水印批量处理软件
    TDengine:无模式写入行协议的四种方式
  • 原文地址:https://blog.csdn.net/zzf1233/article/details/126441826