MySQL Innodb数据及索引文件存储格式

Innodb存储引擎的数据(包括索引)存放在相同的文件中,这一点和MySQL默认存储引擎MyISAM的区别较大,后者分别存放于独立的文件。除此之外,Innodb的数据存放格式也比较独特,每个Innodb表都会将主键以聚簇索引的形式创建。所有的数据都是以主键来作为升序排列在物理磁盘上面,所以主键查询并且以主键排序的查询效率也会非常高。

由于主键是聚族索引的缘故,Innodb的基于主键的查询效率非常高。如果我们在创建一个Innodb存储引擎的表的时候并没有创建主键,那么Innodb会尝试在创建于我们表上面的其他索引,如果存在由单个not null属性列的唯一索引,Innodb则会选择该索引作为聚族索引。如果也没有任何单个not null属性列的唯一索引,Innodb会自动生成一个隐藏的内部列,该列会在每行数据上占用6个字节的存储长度。所以,实质上每个Innodb表都之少会有一个索引存在。

在Innodb上面除了聚族索引之外的索引被成为secondary index,每个secondary index上都会包含有聚族索引的索引键信息,方便通过其他索引查找数据的时候能够更快的定位数据位置所在。

当然,聚族索引也并不是只有好处没有任何问题,要不然其他所有数据库早就大力推广了。聚族索引的最大问题就是当索引键被更新的时候,所带来的成本并不仅仅只是索引数据可能会需要移动,而是相关的所有录的数据都需要移动。所以,为了性能考虑,我们应该尽可能不要更新Innodb的主键值。

一、存储格式
1、页(Page)
Innodb存储引擎中的所有数据,不论是表还是索引,亦或是存储引擎自己的各种结构,都是以page作为最小物理单位来存放,每个page默认大小为16KB。

2、区(extent)
extent是一个由多个连续的page组成一个物理存储单位。一般来说,每个extent为64个page。

3、段(segment)
segment在Innodb存储引擎中实际上也代表“files”的意思,每个segment由一个或多个extent组成,而且每个segment都存放同一种数据。一般来说,每个表数据会存放于一个单独的segment中,实际上也就是每个聚族索引会存放于一个单独的segment中。

4、表空间(tablespace)
tablespace是Innodb中最大物理结构单位了,由多个segment组成。

二、我们至少可以得出以下几点对性能有较大影响的地方
1、为了尽量减小secondary index的大小,提高访问效率,作为主键的字段所占用的存储空间越小越好,最好是INTEGER类型。当然这并不是绝对的,字符串类型的数据同样也可以作为Innodb表的主键;

2、创建表的时候尽量自己指定相应的主键,让数据按照自己预设的顺序排序存放,提高特定条件下的访问效率;

3、尽可能不要在主键上面进行更新操作,减少因为主键值的变化带来数据的移动;

4、尽可能提供主键条件进行查询;