1. 前言
即使多个存储引擎支持同一种类型的索引,但他们的实现原理也是不同的.InnoDB和MyISAM默认的索引是B树索引,而Memory默认的是哈希索引.
MyISAM使用b+树作为索引结构,叶子节点的data域存放的是数据记录的地址.
2. MyISAM索引的原理
我们知道InnoDB中索引即数据,也就是聚簇索引的那个b+树的叶子节点已经把所有完整的用户记录都包含在内了.而MyISAM的索引方案虽然也使用的是树形结构,但确将索引和数据分开存储.在物理磁盘上,MyISAM选择将索引存储在.MYI文件中,而将真实的数据存储在.MYD文件中.
- 将表中的记录按照记录插入的顺序单独存储在一个文件中,称之为数据文件.这个文件不划分为若干个数据页,有多少记录就往这个文件里塞多少.由于在插入数据的时候并没有刻意按照主键的大小排序,所以我们不能在这些数据上使用二分查找.
- 使用MyISAM存储引擎的表会把索引信息另外存储到称为索引文件的另一个文件中.MyIsAM会单独为表的主键创建一个索引,只不过在索引的叶子节点上存储的不是真实的完整的用户记录,而是主键值+数据记录地址的组合.
MyISAM的索引文件仅仅保存记录的地址.在MyISAM中,主键索引与二级索引在结构上没什么区别,只是主键索引要求key是唯一的,而二级索引的key可以重复.
3. MyISAM与InnoDB的区别
- 在InnoDB中,我们只需要根据主键值对聚簇索引进行一次查找就能找到对应的记录.而在MyISAM中却需要进行一次回表操作.意味着在MyISAM中建立的索引都是二级索引.
- InnoDB的数据文件本身就是索引文件.而在MyISAM中索引文件和数据文件是分开存储的.索引文件仅仅保存用户记录的地址.
- InnoDB的非聚簇索引的data域存储相应记录的主键值,而MyISAM索引记录的是地址.
- MyISAM的回表操作是非常快捷的.因为的直接拿着地址偏移量直接到文件中取数据.时间复杂度为O(1).
- InnoDB要求表必须有主键,MyISAM可以没有.
4. 小结
- 知道了InnoDB的索引实现以后,很容易明白为什么不要选择过长的字段作为主键.因为所有的二级索引都引用主键,过长的主键索引会使二级索引变的过大.
- 使用非单调的字段作为主键在InnoDB中不是个好主意.因为数据文件本身是b+树,非单调字段在插入新记录时,数据文件为了维护b+树的特性而频繁的分裂调整,非常的低效,而使用自增字段作为主键是个不错的选择.