InnoDB 和 MyISAM 的数据分布是什么样的?

复制代码

然后插入下面的数据,id从1-9,故意把插入顺序打乱,tag代表插入顺序

INSERT test(id, num, tag) VALUES(7, 1, ‘no.1’);

INSERT test(id, num, tag) VALUES(5, 19, ‘no.2’);

INSERT test(id, num, tag) VALUES(6, 7, ‘no.3’);

INSERT test(id, num, tag) VALUES(9, 5, ‘no.4’);

INSERT test(id, num, tag) VALUES(3, 13, ‘no.5’);

INSERT test(id, num, tag) VALUES(4, 17, ‘no.6’);

INSERT test(id, num, tag) VALUES(2, 3, ‘no.7’);

INSERT test(id, num, tag) VALUES(8, 23, ‘no.8’);

INSERT test(id, num, tag) VALUES(1, 11, ‘no.9’);

复制代码

MyISAM的数据存储

MyISAM按照数据插入的顺序存储在磁盘上,我们假设第一行数据在数据库表文件中的偏移位置是1,以此类推。 如下图

现在我们验证一下,使用 SELECT * FROM test; 扫描全表(SELECT * 不会使用任何索引,可以用 explain 实际观察下),输出的顺序正是我们sql插入的顺序,大家可以调整sql的顺序再次插入,观察输出顺序。

搞清楚了MyISAM的数据存储方式,再来看下主键索引的存储。我们假设每个磁盘块只能存储两个节点数据,MyISAM的主键分布如下图:

其实MyISAM的二级索引和主键索引并无区别,只是名称不同罢了,二级索引key(num)分布如下图:

二级索引子节点也只存储了索引列(num)和文件的偏移量(P),但可以看出num是有序的,这在范围查找(比如:where num > 3)是非常有利的,但文件的偏移量并没有规律,当需要回表查询其他字段,可能会导致多次随机I/O。

当对增加数据时MyISAM直接添加到文件尾部,不需要移动其他数据,而且更新主键时,也不会导致其他行数据移动,但它不支持行级锁,修改时直接锁表。若不需要事务支持,对读多写少的场景可以考虑MyISAM引擎,但不要默认使用MyISAM引擎。

InnoDB的数据存储

InnoDB支持聚簇索引,所以使用非常不同的方式存储同样的数据。InnoDB数据存储方式如下图:

注意整个树和MyISAM的主键索引非常类似,唯一的区别是叶子节点,InnoDB的叶子节点存储了整个行数据(id、num、tag),而不是只有索引。聚簇索引“就是”整个表,而不像MyISAM那样需要单独的行存储文件。当更新主键id时,可能会导致数据行移动,因为索引和数据是存储在一起的。若主键id是乱序写入的,InnoDB不得不做页分裂操作时,至少会导致修改三个页(分裂产生的两个页,以及他们的父节点页面),而不是一个页,这和MyISAM新增数据时添加到文件尾部很不一样。所以使用InnoDB引擎尽可能的按主键顺序插入数据。

InnoDB的二级索引和聚簇索引也不一样。InnoDB二级索引的叶子节点中存储的不是行数据的“偏移量”,而是主键值。这意味着通过二级索引查找行数据,存储引擎需要找到二级索引的叶子节点获得对应的主键值,然后根据这个值去聚簇索引中查找到对应的行数据。这里做了重复的工作:两次B-Tree查找,而不是一次。这样的策略减少了当出现行移动或者数据页分裂时二级索引的维护工作。二级索引的数据分布如下图:

如果没有定义主键,InnoDB会选择一个唯一的非空索引代替。如果没有这样的索引InnoDB会隐式的定义一个主键作为聚簇索引。选择主键最好是自增id,如果采用字符串当做主键,不仅仅会增加聚簇索引的大小,也会增加二级索引的大小(二级索引叶子节点包含主键值),并且字符串匹配需要一个个字符判断,更加降低索引的查找性能。当然某些场景使用字符串作为主键带来的优势要比这些损失更有利,需要根据场景具体评估。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Java)

最后

针对最近很多人都在面试,我这边也整理了相当多的面试专题资料,也有其他大厂的面经。希望可以帮助到大家。

image

上述的面试题答案都整理成文档笔记。 也还整理了一些面试资料&最新2021收集的一些大厂的面试真题(都整理成文档,小部分截图)

image

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
大家的学习有所帮助,也希望大家多多支持。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 23
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值