在《MYSQL数据库索引,终于懂了!》这篇文章中,为大家深入解析了为什么B+树如此适合用作数据库的索引工具。
那么,MyISAM和InnoDB这两种引擎是如何利用B+树来设计索引的呢?
它们又有什么不同呢?
问题1:MyISAM的索引结构是怎样的?
MyISAM的索引存储方式有点特别,它把索引和行记录分开存储,这种方式被称为非聚集索引(UnClustered Index)。
具体来说,MyISAM的主键索引和普通索引并没有本质的区别:
- 行记录被单独存储在一个区域;
- 主键索引的叶子节点存储的是主键和与行记录的指针;
- 普通索引的叶子节点则存储的是索引列和行记录的指针。
这也意味着,即使表没有主键,MyISAM依然可以正常工作——也就是说:MyISAM的表是可以没有主键的。
举个例子,假设表结构是这样:
t(id PK, name KEY, sex, flag);
我们有四条记录:
- 1, xiaobei, m, A
- 3, zhangsan, m, A
- 5, lisi, m, A
- 9, wangwu, f, B
MyISAM的B+树索引是如何构造的呢?看看这张图:
- 行记录是单独存储的;
- id是主键(PK),它有一棵自己的B+树索引,叶子节点指向行记录;
- name是普通索引(KEY),也有一棵B+树,叶子节点同样指向行记录。
最近无意间获得一份阿里大佬写的刷题笔记,一下子打通了我的任督二脉,进大厂原来没那么难。 这是大佬写的 7701页的BAT大佬写的刷题笔记,让我offer拿到手软
问题2:InnoDB的索引结构是怎样的?
InnoDB有个比较特别的特性,它将主键索引和行记录一起存储,这叫做聚集索引(Clustered Index)。
和MyISAM不同,InnoDB的主键索引叶子节点不仅仅存储主键,还直接存储了行记录的内容,而不是指针。
这意味着,InnoDB表必须拥有聚集索引。
如果表中没有定义主键,则第一个非空的唯一列将会成为聚集索引。
如果没有这种列,InnoDB会为每个表创建一个隐式的行ID来作为聚集索引。
由于行数据与聚集索引是共存的,InnoDB的表最多只能有一个聚集索引,因为行记录物理存储的位置是唯一的。
InnoDB的普通索引则不同,它的叶子节点存储的是主键值,而不是指针。
问题3:InnoDB为何建议使用趋势递增主键?
为什么InnoDB建议使用递增的主键?关键在于插入性能。如果主键是递增的,那么每次插入记录时,新的行会直接添加到聚集索引的末尾,不会引发索引分裂,也避免了大量行记录的移动。这样,不仅能提高插入效率,还能有效减少性能开销。
问题4:InnoDB为何不宜使用较长的列做主键?
假设我们有一个用户中心,其中包含身份证号、身份证MD5、姓名、出生年月等信息。如果我们考虑将身份证号作为主键,问题就来了:
- 身份证号作为主键会导致索引树的空间使用效率低下,因为每个索引节点都要存储较长的身份证号码。在数据量增大时,这对内存和磁盘IO的压力非常大。
解决方案很简单:给表加一个自增的ID列,作为主键。这不仅避免了使用过长的字段作为主键,还能让索引变得更紧凑。优化后的表结构如下:
user(id PK auto inc, id_code(index), id_md5(index), name(index), birthday(index));
这样一来,存储效率就大大提高了,磁盘IO的频率也降低了。
问题5:InnoDB的普通索引存储主键键值,可能存在什么问题?
这里要说的就是回表查询。回表查询是指:在普通索引查询时,先根据普通索引定位到主键值,再通过聚集索引查找具体的行记录。显然,这样的查询效率要低于直接通过聚集索引查找。
问题6:如何优化回表查询?
一种常见的优化方案是使用覆盖索引。所谓覆盖索引,就是索引包含了查询所需的所有列数据,这样查询时就无需回表。
例如,针对查询:
SELECT id, name, sex FROM t WHERE name='lisi';
我们可以将name索引升级为联合索引(name, sex),这样查询时直接通过联合索引就能获取所有数据,无需再访问聚集索引。
总结
- MyISAM和InnoDB都使用B+树来实现索引:MyISAM将索引和数据分开存储,而InnoDB将索引与数据存储在一起;
- InnoDB不宜使用长列做主键:长列会增加索引空间消耗,影响查询效率;
- 回表查询的优化:通过覆盖索引可以避免回表查询,提升性能。
最后说一句(求关注,求赞,别白嫖我)
最近无意间获得一份阿里大佬写的刷题笔记,一下子打通了我的任督二脉,进大厂原来没那么难。 这是大佬写的 7701页的BAT大佬写的刷题笔记,让我offer拿到手软
本文,已收录于,我的技术网站 cxykk.com:程序员编程资料站,有大厂完整面经,工作技术,架构师成长之路,等经验分享
求一键三连:点赞、分享、收藏
点赞对我真的非常重要!在线求赞,加个关注我会非常感激!