您的位置:首页 > 新闻 > 资讯 > 市场营销实务_镇江百度开户_html网页制作模板代码_网络营销战略

市场营销实务_镇江百度开户_html网页制作模板代码_网络营销战略

2025/3/11 15:13:35 来源:https://blog.csdn.net/weixin_49426115/article/details/146163655  浏览:    关键词:市场营销实务_镇江百度开户_html网页制作模板代码_网络营销战略
市场营销实务_镇江百度开户_html网页制作模板代码_网络营销战略

大家好,我是钢板兽!

这篇文章包含了Java后端面试中关于MySQL八股中的两个常问的问题:(1)为什么MySQL选用innoDB作为存储引擎?,这个问题在面试的时候可能换一种问法:“innoDB和MyISAM的区别”。(2)“Mysql的索引结构你了解吗?”,这个问题也可能换一种问法:“为什么MySQL索引结构用B+树?”。接下来让我们深入理解这两个问题。

1.为什么MySQL选用innoDB作为存储引擎?

MySQL 的插件式存储引擎架构,这种架构允许我们在创建数据表时,指定不同的存储引擎来处理数据的存储和管理方式,常见的 MySQL 存储引擎主要包括 InnoDB、MyISAM、Memory、Archive、CSV、NDB Cluster 等。不同的存储引擎在事务支持、锁机制、性能优化等方面各有优劣,适合不同的业务场景。MySQL5.5版本之后默认的就是innodb存储引擎,我们通常拿MyISAM来和innodb进行比较,那么Mysql为什么用innoDB作为存储引擎,而不是MyISAM?

innoDB相对于MyISAM有5个优势:

  • **事务管理:**InnoDB完整地支持ACID特性,它的Redo Log用于崩溃恢复,确保事务持久性,UndoLog用于事务回滚和MVCC,保证事务的一致性、原子性和隔离性。

    而MyISAM不提供事务支持。

  • **外键约束:**InnoDB 支持外键约束,在处理多表关联时,可以避免出现数据不一致的问题。

    MyISAM 不支持外键约束,易出现脏数据。

  • 行级锁粒度:InnoDB 支持行级别的锁粒度,在进行数据增删查改时,只锁定特定的数据行,能够显著提升并发性能。

    MyISAM只支持表级别的锁粒度。

  • **底层结构:**InnoDB 每个表都有一个聚簇索引(主键索引),聚簇索引使用B+树构建,主键索引的叶子节点直接存储完整的数据行,查询主键时仅需一次I/O。

    MyISAM的主索引和辅助索引都使用非聚簇索引,叶子节点保存数据地址,查询主键时需要两次I/O。

  • **缓存机制:**InnoDB 采用Buffer Pool(缓冲池)作为核心的缓存机制,可以将热点数据页和索引页缓存在内存中,显著减少I/O次数。

    MyISAM基于磁盘I/O,没有内存缓存机制。

InnoDB的事务管理与外键约束保障了数据的一致性、持久性、隔离性,而行级锁粒度、底层结构和缓存池机制保障了MySQL在高并发场景下的性能的稳定性。

这其中涉及到的Redo Log、UndoLog、行级锁、Buffer Pool(缓冲池)等概念我将会在后面的几篇文章里详细讲到。

2.为什么MySQL的索引结构用B+树?

之前我很容易把Mysql的底层数据结构Mysql的索引结构搞混,简单来说,Mysql的底层数据结构是MySQL 用来存储和管理数据的具体形式和方法,它包括索引的存储方式、数据的组织形式、磁盘管理策略等,不同的存储引擎(如 InnoDB 和 MyISAM)采用不同的底层数据结构。

底层数据结构包括以下内容:

  • 索引结构:B+树
  • 数据存储:聚簇索引与非聚簇索引
  • 数据页与磁盘管理策略:每次读取一个数据页,Buffer Pool缓冲机制
  • 日志机制:Redo Log & Undo Log

我们这里只探究索引结构。

MySQL5.5版本之后默认使用InnoDB存储引擎,对于InnoDB来说,可以用作索引结构的数据结构有很多,比如二叉树、红黑树、Hash表、B树、B树+,为什么MySQL的innoDB使用B+树呢?

