一、存储引擎作用于什么对象

存储引擎是作用在表上的,而不是数据库。

二、MyIsam和InnoDB对索引和数据的存储在磁盘上是如何体现的?

下面是创建好的两张表信息,role表使用的存储引擎是MyIsam,而User 使用的是InnoDB:

MySQL存储引擎MyIsam和InnoDB底层索引结构
再来看下这两张表在磁盘中的索引文件和数据文件:

MySQL存储引擎MyIsam和InnoDB底层索引结构
1、role表有三个文件,对应如下:

  • role.frm:表结构文件
  • role.MYD:数据文件(MyIsam Data)
  • role.MYI:索引文件(MyIsam Index)
    2、user表有两个文件,对应如下:
  • user.frm:表结构文件
  • user.ibd:索引和数据文件(InnoDB Data)

三、MyIsam主键索引和辅助索引(非主键索引)的结构

先列举一部分数据出来分析,如下:
MySQL存储引擎MyIsam和InnoDB底层索引结构由磁盘文件可以知道,MyIsam引擎的索引文件和数据文件是分离的,下面看一下两种索引结构的异同。

1、主键索引

MyIsam引擎中叶子结点存储的数据其实是索引和数据的文件指针两类。

如下图中以Col1列作为主键建立索引,对应的叶子结点存储形式可以看一下表格。
MySQL存储引擎MyIsam和InnoDB底层索引结构
MySQL存储引擎MyIsam和InnoDB底层索引结构
通过索引查找数据的流程,先从索引文件中查找到索引结点,从中拿到数据的文件指针,再到数据文件中通过文件指针定位了具体的数据。

2、辅助索引(非主键)索引

以Col2列建立索引,得到的辅助索引结构跟上面的主键索引的结构是相同的。
MySQL存储引擎MyIsam和InnoDB底层索引结构

四、InnoDB主键索引与辅助索引的结构

1、主键索引

InnoDB引擎中的索引和数据是存入同一个 .idb 文件中的,因此它的索引结构是在同一个树节点中同时存放索引和数据,如下图中最底层的叶子节点有三行数据,对应于数据表中的Col1,Col2,Col3数据项。
MySQL存储引擎MyIsam和InnoDB底层索引结构

2、辅助(非主键)索引

以数据表中的Col3列的字符串数据建立辅助索引,它的索引结构跟主键索引的结构有很大差别,我们来看下面的图:
在最底层的叶子结点有两行数据,第一行的字符串是辅助索引,按照ASCII码进行排序,第二行的整数是主键的值。
MySQL存储引擎MyIsam和InnoDB底层索引结构

五、InnoDB索引结构需要注意的点

  1. 数据文件本身就是索引文件
  2. 表数据文件本身就是按B+Tree组织的一个索引结构文件
  3. 聚集索引中叶子节点包含了完整的数据记录
  4. InnoDB表必须要有主键,并且推荐使用整型自增主键

如果我们在设计表结构时没有显式指定索引列的话,MySQL会从表中选择数据不重复的列建立索引,如果没有符合的列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,并且这个字段长度为6个字节,类型为整型。

为什么推荐使用整型自增主键而不是选择UUID?

  • UUID是字符串,比整型消耗更多的存储空间
  • 在B+树中进行查找时需要跟经过的节点值比较大小,整型数据的比较运算比字符串更快速
  • 自增的整型索引在磁盘中会连续存储,在读取一页数据时也是连续;UUID是随机产生的,读取的上下两行数据存储是分散的,不适合执行 范围条件 查询语句。如 where id > 5 && id <20
  • 在插入或删除数据时,整型自增主键会在叶子结点的末尾建立新的叶子结点,不会破坏左侧子树的结构;UUID主键很容易出现这样的情况,B+树为了维持自身的特性,有可能会进行结构的重构,消耗更多的时间

为什么非主键索引结构叶子结点存储的是主键值?
保证数据一致性和节省存储空间,可以这么理解:商城系统订单表会存储一个用户ID作为关联外键,而不推荐存储完整的用户信息,因为当我们用户表中的信息(真实名称、手机号、收货地址···)修改后,不需要再次维护订单表的用户数据,同时也节省了存储空间。

相关文章: