引言

定义:帮助mysql高效获取数据的排好序的数据结构;

首先清楚数据在底层存储方式:向链表一样前后相连,而非数组的形式开辟一片相连的空间,这意味着我们看到的有序的相连的数据不一定在一起,当我们想要获取数据时,每一次读取就是一次io,当减少io次数时,就可以将获取数据的速度加快。

数据结构

二叉树:

缺点:递增索引下,高度会过高浅理解MYSQL索引数据结构B+TREE_主键

红黑树:

二叉平衡树,也会高度过高,递增索引下,高度过高浅理解MYSQL索引数据结构B+TREE_数据_02


hash表:

会创建hash桶,对索引列进行hash计算,将数据存储位置依次放入桶中

缺点:hash冲突;仅能满足‘=‘查询,不支持范围查询(主因)

浅理解MYSQL索引数据结构B+TREE_数据_03


b-Tree:

增大红黑树根节点空间,使根节点横向增大

缺点:每个节点都带有数据,占用内存

浅理解MYSQL索引数据结构B+TREE_数据_04

b+Tree:

将b-树非叶子节点的数据统一安排到叶子结点,叶子结点将有所有数据和索引,非叶子节点只放索引(冗余索引);

共同点:

  1. 从左到右递增,查找时可以使用二分查找法快速定位横向节点;
  2. 快速查找时横向查找将会把数据放入内存,内存大小为16k;

不同点:

  1. b+Tree假设非叶子节点上一个索引占(8+6)B全部存满,1100 * 1100 * 16大概三层可以快速查找两千万内数据;B-Tree每一个索引下都有数据,若每一个索引的数据按照1kb算,将索引和数据放入内存,每一次只能放16个数据,按三层数据高度算,16x16x16远远低于B+Tree的存储;
  2. b+tree相比b-tree叶子结点多一个双向指针,指针会记录下一节点位置,当出现范围查找时,不需要重新根节点查找元素,直接得到位置,将数据取出即可;当b-tree范围查找,叶子结点出现断层,需要重新返回根节点去查找元素位置;

注:MySQL叶子节点指向是双向的,且只有最下面的叶子节点有数据

浅理解MYSQL索引数据结构B+TREE_数据_05


MYSQL存储引擎

MyISAM存储引擎:建表后由三个文件组成(同一文件名,不同后缀)

  • .frm:框架表结构
  • .MYI:索引
  • .MYD:数据

InnoDB存储引擎:两个文件组成(同一文件名,不同后缀)

  • .frm:框架表结构
  • .ibd:索引+数据

聚集索引:叶子节点包含完整的数据记录;

非聚集索引:MyISAM在叶子结点不放入数据,只放入地址,之后根据地址去数据表查找数据,速度变慢

为什么InnoDB建议建主键,并且推荐整数类型自增主键

前提:建立表时必须由b+Tree去创建表,b+Tree必须得有索引

  • 为什么建主键

当开始建表是会从第一页查找不存在重复数据的列,若存在则当前列为索引,若不存在,会重建一个隐藏不重复数据列,作为该表的索引列;

  • 为什么整数类型

假如使用uuid做主键,必须先要将uuid转换为asic码,再进行大小比较,浪费时间、性能,同时uuid占用内存也会比整型占用空间大;

  • 为什么自增

当建立表时,数据根据b+Tree结构添加索引,主键递增,非叶子节点会往后添加,若不是递增,则会进行一个平衡再自加,特别是大数据时,会直接变更已经定好的树结构;

普通索引

采用b+Tree结构,叶子结点的数据层将会存储表的主键值,然后根据主键值回表查询数据行。

为什么非主键索引结构叶子结点存储的是主键值?

  • 一致性:当进行数据修改和插入时,如果都是数据的话,需要多次修改或添加,使用主键只需要改变主键索引下的数据;
  • 节省空间:若每一个非主键索引的叶子结点都存入数据,将会占用很大内存空间(主因)

联合索引数据结构

按照索引最左前缀原理,当联合索引有三个元素时,按照第一个排序,后第二第三个元素依次排序,得到主键后直接得到数据