这些知识点你都掌握了吗?大家可以对着问题看下自己掌握程度如何?对于没掌握的知识点,大家自行网上搜索,都会有对应答案,本文不做知识点详细说明,只做简要文字或图示引导。
1 基础
1.1内部组件结构
1.2 数据类型选择
1.3 一行记录是怎么存储的?
InnoDB 提供了 4 种行格式,分别是 Redundant、Compact、Dynamic和 Compressed 行格式。
Compact 行格式长什么样?
「变长字段长度列表」中的信息之所以要逆序存放,是因为这样可以使得位置靠前的记录的真实数据和数据对应的字段长度信息可以同时在一个 CPU Cache Line 中,这样就可以提高 CPU Cache 的命中率。
当数据表的字段都定义成 NOT NULL 的时候,这时候表里的行格式就不会有 NULL 值列表了。所以在设计数据库表的时候,通常都是建议将字段设置为 NOT NULL,这样可以至少节省 1 字节的空间。
MySQL 规定除了 TEXT、BLOBs 这种大对象类型之外,其他所有的列(不包括隐藏列和记录头信息)占用的字节长度加起来不能超过 65535 个字节。
2 常见的存储引擎
2.1 InnoDB 存储引擎
表存储在磁盘中,用两个文件存储数据 xx.frm(表结构文件),xx.idb (数据文件+索引文件)。
3 索引
3.1 索引数据结构
为什么 MySQL InnoDB 选择B+Tree 作为索引的数据结构?
MySQL 单表不要超过2000w行,靠谱吗?
MySQL 默认页文件大小 16K。
假设一行数据大小为1K,那么一页就能存16条数据,也就是一个叶子节点能存16条数据;
再看非叶子节点,假设主键为 bigInt 类型,即长度为 8B,指针大小在 Innodb 源码中为 6B,一共就是14B,那么一页里就可以存储 16K/14=1170个(主键+指针)。
一颗高度为3的 B+ 树能存储的数据为:1170*_1170*_16 = 21902400。
3.2 索引设计原则
3.3 索引优化方法
4 事务
5 锁
6 日志
更新语句的流程会涉及到 undo log(回滚日志)、redo log(重做日志) 、binlog (归档日志)这三种日志:
- undo log(回滚日志):是 Innodb 存储引擎层生成的日志,实现了事务中的原子性,主要用于事务回滚和 MVCC。
- redo log(重做日志):是 Innodb 存储引擎层生成的日志,实现了事务中的持久性,主要用于掉电等故障恢复;
- binlog (归档日志):是 Server 层生成的日志,主要用于数据备份和主从复制;
7 两种机制
7.1 MVVC 机制
实现原理
通过 read-view 机制与 undo 版本链比对机制,使得不同的事务会根据数据版本链对比规则读取同一条数据在版本链上的不同版本数据
read view
可重复读隔离级别中,当事务开启后,执行任何查询SQL(innoDB)时就会生成当前事务的一致性视图 read-view,该视图在事务结束之前都不会变化。
read view的组成:执行查询时所有未提交事务id数组_和已创建的最大事务id_组成。
7.2 Buffer Pool缓存机制
7.2.1 为什么要有 Buffer Pool?
保证每个更新请求都是更新内存BufferPool,然后顺序写日志文件,同时还能在各种异常情况下也保证数据的一致性。
更新内存性能极高,顺序写效率也远高于随机读写磁盘文件。BufferPool机制使得MySQL在较高配置的机器上每秒可以并发几千的读写请求。
7.2.2 Buffer Pool 有多大?
默认只有128MB,可以调整 innodb_buffer_pool_size 设置大小,一般建议设置成物理内存的60%-80%。
7.2.3 Buffer Pool 缓存什么?
Buffer Pool 除了缓存「索引页」和「数据页」,还包括了 undo 页,插入缓存、自适应哈希索引、锁信息等等。