refactor: reorder MySQL docs by learning path
学习路径重排:SQL → 索引 → 存储引擎 → 表设计 → 事务 → 高可用 → 工程实践 关键改动: - 删除旧编号,全部按新学习顺序重新编号(01-40) - README 知识体系更新为 8 个渐进章节 - 每个章节增加了引导性说明文字 - 新增推荐学习顺序和新手/进阶/生产三条路线 - 修复了原顺序中 InnoDB(深)排在 SELECT(浅)之前的问题
This commit is contained in:
+117
-84
@@ -43,27 +43,80 @@ create time: 2026-05-16 00:00
|
||||
|
||||
## 知识体系
|
||||
|
||||
### 一、入门基础
|
||||
### 一、入门基础(了解 MySQL 是什么)
|
||||
|
||||
先装起来、连上去,知道能存什么类型的数据。
|
||||
|
||||
| # | 主题 | 说明 |
|
||||
|---|------|------|
|
||||
| 1.1 | [MySQL 架构概览](./01-MySQL 架构与进程模型.md) | MySQL 分几层(客户端 → SQL → 引擎 → 存储);`mysqld` 是怎么启动的 |
|
||||
| 1.2 | [安装与初始化](./02-安装与初始化.md) | 本地安装、Docker Compose 快速启动、基本配置文件 |
|
||||
| 1.3 | [客户端工具](./03-客户端工具.md) | 命令行 `mysql`、DBeaver、Workbench,选一个顺手的就行 |
|
||||
| 1.4 | [数据类型全景](./04-数据类型全景.md) | 整型、浮点、字符串、日期时间、JSON——每种类型适合存什么 |
|
||||
| 1.5 | [字符集与排序规则](./05-字符集与排序规则.md) | 为什么一定要用 `utf8mb4`、中文搜索不出来的坑 |
|
||||
| 1 | [MySQL 架构与入门](./01-MySQL 架构与入门.md) | MySQL 分几层(客户端 → SQL → 引擎 → 存储);`mysqld` 是怎么启动的 |
|
||||
| 2 | [安装与初始化](./02-安装与初始化.md) | 本地安装、Docker Compose 快速启动、基本配置文件 |
|
||||
| 3 | [客户端工具](./03-客户端工具.md) | 命令行 `mysql`、DBeaver、Workbench,选一个顺手的就行 |
|
||||
| 4 | [数据类型全景](./04-数据类型全景.md) | 整型、浮点、字符串、日期时间、JSON——每种类型适合存什么 |
|
||||
| 5 | [字符集与排序规则](./05-字符集与排序规则.md) | 为什么一定要用 `utf8mb4`、中文搜索不出来的坑 |
|
||||
|
||||
> [!TIP] 选择数据类型时,遵循「够用就好」原则
|
||||
> 能用 TINYINT 就别用 INT,能用 DATETIME 就别用 STRING 存日期——这直接影响索引效率和存储空间。
|
||||
|
||||
### 二、存储引擎与表设计
|
||||
### 二、SQL 核心(学会写最常用的语句)
|
||||
|
||||
建表、插数据、查数据——这是日常开发 90% 的时间在干的事。
|
||||
|
||||
| # | 主题 | 说明 |
|
||||
|---|------|------|
|
||||
| 2.1 | [InnoDB 深度解析](./06-InnoDB 深度解析.md) | InnoDB 是怎么存数据的、聚簇索引的工作原理、缓冲机制概览 |
|
||||
| 2.2 | [其他存储引擎概览](./07-其他存储引擎概览.md) | MyISAM / Memory / Archive 的适用场景,为什么生产几乎只用 InnoDB |
|
||||
| 2.3 | [表结构设计三范式](./08-表结构设计三范式.md) | 什么是 1NF / 2NF / 3NF、什么时候该故意违反范式 |
|
||||
| 2.4 | [主键策略对比](./09-主键策略对比.md) | 自增 ID、UUID、雪花算法——各自对性能的影响 |
|
||||
| 6 | [DDL — 建表与结构变更](./06-DDL 建表与结构变更.md) | 怎么创建和修改表结构、大表加字段会不会锁表 |
|
||||
| 7 | [DML — 增删改](./07-DML 增删改.md) | INSERT / UPDATE / DELETE 的常用技巧和坑 |
|
||||
| 8 | [DQL — SELECT 全解析](./08-DQL SELECT 全解析.md) | SELECT 的执行顺序、去重、分组、分页——查对数据是日常开发的核心能力 |
|
||||
| 9 | [JOIN 原理与优化](./09-JOIN 原理与优化.md) | 多张表怎么连起来查、Nested Loop 是怎么工作的 |
|
||||
| 10 | [子查询与派生表](./10-子查询与派生表.md) | WHERE / FROM 里的子查询什么时候用、EXISTS 和 IN 有什么区别 |
|
||||
| 11 | [UNION 与集合运算](./11-UNION 与集合运算.md) | 把多个查询结果合并在一起,去重 vs 保留重复怎么处理 |
|
||||
|
||||
### 三、索引与查询优化(让 SQL 跑得更快)
|
||||
|
||||
学会写 SQL 之后,下一步是让 SQL 跑得快的——这就是索引的意义。
|
||||
|
||||
| # | 主题 | 说明 |
|
||||
|---|------|------|
|
||||
| 12 | [B+Tree 索引原理](./12-B+Tree 索引原理.md) | MySQL 为什么选 B+ Tree、它比 Hash / 红黑树好在哪里 |
|
||||
| 13 | [聚簇索引与二级索引](./13-聚簇索引与二级索引.md) | 数据存在哪棵树上、查二级索引为什么要"回表" |
|
||||
| 14 | [联合索引与最左前缀](./14-联合索引与最左前缀.md) | 多个字段一起建索引怎么用、为什么跳列就用不上了 |
|
||||
| 15 | [EXPLAIN 完全指南](./15-EXPLAIN 完全指南.md) | 怎么看 SQL 的执行计划、type 从优到差排哪些 |
|
||||
| 16 | [慢查询日志分析](./16-慢查询日志分析.md) | 抓出执行慢的 SQL、用工具分析根因 |
|
||||
| 17 | [查询改写技巧](./17-查询改写技巧.md) | OR → UNION ALL、JOIN → EXISTS,同样的结果写法影响性能 |
|
||||
| 18 | [深分页优化](./18-深分页优化.md) | `LIMIT 1000000, 20` 为什么慢、怎么优化 |
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["SELECT 语句"] --> B["Parse Tree"]
|
||||
B --> C["Query Optimizer"]
|
||||
C --> D["Execution Plan"]
|
||||
D --> E{type}
|
||||
E -->|"system"<| F["最优:只有1行"]
|
||||
E -->|"const"<| G["常量访问"]
|
||||
E -->|"eq_ref"<| H["唯一索引,每行1次"]
|
||||
E -->|"ref"<| I["非唯一索引,多行匹配"]
|
||||
E -->|"range"<| J["索引范围扫描"]
|
||||
E -->|"index"<| K["全索引扫描"]
|
||||
E -->|"ALL"<| L["全表扫描 ⚠️"]
|
||||
style L fill:#EE5A24,color:#fff
|
||||
style F fill:#00B6BC,color:#fff
|
||||
```
|
||||
|
||||
> [!QUESTION] 什么是最左前缀法则?
|
||||
> 假设联合索引 `(city, age, sex)`,以下情况哪些能用上索引?
|
||||
> - `WHERE city = 'Shanghai'` ✅ 第一列命中
|
||||
> - `WHERE city = 'Shanghai' AND age = 20` ✅ 前两列连续命中
|
||||
> - `WHERE age = 20 AND sex = 'M'` ❌ 跳过了第一列 city
|
||||
> - `WHERE city = 'Shanghai' AND sex = 'M'` ⚠️ 用到 city 部分,sex 需额外过滤
|
||||
|
||||
### 四、存储引擎(InnoDB 到底是怎么存的?)
|
||||
|
||||
学会了怎么用,来看看底层是怎么存的。这部分不是必须立刻搞懂,但理解了会受益很多。
|
||||
|
||||
| # | 主题 | 说明 |
|
||||
|---|------|------|
|
||||
| 19 | [InnoDB 深度解析](./19-InnoDB 深度解析.md) | InnoDB 是怎么存数据的、聚簇索引的工作原理、缓冲机制概览 |
|
||||
| 20 | [其他存储引擎概览](./20-其他存储引擎概览.md) | MyISAM / Memory / Archive 的适用场景,为什么生产几乎只用 InnoDB |
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
@@ -100,63 +153,27 @@ graph TB
|
||||
> - **Redo Log**:操作日志,数据库崩溃了靠它恢复数据
|
||||
> - **Undo Log**:撤销日志,回滚和版本控制靠它
|
||||
|
||||
### 三、SQL 精解
|
||||
### 五、表设计(怎么设计一张好表)
|
||||
|
||||
设计先行,写好的表结构能省去后面大量的麻烦。
|
||||
|
||||
| # | 主题 | 说明 |
|
||||
|---|------|------|
|
||||
| 3.1 | [DDL — 建表与结构变更](./10-DDL 建表与结构变更.md) | 怎么创建和修改表结构、大表加字段会不会锁表 |
|
||||
| 3.2 | [DML — 增删改](./11-DML 增删改.md) | INSERT / UPDATE / DELETE 的常用技巧和坑 |
|
||||
| 3.3 | [DQL — SELECT 全解析](./12-DQL SELECT 全解析.md) | SELECT 的执行顺序、去重、分组、分页——查对数据是日常开发的核心能力 |
|
||||
| 3.4 | [JOIN 原理与优化](./13-JOIN 原理与优化.md) | 多张表怎么连起来查、Nested Loop 是怎么工作的 |
|
||||
| 3.5 | [子查询与派生表](./14-子查询与派生表.md) | WHERE / FROM 里的子查询什么时候用、EXISTS 和 IN 有什么区别 |
|
||||
| 3.6 | [UNION 与集合运算](./15-UNION 与集合运算.md) | 把多个查询结果合并在一起,去重 vs 保留重复怎么处理 |
|
||||
| 21 | [表结构设计三范式](./21-表结构设计三范式.md) | 什么是 1NF / 2NF / 3NF、什么时候该故意违反范式 |
|
||||
| 22 | [主键策略对比](./22-主键策略对比.md) | 自增 ID、UUID、雪花算法——各自对性能的影响 |
|
||||
|
||||
### 四、索引与查询优化
|
||||
### 六、事务与并发控制(保证数据不出错)
|
||||
|
||||
当多个用户同时操作数据时,如何保证数据不乱?这是进阶的必经之路。
|
||||
|
||||
| # | 主题 | 说明 |
|
||||
|---|------|------|
|
||||
| 4.1 | [B+ Tree 索引原理](./16-B+Tree 索引原理.md) | MySQL 为什么选 B+ Tree、它比 Hash / 红黑树好在哪里 |
|
||||
| 4.2 | [聚簇索引与二级索引](./17-聚簇索引与二级索引.md) | 数据存在哪棵树上、查二级索引为什么要"回表" |
|
||||
| 4.3 | [联合索引与最左前缀](./18-联合索引与最左前缀.md) | 多个字段一起建索引怎么用、为什么跳列就用不上了 |
|
||||
| 4.4 | [EXPLAIN 完全指南](./19-EXPLAIN 完全指南.md) | 怎么看 SQL 的执行计划、type 从优到差排哪些 |
|
||||
| 4.5 | [慢查询日志分析](./20-慢查询日志分析.md) | 抓出执行慢的 SQL、用工具分析根因 |
|
||||
| 4.6 | [查询改写技巧](./21-查询改写技巧.md) | OR → UNION ALL、JOIN → EXISTS,同样的结果写法影响性能 |
|
||||
| 4.7 | [深分页优化](./22-深分页优化.md) | `LIMIT 1000000, 20` 为什么慢、怎么优化 |
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["SELECT 语句"] --> B["Parse Tree"]
|
||||
B --> C["Query Optimizer"]
|
||||
C --> D["Execution Plan"]
|
||||
D --> E{type}
|
||||
E -->|"system"<| F["最优:只有1行"]
|
||||
E -->|"const"<| G["常量访问"]
|
||||
E -->|"eq_ref"<| H["唯一索引,每行1次"]
|
||||
E -->|"ref"<| I["非唯一索引,多行匹配"]
|
||||
E -->|"range"<| J["索引范围扫描"]
|
||||
E -->|"index"<| K["全索引扫描"]
|
||||
E -->|"ALL"<| L["全表扫描 ⚠️"]
|
||||
style L fill:#EE5A24,color:#fff
|
||||
style F fill:#00B6BC,color:#fff
|
||||
```
|
||||
|
||||
> [!QUESTION] 什么是最左前缀法则?
|
||||
> 假设联合索引 `(city, age, sex)`,以下情况哪些能用上索引?
|
||||
> - `WHERE city = 'Shanghai'` ✅ 第一列命中
|
||||
> - `WHERE city = 'Shanghai' AND age = 20` ✅ 前两列连续命中
|
||||
> - `WHERE age = 20 AND sex = 'M'` ❌ 跳过了第一列 city
|
||||
> - `WHERE city = 'Shanghai' AND sex = 'M'` ⚠️ 用到 city 部分,sex 需额外过滤
|
||||
|
||||
### 五、事务与并发控制
|
||||
|
||||
| # | 主题 | 说明 |
|
||||
|---|------|------|
|
||||
| 5.1 | [ACID 与原子性实现](./23-ACID 与原子性实现.md) | 什么是 ACID、Redo Log + Undo Log 怎么保证不出错 |
|
||||
| 5.2 | [隔离级别与可见性](./24-隔离级别与可见性.md) | 四个隔离级别各是什么意思,MySQL 默认的是哪个 |
|
||||
| 5.3 | [MVCC 原理](./25-MVCC 原理.md) | 不加锁也能并发读的秘密——多版本并发控制 |
|
||||
| 5.4 | [锁机制总览](./26-锁机制总览.md) | 从全局锁到行级锁,MySQL 在不同场景下锁什么 |
|
||||
| 5.5 | [死锁与排查](./27-死锁与排查.md) | 什么时候会发生死锁、怎么定位和避免 |
|
||||
| 5.6 | [一致性读 vs 当前读](./28-一致性读与当前读.md) | 普通 SELECT 读到什么、加 FOR UPDATE 又读到什么 |
|
||||
| 23 | [ACID 与原子性实现](./23-ACID 与原子性实现.md) | 什么是 ACID、Redo Log + Undo Log 怎么保证不出错 |
|
||||
| 24 | [隔离级别与可见性](./24-隔离级别与可见性.md) | 四个隔离级别各是什么意思,MySQL 默认的是哪个 |
|
||||
| 25 | [MVCC 原理](./25-MVCC 原理.md) | 不加锁也能并发读的秘密——多版本并发控制 |
|
||||
| 26 | [锁机制总览](./26-锁机制总览.md) | 从全局锁到行级锁,MySQL 在不同场景下锁什么 |
|
||||
| 27 | [死锁与排查](./27-死锁与排查.md) | 什么时候会发生死锁、怎么定位和避免 |
|
||||
| 28 | [一致性读 vs 当前读](./28-一致性读与当前读.md) | 普通 SELECT 读到什么、加 FOR UPDATE 又读到什么 |
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -179,16 +196,18 @@ sequenceDiagram
|
||||
> - **RC (Read Committed)**:每次查都能看到别的事务刚提交的数据 → 可能出现"不可重复读"
|
||||
> - **RR (Repeatable Read)**:整个事务内看到的是同一个快照 → 数据一致,这也是 MySQL 的默认设置
|
||||
|
||||
### 六、高可用与分布式
|
||||
### 七、高可用与分布式(让数据库永不宕机)
|
||||
|
||||
单台 MySQL 扛不住了怎么办?这就涉及到集群和复制。
|
||||
|
||||
| # | 主题 | 说明 |
|
||||
|---|------|------|
|
||||
| 6.1 | [Binary Log(Binlog)](./29-Binary Log.md) | Binlog 记录了所有写操作,主从复制和恢复都靠它 |
|
||||
| 6.2 | [主从复制详解](./30-主从复制详解.md) | 数据怎么从主库同步到从库、半同步 vs 异步的区别 |
|
||||
| 6.3 | [MHA 与 Orchestrator](./31-MHA与Orchestrator.md) | 主库挂了怎么自动切换到从库 |
|
||||
| 6.4 | [Group Replication](./32-Group Replication.md) | 多主同时写入、冲突怎么处理 |
|
||||
| 6.5 | [InnoDB Cluster](./33-InnoDB Cluster.md) | MySQL 官方的高可用集群方案 |
|
||||
| 6.6 | [备份与恢复](./34-备份与恢复.md) | 全量备份和增量备份、恢复到任意时间点 |
|
||||
| 29 | [Binary Log(Binlog)](./29-Binary Log.md) | Binlog 记录了所有写操作,主从复制和恢复都靠它 |
|
||||
| 30 | [主从复制详解](./30-主从复制详解.md) | 数据怎么从主库同步到从库、半同步 vs 异步的区别 |
|
||||
| 31 | [MHA 与 Orchestrator](./31-MHA与Orchestrator.md) | 主库挂了怎么自动切换到从库 |
|
||||
| 32 | [Group Replication](./32-Group Replication.md) | 多主同时写入、冲突怎么处理 |
|
||||
| 33 | [InnoDB Cluster](./33-InnoDB Cluster.md) | MySQL 官方的高可用集群方案 |
|
||||
| 34 | [备份与恢复](./34-备份与恢复.md) | 全量备份和增量备份、恢复到任意时间点 |
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
@@ -213,16 +232,18 @@ flowchart LR
|
||||
> - 至少 **一主两从**,读写分离时注意刚写的数据可能读不到(有延迟)
|
||||
> - 定期做 **灾备演练**,别等挂了才知道切换不成功
|
||||
|
||||
### 七、工程实践
|
||||
### 八、工程实践(生产环境中怎么管)
|
||||
|
||||
部署上线后,连接池怎么配、数据大了怎么拆、出了问题怎么排查。
|
||||
|
||||
| # | 主题 | 说明 |
|
||||
|---|------|------|
|
||||
| 7.1 | [Go 连接池配置](./35-Go 连接池配置.md) | `sql.DB` 几个关键参数的含义和调优思路 |
|
||||
| 7.2 | [Schema 迁移管理](./36-Schema 迁移管理.md) | 版本化的建表脚本、谁在用、怎么保证可回滚 |
|
||||
| 7.3 | [分库分表](./37-分库分表.md) | 数据量太大时怎么拆分、跨分片查询怎么办 |
|
||||
| 7.4 | [监控指标](./38-监控指标.md) | QPS/TPS、慢查询数、连接数——哪些数据决定数据库健康 |
|
||||
| 7.5 | [安全加固](./39-安全加固.md) | 权限管理、加密传输、SQL 注入防护 |
|
||||
| 7.6 | [常见踩坑](./40-常见踩坑.md) | ORDER BY 文件排序、COUNT 的区别、timestamp 自动更新 |
|
||||
| 35 | [Go 连接池配置](./35-Go 连接池配置.md) | `sql.DB` 几个关键参数的含义和调优思路 |
|
||||
| 36 | [Schema 迁移管理](./36-Schema 迁移管理.md) | 版本化的建表脚本、谁在用、怎么保证可回滚 |
|
||||
| 37 | [分库分表](./37-分库分表.md) | 数据量太大时怎么拆分、跨分片查询怎么办 |
|
||||
| 38 | [监控指标](./38-监控指标.md) | QPS/TPS、慢查询数、连接数——哪些数据决定数据库健康 |
|
||||
| 39 | [安全加固](./39-安全加固.md) | 权限管理、加密传输、SQL 注入防护 |
|
||||
| 40 | [常见踩坑](./40-常见踩坑.md) | ORDER BY 文件排序、COUNT 的区别、timestamp 自动更新 |
|
||||
|
||||
[[hhs/DEV/Go-Database]] — Go 中 sql.DB 的连接池使用模式
|
||||
|
||||
@@ -230,21 +251,33 @@ flowchart LR
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
BASE["一、入门基础<br/>架构 + 数据类型"] --> CORE["二、存储引擎与表设计"]
|
||||
CORE --> SQL["三、SQL 精解<br/>DDL/DML/DQL"]
|
||||
SQL --> INDEX["四、索引与查询优化"]
|
||||
SQL --> TXN["五、事务与并发控制"]
|
||||
INDEX --> HA["六、高可用与分布式"]
|
||||
BASE["一、入门基础<br/>架构 + 数据类型"] --> SQL["二、SQL 核心<br/>DDL/DML/DQL"]
|
||||
SQL --> INDEX["三、索引与优化<br/>B+Tree/EXPLAIN/改写"]
|
||||
INDEX --> ENGINE["四、存储引擎<br/>InnoDB底层"]
|
||||
INDEX --> DESIGN["五、表设计<br/>范式/主键"]
|
||||
SQL --> TXN["六、事务与并发<br/>ACID/MVCC/锁"]
|
||||
INDEX --> HA["七、高可用与分布式<br/>复制/集群/备份"]
|
||||
TXN --> HA
|
||||
HA --> ENG["七、工程实践<br/>分库分表 + 监控 + 安全"]
|
||||
ENGINE --> PROD["八、工程实践<br/>连接池/监控/分库分表"]
|
||||
DESIGN --> PROD
|
||||
HA --> PROD
|
||||
|
||||
style BASE fill:#00B6BC,color:#fff
|
||||
style SQL fill:#4FC08D,color:#000
|
||||
style INDEX fill:#FF9F43,color:#000
|
||||
style TXN fill:#C44569,color:#fff
|
||||
style HA fill:#4FC08D,color:#fff
|
||||
style ENG fill:#EE5A24,color:#fff
|
||||
style ENGINE fill:#C44569,color:#fff
|
||||
style DESIGN fill:#A0AEC0,color:#000
|
||||
style TXN fill:#EE5A24,color:#fff
|
||||
style HA fill:#0097E6,color:#fff
|
||||
style PROD fill:#4A4A4A,color:#fff
|
||||
```
|
||||
|
||||
**推荐学习顺序**:`一 → 二 → 三 → 六 → 四 → 五 → 七 → 八`
|
||||
|
||||
> - **新手**:一 → 二 → (够用)
|
||||
> - **进阶**:一 → 二 → 三 → 六 → 四 → 五
|
||||
> - **生产环境**:全学,重点在 三、六、七、八
|
||||
|
||||
## 关联笔记
|
||||
|
||||
- [[hhs/GORM/02-模型定义]] — GORM Model 如何映射到 MySQL 表和字段类型
|
||||
|
||||
Reference in New Issue
Block a user