Mysql索引
# InnoDB存储引擎索引
# InnoDB索引
# 表数据文件本身就是按B+Tree组织的一个索引结构文件,(聚集索引)叶节点包含了完整的数据记录
InnoDB存储引擎存储数据集,一共有两个文件
- frm文件:表结构
- ibd文件:数据和索引存储文件。数据以主键进行聚集存储,真正的数据保存在叶子节点中。
# 为什么建议InnoDB表必须建主键,并且推荐使用整型的自增主键?
表数据文件本身以B+Tree组织的一个索引结构,这棵树的叶子节点data域保存了完整的数据记录,也就是说InnoDB引擎的表必须有聚集索引。
- 如果表定义了PK,则PK就是聚集索引
- 如果没有定义PK,则第一个NOT NULL UNIQUE列是聚集索引。
- 否则InnoDB会创建一个隐藏的ROW-ID作为积极所以。
综合上述问题,InnoDB表建议必须有主键。
结合B+Tree的数据查找特点(索引查找会根据数据大小进行比较),证书类型比较大小相对简单、快速,企鹅索引节点占的内存会更小。其次如果主键ID是非自增多,这时候会导致页分裂,也会导致B+Tree的树节点分裂。
# 数据页
# 结构
名称 | 大小(字节) | 描述 |
---|---|---|
File Header | 38 | 文件头 |
Page Header | 38 | 页头 |
Infimum + SupreMum | 26 | 最小记录与最大记录 |
User Records | - | 用户记录 |
Free Space | - | 空闲空间 |
Page Directory | - | 页目录 |
File Trailer | 8 | 文件尾部 |
如果不使用自增主键,在数据写入过程中,当我们发现一个主键ID要小于当前页的主键ID时,我们需要将数据写入到左侧子叶中,此时就会进行数据移动,从而满足索引(B+Tree)的基本要求,这个过程就是页分裂。综上所述推荐使用自增主键。
# 为什么非主键索引结构叶子节点存储的是主键值?
# 非聚集索引
非聚集索引包含复合索引、唯一索引、前缀索引,数据结构都是采用B+Tree。
非聚集索引叶子节点存储的是主键ID与非聚集索引的字段内容。这样做一是节省了存储空间;二是保证了数据一致性,减少他的复杂度,减少了出现行移动或者数据页分裂时二级索引的维护工作。
非聚集索引的查询通常首先是从非聚集索引中查找聚集索引,然后在B+树上进行查询,通过聚集索引B+Tree找到完整的数据;例外情况:如果要查找的数据能再非聚集索引中查到到内容,此时便不会去聚集索引中查找(select 非聚集索引字段 from table where 非聚集索引字段 = ?,此时字段与条件都在非聚集索引叶子节点中存储,不需要去聚集索引中查找)。
由于每个非聚集索引单独存储为B+Tree,所以过多的非聚集索引会因为维护B+Tree的操作,影响写入性能。
# 联合索引的底层存储结构长什么样?
- 叶子节点是线性排列,并且每个节点的数据排列顺序和创建索引字段的顺序一致。
- 非叶子节点存储完整的索引关键字信息,排列规则和叶子节点一致。
- 联合索引会生成一个B+Tree,只不过联合索引B+Tree的数据部分存储的是联合索引所在行的主键值。
- 索引最左前缀原理:联合索引中包含多个字段,所以不能像单值索引那样直接使用,所有数据都是按照最左侧列进行排序(其他字段依次从左到右按字段顺序组织,这种顺序是局部,换句话说除最左侧列外,其他列也是有序的,只不过这种有序是局部的。);根据左侧匹配原则,如果靠左侧列使用范围查询,那么其他列列就是无需的,其他列无法再使用索引。
上次更新: 2023/05/09, 17:54:37