一、MySQL 整体架构(物理文件 + 逻辑模块)
1. MySQL 物理文件组成
MySQL 的数据存储依赖三类核心文件,对应数据库目录(/var/lib/mysql/数据库名/):
| 文件类型 | 扩展名 | 作用 |
|---|---|---|
| 表结构文件 | .frm |
存储表的结构定义(字段名、类型、约束)(InnoDB 中表结构与数据共存) |
| 数据文件 | .ibd (InnoDB) / .MYD (MyISAM) |
存储表的实际数据InnoDB :主键聚集索引 + 数据存储在此MyISAM:单独存储数据 |
| 索引文件 | .ibd (InnoDB) / .MYI (MyISAM) |
存储表的索引结构InnoDB :索引与数据共存于聚集索引MyISAM:索引单独存储 |
2. MySQL 逻辑模块及协调工作(核心架构)
MySQL 架构分为 Server 层 (通用服务)和 存储引擎层(数据存储),模块间按流程协作:
- 连接层 (Connection Management):处理客户端连接、权限认证、超时管理。
- 服务层 (SQL Layer) (核心):
- 解析器 (Parser):解析 SQL 语句,生成解析树。
- 预处理器 (Preprocessor):检查解析树合法性,解析视图引用。
- 查询优化器 (Optimizer) :核心环节,基于成本(Cost)选择最优执行计划(如选择走哪个索引、如何关联表)。
- 查询缓存 (Query Cache)(8.0 已移除):缓存查询结果,5.7 及以下可用。
- 存储引擎层 (Storage Engines):负责数据的实际读写、事务、锁、索引实现。
- 文件系统 (File System):将数据 / 索引写入磁盘。
协调工作流:客户端连接 → 解析 SQL → 优化生成执行计划 → 调用存储引擎接口 → 读写磁盘 → 返回结果。
二、数据库存储引擎(核心对比)
存储引擎决定了表的数据存储方式、索引结构、事务支持、锁机制 ,MySQL 支持多种引擎,可通过 SHOW ENGINES; 查看。
1. 核心引擎对比表(面试必背)
| 特性 | InnoDB (默认) | MyISAM | MEMORY | MERGE |
|---|---|---|---|---|
| 事务支持 | ✅ 支持 (ACID) | ❌ 不支持 | ❌ 不支持 | ❌ 不支持 |
| 锁粒度 | 行级锁 (高并发) | 表级锁 (读写互斥) | 表级锁 | 表级锁 |
| 外键支持 | ✅ 支持 | ❌ 不支持 | ❌ 不支持 | ❌ 不支持 |
| 索引结构 | 聚簇索引 (B + 树) | 非聚簇索引 (B + 树) | 哈希索引 (默认) | 合并 MyISAM 表 |
| 存储位置 | 共享表空间 .ibd |
独立 .MYD/.MYI |
内存 (断电丢失) | 同 MyISAM |
| 适用场景 | 电商、金融、银行 (需事务 / 高并发) | 日志、报表 (读多写少) | 临时表、缓存 | 历史表归档 |
| 崩溃恢复 | ✅ 支持 (MVCC/redo log) | ❌ 不支持 (需修复) | 不适用 (内存) | 依赖底层 |
2. 各引擎详解
(1) InnoDB 存储引擎(MySQL 王者)
- 核心特性 :
- 事务安全 :完全支持 ACID 事务,提供
COMMIT/ROLLBACK。 - 行级锁:仅锁定被修改的行,极大提升多写并发性能。
- MVCC:多版本并发控制,解决幻读,实现高并发读。
- 聚簇索引:主键索引即数据文件,查询效率极高。
- 事务安全 :完全支持 ACID 事务,提供
- 创建语句 :
CREATE TABLE t1 (id INT) ENGINE=InnoDB;
(2) MyISAM 存储引擎(旧时代王者)
- 核心特性 :
- 查询极快:不支持事务,无锁开销,查询性能高。
- 表级锁:读写互斥,写操作会阻塞整个表,并发差。
- 全文索引 :支持
FULLTEXT全文检索。
- 适用:仅用于对数据一致性无要求、读多写少的场景(如日志表)。
(3) MEMORY 存储引擎(内存表)
- 核心特性 :数据存储在内存中,速度极快(毫秒级),但断电 / 重启数据丢失。
- 适用:临时表、缓存表、高频访问的小表。
- 限制 :不支持
TEXT/BLOB类型,最大大小由max_heap_table_size控制。
(4) MERGE 存储引擎
- 核心特性 :将多个 MyISAM 表 合并为一个逻辑表,用于分表管理(如按时间分区的日志表)。
- 适用:海量数据的归档查询,查询时需遍历所有子表。
三、MySQL 的锁定机制(行级 / 表级 / 页级)
锁是并发控制的核心,解决多事务同时读写数据的冲突问题。
1. 锁的分类
| 锁类型 | 粒度 | 并发性能 | 冲突概率 | 适用场景 |
|---|---|---|---|---|
| 行级锁 (Row Lock) | 锁定一行 | ⭐⭐⭐⭐⭐ (最高) | 低 | InnoDB 高并发写场景 |
| 表级锁 (Table Lock) | 锁定整张表 | ⭐⭐ (较低) | 高 | MyISAM、InnoDB 大范围更新 |
| 页级锁 (Page Lock) | 锁定一个数据页 (16KB) | ⭐⭐⭐ | 中 | BDB 存储引擎,InnoDB 内部管理 |
2. InnoDB 与 MyISAM 的锁机制对比
(1) MyISAM 的锁定机制
- 只有表级锁,没有行级锁。
- 机制 :当执行
SELECT时加读锁 (共享锁,多个事务可读),执行INSERT/UPDATE/DELETE时加写锁(排他锁,阻塞其他读写)。 - 问题 :写操作会阻塞所有其他操作,读多写少 场景尚可,高并发写场景性能极差。
(2) InnoDB 的锁定机制(重点)
InnoDB 支持 行级锁,但有前提条件:
- 必须使用索引 :行级锁仅针对索引字段生效。如果
WHERE条件无索引或索引失效,InnoDB 会退化为 表级锁。 - 锁模式 :
- 共享锁 (S Lock):读锁,多个事务可同时加锁读。
- 排他锁 (X Lock):写锁,阻塞其他读写锁。
- InnoDB 行级锁模式 :
- 记录锁 (Record Lock):锁定索引中的具体记录。
- 间隙锁 (Gap Lock):锁定索引区间,防止幻读(核心特性)。
- 临键锁 (Next-Key Lock):记录锁 + 间隙锁,是 InnoDB 默认的隔离级别(REPEATABLE READ)下防止幻读的手段。
四、一个查询 SQL 的执行过程
以 SELECT * FROM student WHERE id = 10; 为例,执行流程如下:
- 连接处理:客户端连接成功,发送 SQL 语句。
- 查询缓存(8.0 已移除):检查是否有缓存,有则直接返回。
- 解析与预处理 :
- 解析 SQL 语法,生成解析树。
- 检查表 / 字段是否存在。
- 优化器生成执行计划 :
- 分析成本,选择是否使用索引(如
id是主键,走主键索引)。 - 确定执行顺序(如先过滤后关联)。
- 分析成本,选择是否使用索引(如
- 执行计划调用 :
- 调用存储引擎接口。
- InnoDB 查找主键索引,定位到
id=10的行。
- 返回结果:将数据返回给客户端。
五、数据库范式
数据库范式(Normal Form)是设计数据库表结构的规则,用于减少数据冗余、避免更新异常。
1. 三大核心范式
| 范式 | 简称 | 核心规则 | 解决问题 |
|---|---|---|---|
| 第一范式 | 1NF | 原子性:列不可再分。例:地址字段拆分为省、市、区。 | 避免数据混乱 |
| 第二范式 | 2NF | 完全依赖 :非主键字段必须完全依赖于主键,不能仅依赖主键的一部分。例:联合主键 (stu_id, course_id),score 依赖整体主键,teacher_name 仅依赖 course_id → 需拆分。 |
解决部分依赖 |
| 第三范式 | 3NF | 传递依赖 :非主键字段不能依赖于其他非主键字段。例:学生表 (id, name, class_id),班级表 (class_id, class_name)。 |
解决传递依赖 |
2. 总结
实际开发中,遵循 3NF 即可,适度反范式化(如增加冗余字段)以提升查询性能是常见的优化手段。
六、核心总结
- 架构:Server 层负责解析 / 优化,存储引擎层负责读写。
- 存储引擎 :
- InnoDB:首选,支持事务、行锁、MVCC。
- MyISAM:弃用,仅用于特定只读场景。
- MEMORY:内存临时表。
- 锁:InnoDB 行级锁最高并发,但必须走索引;MyISAM 表级锁简单低效。
- 执行流程:解析 → 优化 → 执行 → 返回。
- 范式:1NF 原子,2NF 完全依赖,3NF 无传递依赖。