索引数据结构红黑树,Hash,B+tree详解
    索引是帮助MySQL高效获取数据的排好序的数据结构
    没有索引的情况下,查询数据会一行行的去找,记录写在磁盘上,但是在磁盘上是随机分布的。
    读取一次数据,需要与磁盘做一次IO交互,需要控制与IO的次数。

    二叉树维护索引:优势,对无序字段有优势,但是对有序字段建立索引没有帮助

    红黑树:平衡二叉树,也存在弊端,某些场景下对mysql索引查询效率帮助不是很大,树的高度,如果数据在叶子结点,红黑树查找数据,是从根节点开始查找,高度很高,IO次数就越多,影响效率。

    优化:只要一个节点,横向多存放一些数据。就是B-Tree结构

    B-Tree
    叶节点具有相同的深度,叶节点的指针为空
    所有元素不重复
    节点中的数据索引从左到右递增排列
    每个节点从左到右是有序的
    16^n=2000W n是树的高度

    B+Tree
    非叶子节点不存储data,只存储索引(冗余),可以放更多的索引
    叶子节点包含所有索引字段
    叶子节点用指针链接,提高区间访问的性能。
    取第一个元素,每个节点从左到右是有序的
    节点所有元素都load到内存中,然后二分查找到需要的位置,找到子叶的地址
    根节点(非叶子节点)常驻内存中

    一个节点就是一个页:大小16K(mysql推测的最优数据),最耗费时间的是load节点,所以把节点加载到内存中比对,速度会快很多。

    计算:bigint做主键占用8字节+空间地址6字节。16kb/(8+6)~1170
    第一层、第二层、第三层 1170117016~2000W

    一个节点存放索引的数量越多,效率越高

    数据库表位置:/data/test

    数据库存储引擎:引擎形容数据库表的
    新建表的时候选择存储引擎
    a73f5a84a60a70ef7b0a6fae4c624e8.png
    MyISAM:有三张表(user表为例)

    • user.frm:数据表结构的信息
    • user.MYD:数据
    • user.MYI:索引

    索引所在行的磁盘地址

    InnoDB:整张表只有一个聚集索引

    • tbox.frm:数据表结构信息
    • tbox.ibd:索引+数据

    聚集索引:InnoDB叶节点包含了完整的数据记录,
    非聚集索引(稀疏索引):MyISAM就是非聚集的,数据与索引两个文件分开的
    查找速度:聚集索引>非聚集索引 因为非聚集索引跨表

    面试题:为什么建议InnoDB表必须建主键,并且推荐使用整型的自增主键?

    • 主键:因为mysql设计的时候,ibd必须用B+树来组织,就可以用主键来维护索引,如果没有用主键,mysql会自动选择一个所有列都不相等的列作为索引列,如果还没有,mysql会自动创建一个隐藏列主键(rowid)。尽量减少mysql的工作。
    • 主键自增:节点内的数据,是按照从小到大排列的,而且数据类型占用空间也会小,节约空间,建议整型。非自增插入数据,可能导致源树分裂进行平衡。自增的插入,尾节点追加

    为什么非主键索引结构叶子节点存储的是主键值?(一致性和节省存储空间)

    • 节省存储空间:如果存在多个索引,每个叶子节点没必要都存储全部数据,只要存储主键就好
    • 一致性:减少复杂度,保证两个或者多个索引表里面的数据一致性。

    hash结构:hash+链表
    hash算法:MD5

    某些情况下hash可能比B+树效率更高,但是hash存在一些缺点,不支持范围查找
    B+树可以,因为叶子节点有一个指针,B+树是排好序的

    联合索引的底层存储结构长啥样?
    一张表不建议创建太多单值索引,建议2-3个联合索引。

    索引最左前缀原理
    建立索引的先后顺序进行创建,如果第一个字段就已经排好序,区分出要查找的值,就不会查找后面的字段了。如果第一个字段都相等,就对比第二个字段,一次类推
    联合主键(模拟三个字段:name,age,position)三个字段不可能相等的
    要用的时候一定要按照建索引的顺序去用,不能跳过第一个直接用后面的,顺序从左开始

    最左前缀原理为什么要这样定义?
    因为排好序索引的创建就是从左往右依次创建,最左的放第一位,第一位的是排好序的。