数据库学习路线
数据库不能只学“会写 SQL”。商业项目真正需要的是:能设计表、能解释索引为什么快、能看懂执行计划、能处理事务并发、能做备份恢复、能定位线上慢查询和锁等待,还要知道不同数据库为什么会有不同实现。
一句话先建立全局认识:
关系型数据库的核心任务是:把结构化数据可靠地保存起来,让业务在并发读写、机器故障、数据增长的情况下,仍然能查得准、写得对、恢复得回来。
学习目标
学完数据库主线,你要能做到:
- 从零写出正确的建表 SQL、查询 SQL、分页 SQL 和事务代码。
- 解释一条 SQL 从客户端到数据库内部的执行全过程。
- 解释索引、B+Tree、B-Tree、Hash、Bitmap、GIN、GiST 等索引为什么适合不同场景。
- 看懂
EXPLAIN、EXPLAIN ANALYZE、执行计划算子、估算行数和真实行数差异。 - 理解事务 ACID、隔离级别、锁、MVCC、undo、redo、binlog、WAL、SCN、事务日志。
- 能处理慢 SQL、锁等待、死锁、主从延迟、版本膨胀、大表、深分页、备份恢复。
- 能根据商业场景选择 MySQL、PostgreSQL、Oracle、SQL Server、MongoDB、Redis、Elasticsearch 的边界。
如果你是零基础,或者学了几个数据库仍然串不起来,先看这篇总原理:关系型数据库底层原理从零到生产级掌握。它把 SQL 层、优化器、执行器、页、索引、缓存、事务、MVCC、日志和 MySQL / PostgreSQL / Oracle / SQL Server 差异放在一条主线里讲。
如果你已经学过 MySQL,但不清楚 Oracle、PostgreSQL、SQL Server 为什么叫法和排查方式不同,再看:MySQL、PostgreSQL、Oracle、SQL Server 核心差异与选型。这篇专门讲 B+Tree/B-tree、日志、MVCC、执行计划、商业选型和迁移坑,避免把不同数据库硬背成孤立知识点。
如果你想判断“看完这些到底算不算学会”,看:数据库从零到精通验收路线。这篇把 SQL、表设计、索引、执行计划、事务、日志、四大关系库差异、商业项目训练和面试闭环拆成可验证任务。
如果你不想只停留在“看懂概念”,而是要按商业项目一步步练出来,继续看:关系型数据库商业场景训练营。它用订单支付、用户订单列表、医疗资产采集、库存扣减、四大数据库建表差异、UPDATE 原理和慢 SQL 排查,把知识点变成可执行训练。
数据库先学什么
零基础不要一上来背“MVCC、WAL、redo、undo”。推荐按这个顺序学:
flowchart TD
A["SQL 基础<br/>增删改查、过滤、排序、分页"] --> B["表设计<br/>字段类型、主键、唯一约束、范式"]
B --> C["索引基础<br/>为什么索引能减少扫描"]
C --> D["执行计划<br/>数据库准备怎么查"]
D --> E["事务并发<br/>ACID、隔离级别、锁、MVCC"]
E --> F["日志恢复<br/>redo、undo、binlog、WAL、事务日志"]
F --> G["高可用<br/>主从复制、备份恢复、故障切换"]
G --> H["性能治理<br/>慢 SQL、大表、分库分表、归档"]这条路线的原因是:先会写 SQL,才知道数据库要处理什么请求;先理解表和索引,才看得懂执行计划;先理解执行计划,才知道慢 SQL 慢在哪里;先理解事务和日志,才知道并发和故障时为什么不会乱。
数据库核心流程图
一条业务请求访问数据库,通常不是“代码直接读硬盘”,而是经过多层组件:
flowchart TD
A["业务接口<br/>Controller / API"] --> B["Service 事务边界"]
B --> C["ORM 或 JDBC<br/>MyBatis / JPA / JDBC"]
C --> D["连接池<br/>HikariCP 等"]
D --> E["数据库连接层<br/>认证、权限、会话"]
E --> F["SQL 层<br/>解析、优化、执行计划"]
F --> G["存储引擎<br/>索引、页、缓存、锁、MVCC"]
G --> H["日志与磁盘<br/>数据文件、事务日志、复制日志"]每层都可能出问题:
| 层 | 常见问题 | 排查方向 |
|---|---|---|
| 业务层 | 循环查库、N+1、事务包太大 | 看代码链路、接口耗时、SQL 次数 |
| ORM/JDBC | 批量变单条、未分页、大结果集 | 打印 SQL、看参数、看 fetch size |
| 连接池 | 连接耗尽、泄漏、等待连接 | 连接池监控、活跃连接、等待队列 |
| SQL 层 | 计划选错、排序、临时表 | EXPLAIN、统计信息、索引 |
| 存储引擎 | 锁等待、回表多、缓存未命中 | 锁表、事务表、Buffer 命中率 |
| 日志磁盘 | 提交慢、复制延迟、恢复慢 | redo/WAL/binlog、磁盘延迟、大事务 |
关系型数据库共同知识
无论学 MySQL、PostgreSQL、Oracle 还是 SQL Server,都要先掌握这些共同概念。
| 知识点 | 必须理解什么 | 不理解会怎样 |
|---|---|---|
| 表和约束 | 主键、唯一、非空、外键、默认值 | 数据重复、脏数据只能靠应用兜底 |
| 数据类型 | 字符串、数字、时间、精度、编码 | 金额精度错误、索引变大、比较异常 |
| 索引 | 索引是有序数据结构,不是魔法 | 乱加索引,写入变慢,慢 SQL 仍然慢 |
| 执行计划 | 数据库会估算不同路径成本 | 有索引不用索引时无法解释 |
| 事务 | 多条 SQL 组成一个原子操作 | 订单扣款、库存扣减容易不一致 |
| 锁 | 写写冲突、当前读、范围保护 | 死锁、阻塞、超卖问题不会排查 |
| MVCC/版本 | 读写尽量不互相阻塞 | 长事务、版本膨胀、undo 堆积看不懂 |
| 日志 | 提交、回滚、恢复、复制依赖日志 | 宕机恢复、主从同步、误删恢复讲不清 |
| 备份恢复 | 备份不是复制文件那么简单 | 误删后无法恢复到指定时间点 |
主流数据库怎么选
商业项目选数据库,不能只看“哪个性能最好”。要看业务模型、团队经验、生态、成本、稳定性和运维能力。
| 数据库 | 更适合 | 不适合误用成 |
|---|---|---|
| MySQL | 互联网业务、订单、支付、库存、用户、后台系统 | 复杂分析型仓库、无限日志库 |
| PostgreSQL | 复杂 SQL、GIS、JSONB、报表、强约束、扩展能力 | 纯缓存、大规模全文检索主力 |
| Oracle | 金融、政企、运营商、大型核心交易、高可用强要求 | 小团队低成本轻量项目 |
| SQL Server | .NET 企业系统、微软生态、报表和 BI | 跨平台轻量互联网首选 |
| MongoDB | 文档模型、灵活字段、内容系统、事件文档 | 强事务强 Join 的核心关系模型 |
| Redis | 缓存、分布式锁、计数、限流、热点数据 | 主要持久化关系数据库 |
四大关系库课程入口
如果目标是“从零学到能面试、能写项目、能排查线上问题”,不要只点某个零散知识点。建议按下面入口走完整链路:
| 方向 | 先学什么 | 再学什么 | 最后验收 |
|---|---|---|---|
| MySQL | SQL、表设计、B+Tree、EXPLAIN | InnoDB、事务、MVCC、redo/undo/binlog、主从复制 | 能处理慢 SQL、大表、锁等待、主从延迟 |
| PostgreSQL | Schema、类型、B-tree/GIN、EXPLAIN ANALYZE | tuple 多版本、VACUUM、WAL、锁、复制 | 能处理膨胀、长事务、Index Only Scan、WAL 延迟 |
| Oracle | 用户、表空间、对象、B-tree、ROWID | SGA/PGA、Undo、Redo、SCN、等待事件 | 能处理锁等待、snapshot too old、Redo/TEMP/AWR |
| SQL Server | T-SQL、页、聚集索引、非聚集索引 | Transaction Log、锁、RCSI、TempDB、参数嗅探 | 能处理 Key Lookup、阻塞、死锁、TempDB、日志暴涨 |
四个专栏的首页都已经按“课程地图 + 原理页 + 商业 Demo + 面试跳转”组织。面试时先用对应面试页给标准回答,追问原理时跳回知识点页讲全过程。
MySQL、PostgreSQL、Oracle、SQL Server 的本质区别
它们都支持 SQL 和事务,但内部实现差异很大。
| 维度 | MySQL InnoDB | PostgreSQL | Oracle | SQL Server |
|---|---|---|---|---|
| 常见定位 | Web 业务主库 | 标准 SQL、扩展、复杂查询 | 企业核心商业数据库 | 微软生态企业数据库 |
| 默认索引叫法 | B+Tree | B-tree | B-tree | B-tree |
| 数据版本 | undo log 版本链 | tuple 多版本 | Undo + SCN 一致性读 | 锁或行版本 |
| 主要恢复日志 | redo log | WAL | Redo | Transaction Log |
| 复制日志 | binlog | WAL 流复制 | Redo/归档日志/Data Guard | Transaction Log/Always On |
| 运维重点 | Buffer Pool、binlog、主从延迟 | VACUUM、膨胀、WAL | Undo/Redo/SCN、AWR、RAC | TempDB、等待、参数嗅探 |
注意:很多数据库文档把 B+Tree 也称为 B-tree 家族索引。MySQL 教材常强调 B+Tree,是为了突出叶子节点保存数据或主键并适合范围扫描;Oracle、PostgreSQL、SQL Server 官方文档常说 B-tree,并不代表它们使用普通教科书里“数据分散在所有节点”的二叉树或简单 B 树。
从查询到优化的学习闭环
学习数据库必须形成闭环,而不是背概念。
flowchart TD
A["写出业务 SQL"] --> B["用真实数据量执行"]
B --> C["查看执行计划"]
C --> D["判断访问路径"]
D --> E["分析扫描行数、排序、回表、Join"]
E --> F["调整 SQL、索引、表设计或架构"]
F --> G["重新验证耗时和计划"]
G --> H["沉淀监控和排查手册"]如果跳过执行计划,只靠感觉优化,会出现:
- 给低区分度字段加索引,优化器仍然不用。
- 单列索引很多,但没有一个匹配真实联合查询。
- 覆盖索引减少了回表,但扫描范围仍然很大。
- 把所有问题都归因于数据库,实际上是接口循环查询。
- 只在小数据量验证,线上千万级数据后完全变慢。
商业场景怎么落地
订单系统
核心表通常有订单表、支付表、订单明细表、库存流水表。重点是:
- 订单号唯一约束必须在数据库层保证。
- 支付状态更新必须放在事务里。
- 高频查询要按用户、状态、时间设计联合索引。
- 对账和报表不要直接拖垮在线交易库。
- 大表要提前设计归档和冷热数据策略。
医疗资产采集平台
常见表有设备表、采集任务表、采集结果表、异常事件表、资产变更流水。重点是:
- 设备唯一标识、医院编码、科室编码要建唯一或联合约束。
- 采集结果写入量大,要考虑批量写入、分区或归档。
- 查询资产当前状态适合关系库,全文检索和复杂搜索可同步到 Elasticsearch。
- 热点设备状态可以缓存到 Redis,但数据库仍是最终事实源。
- 数据同步要有幂等键,避免重复采集导致重复入库。
搜索系统
MySQL 不适合承担复杂全文搜索主力。常见做法是:
- MySQL 保存权威业务数据。
- Elasticsearch 保存搜索视图。
- 通过 binlog CDC、消息队列或本地消息表同步。
- ES 更新失败时要进入补偿队列,不允许静默丢失。
- 详情页仍然可以回源 MySQL 校验最新状态。
可运行 Demo:建立一个可优化的订单表
这个 Demo 用 MySQL 写法,其他关系库语法略有差异,但思想相通。
create table order_main (
id bigint primary key auto_increment,
order_no varchar(64) not null,
user_id bigint not null,
status tinyint not null,
total_amount decimal(12, 2) not null,
pay_time datetime null,
created_at datetime not null,
updated_at datetime not null,
unique key uk_order_no (order_no),
key idx_user_status_created (user_id, status, created_at),
key idx_status_created (status, created_at)
) engine = InnoDB default charset = utf8mb4;查询用户最近订单:
explain
select id, order_no, status, total_amount
from order_main
where user_id = 1001
and status = 1
order by created_at desc
limit 20;你要观察:
| 字段 | 观察点 |
|---|---|
key | 是否使用 idx_user_status_created |
type | 是否避免 ALL 全表扫描 |
rows | 预估扫描行数是否合理 |
Extra | 是否出现 Using filesort、Using temporary |
如果这个查询没有合适索引,大数据量下会扫描很多订单;如果索引列顺序不符合查询条件,也可能无法同时利用过滤和排序。
线上排查通用流程
flowchart TD
A["数据库变慢"] --> B{"是单条 SQL 慢还是整体慢"}
B -- "单条 SQL 慢" --> C["看执行计划和扫描行数"]
C --> D["看索引、排序、临时表、回表"]
B -- "整体慢" --> E["看连接、CPU、IO、锁等待"]
E --> F["定位是否大事务、刷盘、复制延迟"]
D --> G["改 SQL / 索引 / 表设计"]
F --> H["限流 / 拆事务 / 扩容 / 故障恢复"]
G --> I["复测并沉淀规则"]
H --> I排查时不要只看一个指标:
| 现象 | 可能原因 |
|---|---|
| SQL 偶尔慢 | 锁等待、缓存未命中、参数导致计划变化 |
| SQL 一直慢 | 索引不合适、扫描范围大、排序临时表 |
| 提交慢 | 日志刷盘慢、大事务、磁盘延迟 |
| CPU 高 | 复杂排序、函数计算、并发过高、执行计划差 |
| IO 高 | 全表扫描、回表多、Buffer Pool 不够、大查询 |
| 从库延迟 | 大事务、从库慢 SQL、并行复制不足 |
面试标准回答
数据库学习不能只停留在 SQL 语法,要按表设计、索引、执行计划、事务并发、日志恢复、高可用和性能排查这条主线理解。关系型数据库的核心是可靠保存结构化数据,并在并发读写和故障恢复场景下保证正确性。
MySQL、PostgreSQL、Oracle、SQL Server 都支持 SQL、事务和索引,但内部实现不同。MySQL InnoDB 常强调 B+Tree、Buffer Pool、undo、redo、binlog;PostgreSQL 重点是 tuple 多版本、WAL、VACUUM 和扩展索引;Oracle 重点是实例、SGA/PGA、Undo、Redo、SCN;SQL Server 重点是 Buffer Pool、聚集/非聚集索引、事务日志、锁和行版本。学习时要把一条 SQL 的执行过程、执行计划来源、索引选择、事务日志和线上排查串起来。关联知识点
| 知识点 | 说明 |
|---|---|
| MySQL | 互联网业务最常用关系库主线 |
| 主流关系库核心差异与选型 | 对比 MySQL、PostgreSQL、Oracle、SQL Server 的索引、日志、MVCC、执行计划和选型 |
| PostgreSQL | 复杂 SQL、扩展能力、MVCC/VACUUM/WAL |
| Oracle | 企业级事务、Undo/Redo/SCN、RAC/Data Guard |
| SQL Server | 微软生态、聚集索引、事务日志、等待排查 |
| MongoDB | 文档模型和聚合管道 |
| Redis | 缓存、高并发、分布式锁、大 key/热 key |
| Elasticsearch | 搜索引擎、倒排索引、MySQL 与 ES 一致性 |
