数据库的存储引擎是应用于数据库表的,一个库中不同的表可以使用不同的存储引擎。
MyISAM存储引擎实现
1、索引结构
MyISAM索引文件和数据文件是分离的(非聚集)
非聚集索引: 数据和索引是分开存储的。
2、文件说明
表对应的就是磁盘中的文件
- .frm存储表结构信息,
- .MYD存储使用MyISAM引擎的表的数据。
- .MYI存储使用MyISAM引擎的表索引数据。上面图索引结构就是这个MYI文件中存储的。
3、查询过程
MYI存储了索引,MYD存储数据。
查询的时候,如果查询条件符合索引查询,那么先从MYI文件查询索引,定位了叶子节点后,节点中索引存了这条记录的磁盘文件地址,再从磁盘中拿到数据。
InnoDb存储引擎
1、InnoDB索引实现(聚集)
- 表数据文件本身就是按B+树组织的一个索引结构文件。
- 聚集索引 - 叶节点包含了完整的数据记录。
- 为什么InnoDB表必须有主键,并且推荐使用整型的自增主键?
- 为什么非主键索引结构叶子节点存储的是主键值?(一致性和节省存储空间)
聚集索引: 数据和索引是存储在一起的。
2、为什么dba推荐使用自增的整型为主键?
InnoDB的表如果没有创建索引,那么它会找到一列没有重复数据的列作为索引列,如果没找到符合条件的列,就是维护一个隐藏列去组织这个B+树结构。我们要主动创建一个自增的列作为主键,这样减少mysql的工作。
主键为什么使用整型?
-
我们查询数据的时候,每次加载一个节点后要进行数据比大小,要经过大量比大小运算,使用整型时进行比大小运算非常块,远远优于用uuid(String)。
-
整型,即时是bigint,也就8字节,少于用uuid字符类型的开销。
-
uuid虽然方便分库分布,但是用整型也不影响,也是可用做的。
主键为什么使用自增?
如果主键不是自增,会影响insert语句的效率,插入非顺序的数据,会引起节点的分裂和树的在平衡。
下面是001-007,7条数据的索引。
我们先插入一个009,引起节点分裂,如下
再插入0010,
现在插入008
因此,如果索引主键不是自增的,insert时,效率就很低。叶子节点中时不时插入数据,会造成节点分裂和上层节点的分裂和树的平衡,树的维护成本很高。