在数据库系统中查询数据,我们需要磁盘I/O操作,但是I/O操作很消耗性能和时间,所以要减少单次I/O的时长或者I/O的次数,除此之外,所选择的数据结构可要高效处理范围查询的情况,所以我们可以从减少I/O次数和范围查询来答这个问题。

(1)对于二叉树和红黑树来说,它们的每个节点最多只有两个子节点,这使得树的高度容易过高,这意味着访问一个数据需要更多次磁盘 I/O(每个节点访问一次磁盘)。

MySQL 采用页(Page)作为磁盘管理的基本单位,每页默认大小为 16KB。B+ 树的节点大小也设计成与页大小相匹配,这种设计使得一个节点的读取恰好对应一次磁盘 I/O,避免了读半页或跨页读取的问题。

(2)Hash表的查找效率很高,但是只支持等值查询(如 =IN),不支持范围查询(如 BETWEEN 和排序)。而且Hash 表的散列函数导致数据随机分布,无法利用磁盘的顺序读写性能,导致 I/O 开销大。

(3)相对于红黑树,B树的一个节点可以有多个子节点,而B树的所有节点既存储索引,也存储实际的数据(data),这导致单个非叶子节点的大小变大,能容纳的子节点指针数变少,树的高度也随之增加,也就导致了更多的I/O次数。

​ 而且在B 树中,范围查询需要进行中序遍历,这意味着要频繁地跨节点访问,导致大量随机 I/O。

(4)而B+树的非叶子节点只存储索引,不存储实际的数据,所有的数据都存储在叶子节点,这使得非叶子节点能容纳更多的子节点指针,B+ 树的扇出率(即每个节点的子节点数量)大幅提高

​ 其次B+树的所有的叶子节点都通过双向链表连接,使得范围查询和顺序扫描的效率极高,只要找到范围查询的起点,之后就可以顺序遍历叶子节点的链表,无需返回上层节点进行重新搜索。

上面两张图我们还不太能看出来B树和B+树在扇出率和层级上的差别,这是因为数据量很小。我们可以举个例子,假设我们有一个 100 万条数据的表,现在用 B+ 树和 B 树来构建索引。

  • 节点大小: 每个节点的大小是 16KB(InnoDB 的默认配置)。
  • 索引指针大小: 每个索引指针是 8 字节。
  • 数据项大小: 假设每条数据的大小是 1KB(B 树节点要存储数据)。

我们可以来计算一下B树和B+树的性能

(1)每个节点能容纳多少个节点?

B树的每个节点存储一个数据项加上索引指针,大约需要 1KB + 8 字节 ≈ 1KB,保守估计,16KB 的节点最多可以容纳15个节点。

而B+树的每个非叶子节点只存储索引指针,16KB的节点最多可以容纳:16*1024/8=2048个索引指针,保守估计B+树可以容纳2000个子节点。

B+树 K.O. B树!

(2)100万条数据需要多少层?

B树每个节点只能容纳15个子节点,设B树需要n层才能覆盖100万条数据,通过计算15^(n-1)>100万,可以得到 n=7,也就是B树需要7层才能存储100万条数据。

B+树每个节点可以容纳2000个子节点,假设第1层根节点指向2000个子节点。第2层每个子节点再指向 2000 个子节点,所以第三层可以容纳:2000*2000=400万条数据,也就是说B+树三层节点就可以存储400万条数据。

(3)查询时间

每层节点访问一次磁盘 I/O。假设每次 I/O 花费 10ms,那么B+ 树3 层只需要3 次 I/O,总耗时约为 30ms。B 树7层需要7 次 I/O,总耗时约为 70ms。

所以,我们可以看到B+树通过更高的扇出率、更少的层级,显著减少了 I/O 次数,而其叶子节点的双向链表结构提升了顺序读取的性能,很适合范围查询。这两个优点让B+树在大规模数据场景下提供更高效的查询能力。

如果你觉得这篇文章对你有帮助,欢迎点赞、留言、转发

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com