Files
cs-note/hhs/MySQL/README.md
T
2026-05-24 11:42:38 +08:00

287 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
tags: [MySQL, Database, SQL, RDBMS]
create time: 2026-05-16 00:00
---
# MySQL 知识库
## 概述
本文件夹系统整理 MySQL 的核心知识点。MySQL 是目前世界上最流行的关系型数据库,几乎所有后端项目都在用它——存用户数据、订单记录、配置信息……本质上它就是**一个帮你安全存放和查询数据的程序**。
### 从零开始的三条学习路线
```
路线 A(日常开发) 路线 B(深入原理) 路线 C(运维 & 高可用)
↓ ↓ ↓
基础语法 → SQL 查询 存储引擎 / 索引底层 主从复制 / 备份恢复
表设计 → CRUD 操作 事务 / 隔离级别 / MVCC 高可用方案 / 故障切换
连接池 → ORM 框架 EXPLAIN / 慢查询优化 监控 / 分库分表
```
> [!QUESTION] 怎么选?
> - **如果你是刚入门的后端开发**:走路线 A 就够了,搞定增删改查和表设计就能上手干活
> - **如果你想面试大厂或解决线上性能问题**:继续走路线 B,理解索引和事务底层原理
> - **如果你要负责生产环境运维**:路线 C 是必修课,主从、备份、故障切换一个不能少
> - **理想状态**:A → B → C,循序渐进
### 核心概念速览(不用现在全懂)
下面的术语你在后面会逐一遇到,先有个印象就行:
| 概念 | 一句话理解 |
|------|-----------|
| **数据库 (Database)** | 存放表的容器,类似一个项目文件夹 |
| **表 (Table)** | 按行和列组织的数据,像 Excel 表格 |
| **SQL** | 跟数据库沟通的语言,比如"把这条数据查出来" |
| **索引 (Index)** | 书的目录,让查找更快,不加索引就像一页页翻书 |
| **事务 (Transaction)** | 一组操作要么全部成功、要么全部回滚,保证数据不出错 |
| **InnoDB** | MySQL 默认的存储引擎,支持事务、行锁,生产环境几乎都用它 |
> [!TIP] 学习建议
> 不要试图一口气吃成胖子。先学会写 `SELECT` 和 `INSERT`,看到能查出数据,再慢慢往下挖。每一个高级主题(比如事务隔离级别)都建立在前面的基础之上。
## 知识体系
### [一、入门基础(了解 MySQL 是什么)](./01-入门基础/README.md)
先装起来、连上去,知道能存什么类型的数据。
| # | 主题 | 说明 |
|---|------|------|
| 1 | [MySQL 架构与入门](./01-入门基础/01-MySQL 架构与入门.md) | MySQL 分几层(客户端 → SQL → 引擎 → 存储);`mysqld` 是怎么启动的 |
| 2 | [安装与初始化](./01-入门基础/02-安装与初始化.md) | 本地安装、Docker Compose 快速启动、基本配置文件 |
| 3 | [客户端工具](./01-入门基础/03-客户端工具.md) | 命令行 `mysql`、DBeaver、Workbench,选一个顺手的就行 |
| 4 | [数据类型全景](./01-入门基础/04-数据类型全景.md) | 整型、浮点、字符串、日期时间、JSON——每种类型适合存什么 |
| 5 | [字符集与排序规则](./01-入门基础/05-字符集与排序规则.md) | 为什么一定要用 `utf8mb4`、中文搜索不出来的坑 |
> [!TIP] 选择数据类型时,遵循「够用就好」原则
> 能用 TINYINT 就别用 INT,能用 DATETIME 就别用 STRING 存日期——这直接影响索引效率和存储空间。
### [二、SQL 核心(学会写最常用的语句)](./02-SQL核心/README.md)
建表、插数据、查数据——这是日常开发 90% 的时间在干的事。
| # | 主题 | 说明 |
|---|------|------|
| 6 | [DDL — 建表与结构变更](./02-SQL核心/06-DDL 建表与结构变更.md) | 怎么创建和修改表结构、大表加字段会不会锁表 |
| 7 | [DML — 增删改](./02-SQL核心/07-DML 增删改.md) | INSERT / UPDATE / DELETE 的常用技巧和坑 |
| 8 | [DQL — SELECT 全解析](./02-SQL核心/08-DQL SELECT 全解析.md) | SELECT 的执行顺序、去重、分组、分页——查对数据是日常开发的核心能力 |
| 9 | [JOIN 原理与优化](./02-SQL核心/09-JOIN 原理与优化.md) | 多张表怎么连起来查、Nested Loop 是怎么工作的 |
| 10 | [子查询与派生表](./02-SQL核心/10-子查询与派生表.md) | WHERE / FROM 里的子查询什么时候用、EXISTS 和 IN 有什么区别 |
| 11 | [UNION 与集合运算](./02-SQL核心/11-UNION 与集合运算.md) | 把多个查询结果合并在一起,去重 vs 保留重复怎么处理 |
### [三、索引与查询优化(让 SQL 跑得更快)](./03-索引与查询优化/README.md)
学会写 SQL 之后,下一步是让 SQL 跑得快的——这就是索引的意义。
| # | 主题 | 说明 |
|---|------|------|
| 12 | [B+Tree 索引原理](./03-索引与查询优化/12-B+Tree 索引原理.md) | MySQL 为什么选 B+ Tree、它比 Hash / 红黑树好在哪里 |
| 13 | [聚簇索引与二级索引](./03-索引与查询优化/13-聚簇索引与二级索引.md) | 数据存在哪棵树上、查二级索引为什么要"回表" |
| 14 | [联合索引与最左前缀](./03-索引与查询优化/14-联合索引与最左前缀.md) | 多个字段一起建索引怎么用、为什么跳列就用不上了 |
| 15 | [EXPLAIN 完全指南](./03-索引与查询优化/15-EXPLAIN 完全指南.md) | 怎么看 SQL 的执行计划、type 从优到差排哪些 |
| 16 | [慢查询日志分析](./03-索引与查询优化/16-慢查询日志分析.md) | 抓出执行慢的 SQL、用工具分析根因 |
| 17 | [查询改写技巧](./03-索引与查询优化/17-查询改写技巧.md) | OR → UNION ALL、JOIN → EXISTS,同样的结果写法影响性能 |
| 18 | [深分页优化](./03-索引与查询优化/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 到底是怎么存的?)](./04-存储引擎/README.md)
学会了怎么用,来看看底层是怎么存的。这部分不是必须立刻搞懂,但理解了会受益很多。
| # | 主题 | 说明 |
|---|------|------|
| 19 | [InnoDB 深度解析](./04-存储引擎/19-InnoDB 深度解析.md) | InnoDB 是怎么存数据的、聚簇索引的工作原理、缓冲机制概览 |
| 20 | [其他存储引擎概览](./04-存储引擎/20-其他存储引擎概览.md) | MyISAM / Memory / Archive 的适用场景,为什么生产几乎只用 InnoDB |
```mermaid
graph TB
subgraph "SQL Layer"
A["Parser"] --> B["Preprocessor"]
B --> C["Optimizer"]
C --> D["Executor"]
end
subgraph "Storage Engine<br/>InnoDB"
D --> E["Buffer Pool"]
E --> F["Redo Log"]
E --> G["Undo Log"]
E --> H["Data File"]
D --> I["Change Buffer"]
end
subgraph "OS Layer"
H --> J["Page Cache"]
F --> K["I/O Subsystem"]
G --> K
end
style A fill:#4FC08D,color:#fff
style C fill:#FF9F43,color:#000
style E fill:#00B6BC,color:#fff
style F fill:#EE5A24,color:#fff
style G fill:#C44569,color:#fff
style H fill:#A0AEC0,color:#fff
```
> [!NOTE] InnoDB 的三个关键机制(先有个印象,后面详解)
> - **Buffer Pool**:内存里的"草稿纸",频繁访问的数据先放这里,减少磁盘读取
> - **Redo Log**:操作日志,数据库崩溃了靠它恢复数据
> - **Undo Log**:撤销日志,回滚和版本控制靠它
### [五、表设计(怎么设计一张好表)](./05-表设计/README.md)
设计先行,写好的表结构能省去后面大量的麻烦。
| # | 主题 | 说明 |
|---|------|------|
| 21 | [表结构设计三范式](./05-表设计/21-表结构设计三范式.md) | 什么是 1NF / 2NF / 3NF、什么时候该故意违反范式 |
| 22 | [主键策略对比](./05-表设计/22-主键策略对比.md) | 自增 ID、UUID、雪花算法——各自对性能的影响 |
### [六、事务与并发控制(保证数据不出错)](./06-事务与并发控制/README.md)
当多个用户同时操作数据时,如何保证数据不乱?这是进阶的必经之路。
| # | 主题 | 说明 |
|---|------|------|
| 23 | [ACID 与原子性实现](./06-事务与并发控制/23-ACID 与原子性实现.md) | 什么是 ACID、Redo Log + Undo Log 怎么保证不出错 |
| 24 | [隔离级别与可见性](./06-事务与并发控制/24-隔离级别与可见性.md) | 四个隔离级别各是什么意思,MySQL 默认的是哪个 |
| 25 | [MVCC 原理](./06-事务与并发控制/25-MVCC 原理.md) | 不加锁也能并发读的秘密——多版本并发控制 |
| 26 | [锁机制总览](./06-事务与并发控制/26-锁机制总览.md) | 从全局锁到行级锁,MySQL 在不同场景下锁什么 |
| 27 | [死锁与排查](./06-事务与并发控制/27-死锁与排查.md) | 什么时候会发生死锁、怎么定位和避免 |
| 28 | [一致性读 vs 当前读](./06-事务与并发控制/28-一致性读与当前读.md) | 普通 SELECT 读到什么、加 FOR UPDATE 又读到什么 |
```mermaid
sequenceDiagram
participant T1 as Transaction A
participant DB as InnoDB Engine
participant T2 as Transaction B
T1->>DB: BEGIN;
T2->>DB: BEGIN;
T1->>DB: SELECT balance FROM accounts WHERE id=1;
Note over T1,DB: 一致性读 → 返回历史版本(快照)
T2->>DB: UPDATE accounts SET balance=100 WHERE id=1;
T2->>DB: COMMIT;
T1->>DB: SELECT balance FROM accounts WHERE id=1 FOR UPDATE;
Note over T1,DB: 当前读 → 读取最新已提交记录 + X锁
T1->>DB: COMMIT;
```
> [!NOTE] RC vs RR 的关键区别(面试常考)
> - **RC (Read Committed)**:每次查都能看到别的事务刚提交的数据 → 可能出现"不可重复读"
> - **RR (Repeatable Read)**:整个事务内看到的是同一个快照 → 数据一致,这也是 MySQL 的默认设置
### [七、高可用与分布式(让数据库永不宕机)](./07-高可用与分布式/README.md)
单台 MySQL 扛不住了怎么办?这就涉及到集群和复制。
| # | 主题 | 说明 |
|---|------|------|
| 29 | [Binary Log(Binlog)](./07-高可用与分布式/29-Binary Log.md) | Binlog 记录了所有写操作,主从复制和恢复都靠它 |
| 30 | [主从复制详解](./07-高可用与分布式/30-主从复制详解.md) | 数据怎么从主库同步到从库、半同步 vs 异步的区别 |
| 31 | [MHA 与 Orchestrator](./07-高可用与分布式/31-MHA与Orchestrator.md) | 主库挂了怎么自动切换到从库 |
| 32 | [Group Replication](./07-高可用与分布式/32-Group Replication.md) | 多主同时写入、冲突怎么处理 |
| 33 | [InnoDB Cluster](./07-高可用与分布式/33-InnoDB Cluster.md) | MySQL 官方的高可用集群方案 |
| 34 | [备份与恢复](./07-高可用与分布式/34-备份与恢复.md) | 全量备份和增量备份、恢复到任意时间点 |
```mermaid
flowchart LR
subgraph "Master"
W["Write / DML"] --> WL["Binlog Writer"]
end
subgraph "Network"
BL["Binlog Stream"] --> IO["IO Thread"]
end
subgraph "Slave"
IO --> SL["SQL Thread"]
SL --> SF["Slave Status Variables"]
end
WL -.->|异步/半同步| BL
SF -.->|Seconds_Behind_Master| Monitor["Monitoring"]
```
> [!TIP] 生产环境的主从架构建议
> - 至少 **一主两从**,读写分离时注意刚写的数据可能读不到(有延迟)
> - 定期做 **灾备演练**,别等挂了才知道切换不成功
### [八、工程实践(生产环境中怎么管)](./08-工程实践/README.md)
部署上线后,连接池怎么配、数据大了怎么拆、出了问题怎么排查。
| # | 主题 | 说明 |
|---|------|------|
| 35 | [Go 连接池配置](./08-工程实践/35-Go 连接池配置.md) | `sql.DB` 几个关键参数的含义和调优思路 |
| 36 | [Schema 迁移管理](./08-工程实践/36-Schema 迁移管理.md) | 版本化的建表脚本、谁在用、怎么保证可回滚 |
| 37 | [分库分表](./08-工程实践/37-分库分表.md) | 数据量太大时怎么拆分、跨分片查询怎么办 |
| 38 | [监控指标](./08-工程实践/38-监控指标.md) | QPS/TPS、慢查询数、连接数——哪些数据决定数据库健康 |
| 39 | [安全加固](./08-工程实践/39-安全加固.md) | 权限管理、加密传输、SQL 注入防护 |
| 40 | [常见踩坑](./08-工程实践/40-常见踩坑.md) | ORDER BY 文件排序、COUNT 的区别、timestamp 自动更新 |
[[hhs/DEV/Go-Database]] — Go 中 sql.DB 的连接池使用模式
## 学习路径建议
```mermaid
flowchart TD
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
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 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 表和字段类型
- [[hhs/Redis/02-核心数据类型]] — MySQL 与 Redis 数据类型的对应关系和设计选型
- [[hhs/DEV/Go-Database]] — Go 连接 MySQL 的工程实践
- [[hhs/EXAM/Week05]] — Docker Compose 中的 MySQL 服务管理