MySQL-InnerDB和MySAM索引实现
InnoDB索引实现
InnoDB也使用 B+Tree作为索引结构,但具体实现方式却与 MyISAM截然不同。
InnoDB的主索引:
MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而在InnooDB中,数据本身就是按 B+Tree 组织的一个索引结构,这颗树的叶节点 data域保存了完整的数据记录。这个索引的 key就是数据表的主键,因此 InnoDB表数据文件本身就是主键索引。
(图InnoDB主索引)是InnoDB主索引(同时也是数据文件)示意图,可以看到叶节点包含了完整的记录。这种索引叫做聚集索引。因为 InnoDB的数据文件本身要按主键聚集,所以 InnoDB要求表必须有主键(MyISAM可以没有),如果没有显示指定,则 MySQL系统会自动选择一个可以作为唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL会自动为 InnoDB表生成一个隐含字段作为主键,这个字段长度为 6 个字节,类型为长整型。
InnoDB的辅助索引
InnoDB的索引所有辅助索引都是 引用主键作为 data域。例如
InnoDB表是基于聚簇索引建立的。因此 InnoDB的索引能提供一种非常快速的主键查找性能。不过,它的辅助索引(Secondary Index,也就是非主键索引)也会包含主键列,所以,如果主键定义的比较大,则其他索引将很大。如果想在 表上定义很多索引,则争取尽量把主键定义的小一些。InnoDB不会压缩索引。
文字符的 ASCII码作为比较准则。聚集索引这种实现方式使得按主键的搜索十分高效,但是辅助索引需要检索两遍索引:首先检索辅助索引获得主键,然后用主键找到主索引中检索获得记录。
不同存储引擎的实现方式对于正确使用和优化索引都很有帮助。
a. 为什么不建议使用过长字段作为主键,一位内所有辅助索引都引用主键,过长的索引会令辅助索引变得过大。
b. 用非单调的字段作为主键在 InnoDB中不是个好主意,因为 InnoDB数据本身是一个 B+Tree,非单调的主键会造成在插入新记录的数据为了维持 B+Tree的特性而频繁的分裂调整。
聚簇索引和非聚簇索引的区别
聚簇索引的叶子节点存放的是主键值和数据行,支持覆盖索引,二级索引的叶子节点存放的是主键值和指向数据行的指针。
由于叶子节点(数据页)只能按照一颗 B+树排序,故一张表只能有一个聚簇索引。辅助索引的存在不影响聚簇索引中的数据组织,所以一张表可以有多个辅助索引。
MyISAM索引实现
MySAM索引文件和数据是分离的,索引文件仅保存数据记录的地址
主键索引:
MyISAM引擎使用 B+Tree作为索引结构,叶节点的 data域存放的是数据记录的地址。下图为 MyISAM主键索引的原理图:
辅助索引:
在MyISAM中,主索引和辅助索引(Secondary key)在 结构上没有任何区别,只是主索引要求 key 是 唯一的,而辅助索引的 key可以重复。
因此,MyISAM中索引检索的算法为首先按照 B+Tree搜索算法搜索索引,如果指定的 key存在,则取出其 data域的值,然后以data域的值作为地址,读取相对应数据记录。
MyISAM的索引方式也叫做 “非聚集” 的,之所以这么称呼是为了与 InnoDB的聚集索引区分。
MyISAM使用的是非聚集索引,非聚集索引的两棵 B+树看上去没什么不通,节点的结构完全一致只是存储的内容不同而已,主键索引 B+树的节点存储了主键,辅助键索引 B+ 树存储了辅助键。表数据在独立的地方,这两颗 B+树的叶子节点都使用一个地址只想真正的表数据,对于 表数据来说,这两个键没有任何区别。由于索引树是独立的,通过辅助索引无需访问主键的索引树。
InnoDB和MyISAM的区别:
MyISAM只有非聚簇索引,其叶子节点就是真实数据。
InnoDB有聚簇索引和非聚簇索引,聚簇索引叶子节点为数据,非聚簇索引叶子节点为聚簇索引,所以非聚簇索引要进行二次查询,要比MyISAM要慢。
MyISAM不支持事务、行锁、外键
InnoDB支持事务、行锁、外键