这次我们来看一个数据库内核方向非常硬核的学习资源:由宾夕法尼亚州立大学团队打造、带有中英双语字幕的数据库实现精讲课程,内容从关系模型一路讲到事务,定位是“手把手教你打造数据库”。
先说结论:如果你已经会写 SQL、平时用 MySQL 或 PostgreSQL 做增删改查,但一直没搞懂数据库底层到底怎么把数据存下来、一条查询怎么变成执行计划、多个事务并发时靠什么保证一致性,这门课就是补这块知识的好选择。它不空谈概念,而是带着你用工程方式实现一个可运行的数据库内核;同时因为带中英双语字幕,英文术语跟中文概念能一次对齐,学习门槛比直接啃英文原版课程低不少。
这篇文章我会先把课程的核心内容和能力覆盖整理成一个速览表,然后按照“关系模型 → 存储引擎 → 查询执行 → 事务”这条主线,拆解每个模块学什么、需要掌握哪些核心概念、有哪些可以动手验证的实验方向;接着给出推荐的学习路线、需要准备的环境、中英双语学习的重点术语对照,以及一套常见问题排查清单。文章最后会给出一个偏个人向的学习优先级建议,方便你在有限时间里做出取舍。
1. 核心能力速览
| 能力项 | 说明 |
|---|---|
| 课程来源 | 宾夕法尼亚州立大学(Penn State)数据库内核相关课程,具体以公开视频平台发布信息为准 |
| 语言 | 视频原声为英文,同步提供中文字幕,形成中英双语学习体验 |
| 覆盖范围 | 关系模型、数据库存储、索引、查询执行与优化、事务、并发控制、故障恢复等数据库内核核心模块 |
| 核心主线 | 从关系模型出发,到存储、执行、事务,最终落到一个可运行的数据库原型实现 |
| 题目定位 | “手把手教你打造数据库”,面向数据库工程实现,而不是只讲理论 |
| 适合人群 | 数据结构与算法有一定基础、熟悉 SQL、希望深入数据库底层实现的开发者 |
| 学习方式 | 视频精讲 + 子模块拆解 + 动手实现 + 中英术语对照 |
| 前置环境 | C++ 开发环境、CMake、SQLite 或测试数据库作为参照,具体以课程要求为准 |
| 是否免费 | 公开平台资源,通常以免费形式呈现,以实际发布渠道为准 |
| 工程产出 | 通过跟随课程实现数据库核心存储、索引和事务模块,理解真实数据库“从零到一”的构建过程 |
需要说明的是,课程的具体课时数、作业脚本、实验平台等细节,需要以你实际打开的课程页面为准。上面表格里能确认的信息,基本都来自这个项目的标题、摘要和公开定位,不额外虚构参数。
2. 数据库内核到底在学什么
很多人写了三五年 SQL,对数据库的了解依然停留在客户端工具层面:建表、写查询、看执行计划、优化索引。这些确实够日常开发用了,但一旦涉及以下问题,你就会发现知识不够用:
- 为什么有些查询明明加了索引还是慢?
- 为什么高并发下会出现死锁、锁等待、脏读、不可重复读?
- 为什么数据库突然宕机后,已提交的数据没有丢,没提交的却被回滚了?
- 一条多表 JOIN 的查询,底层到底用什么算法在跑?
- 同样是存数据,为什么有的数据库用 B+ 树,有的用 LSM Tree?
这些问题的答案,全在数据库内核里。
数据库内核通常可以划分为四个层次:
第一层,关系模型与 SQL 语义。这一层决定“数据库能表达什么”。关系模型把数据组织成二维表,用关系代数和关系演算为 SQL 提供理论基础。学完这一层,你才能理解为什么 SQL 能表达几乎所有业务查询,也才能理解视图、子查询、连接这些操作的本质。
第二层,存储引擎。这一层决定“数据怎么落盘”。它负责把内存里的数据高效地组织成文件、页、索引结构,并处理缓冲区、磁盘 IO、并发访问。你常用的 InnoDB、MyISAM、RocksDB,本质都是存储引擎。
第三层,查询执行。这一层决定“一条 SQL 怎么跑”。从 SQL 文本到抽象语法树,再到逻辑计划、物理计划,最后通过一组算子(Scan、Filter、Join、Aggregate)执行并返回结果。查询优化器在这一层决定走索引还是全表扫描、用哪种 Join 算法、如何调整算子顺序。
第四层,事务与恢复。这一层决定“数据库怎么保证不丢数据、不错数据”。事务的 ACID 特性依赖并发控制(锁、多版本并发控制)和故障恢复(日志、检查点、重做与回滚)。这也是很多人在应用层搞不清楚的地方。
这门课的价值在于,它不是把这四层当成孤立知识点来讲,而是要求你亲手把它们串起来,最终形成一个能响应用户输入的数据库原型。
3. 课程主线拆解:从关系模型到事务
结合公开材料,这门课的内容主线可以拆成下面几个阶段:
3.1 关系模型与 SQL 处理
课程从关系模型开始,这是所有关系型数据库的地基。
你需要建立这几个认知:关系是一个带有列名和约束的二维表;关系代数包含选择、投影、连接、并、交、差等基本运算;SQL 是关系代数的“用户友好封装”。一个非常关键的思维转变是:SQL 写出来是什么样不重要,数据库怎么理解它才重要。SQL 文本要被解析成语义等价的逻辑查询计划,再转换成物理执行计划。
举个例子,下面这条 SQL:
SELECT student.name, course.title FROM student JOIN course ON student.course_id = course.id WHERE student.score >= 60它在关系代数层面等价于:
π(student.name, course.title)( σ(student.score >= 60)( student ⋈ student.course_id = course.id course ) )理解这个等价关系,是后续学查询优化的前提。
3.2 存储引擎:页、缓冲区、索引
接下来进入存储引擎。这是数据库中最“工程化”的部分,也是最容易在视频里看到实际操作的部分。
存储引擎要解决的核心问题是:内存有限、磁盘很慢,怎样让读写又快又稳?答案是一层层缓存和索引:
- 数据按页存储,一页通常是 4KB 或 8KB。
- 缓冲池(Buffer Pool)在内存里管理最近访问的页,通过替换算法决定哪些页保留、哪些写回磁盘。
- 索引是为了避免全表扫描而设计的额外结构,常见的就是 B+ 树。
B+ 树可以算这门课的一个重点。它跟普通二叉搜索树不同,节点能存多个键、树的层数更少、所有数据落在叶子节点、叶子节点之间有指针串联,非常适合磁盘这种大块读写场景。课程一般会要求你实现一个简化 B+ 树,支持插入、查找、范围扫描。
一个经典的页结构设计思路是这样的:
constexpr int PAGE_SIZE = 4096; struct Page { // 页头 uint32_t page_id; uint32_t num_records; uint32_t free_space_pointer; bool is_dirty; // 页体:用字节数组承载实际记录数据 char data[PAGE_SIZE - 64]; };这里有一个从课程中能得到的重要认知:数据库里“删一条记录”往往不是立刻抹掉磁盘上的字节,而是标记删除或就地更新,最终靠后台清理和页重组完成空间回收。这也是为什么数据库表在频繁删除后需要OPTIMIZE TABLE之类的操作来回收空间。
3.3 查询执行:从 SQL 到结果
查询执行阶段,你要从“数据结构”切换到“执行引擎”视角。
一条 SQL 的旅程大致是:
- 词法分析和语法分析,生成抽象语法树。
- 绑定(Binding),把表名、列名映射到具体的 schema 对象。
- 生成逻辑计划,也就是一棵由关系代数算子组成的树。
- 应用查询优化规则,比如谓词下推、投影裁剪、连接顺序调整。
- 生成物理计划,指定每个算子具体用什么算法执行。
- 执行算子树,逐行或批量返回结果。
在实现层面,你会接触到几种不同的执行模型:
- 迭代器模型(Volcano Model):每个算子实现
next(),一次返回一行。可读性好,通用,但虚函数调用开销大。 - 物化模型:一次计算完整结果。适合批量分析,但内存压力大。
- 向量化模型:一次返回一批行,比如 1024 行,同时利用 SIMD 加速。这是现代分析型数据库的主流做法。
连接操作是一个考研功底的环节。课程里通常会覆盖三种 Join 算法:
- Nested Loop Join:最简单,双重循环,适合小表连接小表。
- Hash Join:为其中一个表建哈希表,另一表逐行探查,适合等值连接和大表连接。
- Sort-Merge Join:先按连接键排序,再归并匹配,适合大表之间按序连接或非等值连接。
这里你能直观看到,为什么常说“查询优化器选择了错误的 Join 算法,性能可能差几个数量级”。
3.4 事务:ACID、并发控制、故障恢复
事务是这门课的重头戏,也是数据库内核里最抽象、最难在应用层体会到的一层。
课程会把 ACID 拆开来讲:
- 原子性:事务里的操作要么全部提交,要么全部回滚。
- 一致性:事务执行前后,数据库都满足约束条件。
- 隔离性:并发事务之间互相不干扰或少干扰。
- 持久性:已提交事务的修改不会因为数据库崩溃而丢失。
实现原子性和持久性的常见手段是预写日志(WAL,Write-Ahead Logging)。核心原则是:日志先落盘,数据再落盘。这样即使数据库崩溃,也可以通过日志重做(Redo)或回滚(Undo)恢复状态。
一个简化版的 WAL 写入流程可以这样理解:
// 提交事务前,保证日志先落盘 void CommitTransaction(TransactionId txn_id, std::vector<LogRecord>& logs) { // 1. 将本次事务产生的所有日志记录写入日志缓冲区 for (auto& record : logs) { log_buffer_.push_back(record); } // 2. 日志缓冲区刷新到磁盘 fsync(log_file_fd_); // 3. 数据页写入磁盘 for (auto& page : dirty_pages_) { WritePage(page); } }并发控制部分,课程会讲两阶段锁(2PL)和基于时间戳的并发控制。两阶段锁的核心约束很简单:事务分两个阶段,第一个阶段只能加锁,第二个阶段只能解锁;锁一旦开始释放,就不能再申请新锁。严格遵守 2PL 可以保证冲突串行化,但也会引入死锁问题,需要死锁检测或超时机制。
如果课程内容扩展到多版本并发控制(MVCC),你会看到更现代的实现:读操作不阻塞写操作,写操作不阻塞读操作,每个事务看到的是数据在某个时间点的快照。MySQL InnoDB 的实现、PostgreSQL 的实现,本质上都是在这个方向上做优化。
学完事务这一层,很多应用层的问题就通了:为什么隔离级别从读未提交到可串行化,并发性能依次下降;为什么基于行锁的数据库在高并发更新同一行时可能出现大量锁等待;为什么分布式事务里要实现两阶段提交而不是简单的“先更新 A 库再更新 B 库”,因为本地事务日志根本无法保证跨库原子性。
4. 关系模型:为什么课程从它开始
课程把关系模型放在最前面,不是走过场,而是因为它决定了数据库的整体架构。
关系模型由 E.F. Codd 在 1970 年提出,核心思想是把数据描述成集合论意义上的关系,而不是像早期网状或层次数据库那样面向物理路径。这个抽象看似浅显,实际上非常深刻:
- 用户面对的是表,而不是文件路径,数据物理存储方式被完全隐藏。
- 查询语言基于关系代数和关系演算,具有数学基础,优化器可以做等价变换。
- 数据独立于应用,同一组数据可以支撑完全不同的查询需求。
学关系模型时,一个很值得做的练习是:不要只写 SQL,而是先画关系代数表达式,再转成 SQL,最后去数据库里验证结果。比如先列出“所有选课成绩大于 90 分的学生姓名,按姓名排序”这个需求,先想清楚你需要哪些关系、哪些选择条件、哪些投影列,再写 SQL。
这个练习看着简单,但它训练的是你把自然语言转换成形式化查询的能力,而这个能力在后续学查询优化时特别有用。
5. 存储引擎实现:一个常见的课程实验方向
按照“手把手打造数据库”的定位,存储引擎部分大概率会配套一个动手实现任务。这里给出一条通用的实现路径,同时不绑定任何具体课程要求:
- 先实现一个定长记录存储。定义一个表结构,每条记录固定长度,支持 insert、update、delete、scan 四个基础操作,数据写入一个二进制文件。
- 引入页和缓冲池。把文件按页切分,缓冲池用哈希表维护页 ID 到内存页的映射,实现 LRU 替换和脏页刷盘。
- 加入系统目录。用一张内部表存储表名、列名、列类型、列偏移量,让数据库能正确解析“student 表有哪些列,每列在哪几个字节”。
- 实现 B+ 树索引。先用内存版 B+ 树跑通逻辑,再改成磁盘版,支持索引页的读入、写入、分裂、合并。
- 把表和索引串起来。插入记录时同步更新索引,删除记录时同步删除索引项。
这套路径也是很多数据库内核课程的标准作业演进路线。第一个版本可以很粗糙,能跑通单线程顺序写入和全表扫描就算成功。后面的优化再逐步考虑并发、事务和崩溃恢复。
6. 查询执行:建议重点看的几个算子与优化规则
查询执行模块信息密度很高,看视频时建议带着问题去看。
6.1 几个核心算子
- Seq Scan:全表扫描,从存储引擎逐页读出记录并应用过滤条件。
- Index Scan:借助索引定位到少量记录,再回表取完整数据。
- Filter:在迭代器模型里表现为每次
next()时判断是否满足谓词条件。 - Join:内连接、左连接、右连接分别对应不同的输出语义。
- Aggregation:分组聚合,需要处理哈希分组或排序分组。
6.2 几条核心优化规则
- 谓词下推:把
WHERE条件尽量往算子树下层移动,先过滤再连接,减少中间结果集。 - 投影裁剪:把不需要的列尽早丢弃,减小每行数据的宽度,降低 IO 和内存开销。
- 连接顺序优化:多表连接时,选择基数最小的表先做连接,可能带来数量级性能差异。
- 消除冗余算子:比如去掉可以合并的 Filter、避免无意义的 Sort。
一个值得亲手验证的实验是:建两张十万行的表,分别测试“先 WHERE 再 JOIN”和“先 JOIN 再 WHERE”两种写法的执行计划差异。多数优化器会自动做谓词下推,但你会发现执行计划里的算子顺序不同,扫描的行数和最终耗时也不同。
7. 事务与并发控制:从单体到分布式
事务部分的内容,建议对照真实数据库来验证。
你可以用一个安装了 MySQL 或 PostgreSQL 的本地环境做如下实验:
- 开启两个客户端连接,设置隔离级别为
READ COMMITTED,模拟脏读和不可重复读场景。 - 把隔离级别改成
REPEATABLE READ,观察快照读的行为。 - 在两个事务里交叉更新同一行,观察死锁报错信息。
- 查看
information_schema.innodb_trx表,观察当前未提交事务持有的锁。
这些实验能让你对课程里的概念产生直接对应:锁是加在索引记录上的、不同的隔离级别影响快照的生成时机、死锁检测需要系统维护等待图。
分布式事务是这门课的自然延伸。热词里频繁出现“分布式事务一致性”“seata 分布式事务原理”“订单与库存分布式事务”,说明这是数据库应用侧的普遍痛点。课程重点在单机数据库内核层面,但学完两阶段锁和 WAL 之后,再去看两阶段提交(2PC)、三阶段提交(3PC)、基于消息的最终一致性,会轻松很多。因为它们的本质问题是一样的:如何在没有单点权威的情况下,让多个参与者达成一致的提交决策。
8. 中英双语学习:术语对照与字幕使用建议
这个课程带中英双语字幕,对中文学习者来说是一个明显加分项。
数据库内核是英文术语主导的领域:Buffer Pool、WAL、B+ Tree、MVCC、Isolation Level、Serializable、Deadlock、Checkpoint。如果你只看中文资料,能听懂概念,但搜英文文档和源码时会对不上号;如果只看英文原声,术语没问题,但复杂句式容易劝退。
建议这样利用双语资源:
- 第一遍看中文字幕,快速建立整体认知。
- 第二遍对照英文字幕,把每个模块的关键术语用双语记录下来。
- 第三遍只看课程里出现的代码和图示,尝试自己复述一遍实现逻辑。
这里给一份高频术语对照表,建议直接收藏:
| 英文术语 | 中文翻译 | 所属模块 |
|---|---|---|
| Relation / Tuple / Attribute | 关系 / 元组 / 属性 | 关系模型 |
| Relational Algebra | 关系代数 | 关系模型 |
| Buffer Pool | 缓冲池 | 存储引擎 |
| Page | 页 | 存储引擎 |
| B+ Tree | B+ 树 | 存储引擎 |
| Table Scan | 全表扫描 | 查询执行 |
| Index Scan | 索引扫描 | 查询执行 |
| Query Optimizer | 查询优化器 | 查询执行 |
| Volcano Model | 火山模型(迭代器模型) | 查询执行 |
| Vectorized Execution | 向量化执行 | 查询执行 |
| Transaction | 事务 | 事务 |
| ACID | 原子性、一致性、隔离性、持久性 | 事务 |
| Two-Phase Locking | 两阶段锁 | 并发控制 |
| Deadlock | 死锁 | 并发控制 |
| MVCC | 多版本并发控制 | 并发控制 |
| Write-Ahead Logging | 预写日志 | 故障恢复 |
| Checkpoint | 检查点 | 故障恢复 |
| Redo / Undo | 重做 / 回滚 | 故障恢复 |
| Serializable | 可串行化 | 隔离级别 |
| Isolation Level | 隔离级别 | 隔离级别 |
建议你在学习过程中维护一份自己的术语表,每学到一个新概念,就记录它的英文术语、中文翻译、一句话定义、一个例子。这份术语表后期回看非常值钱。
9. 环境准备与动手实践建议
跟看视频学数据库内核,只看不练很难真正掌握。哪怕课程没有强制要求作业,也建议自己搭一个最小实验环境。
9.1 推荐的开发环境
学习数据库内核实现时,C++ 是最常见的选择,也是这套课程大概率采用的工程语言。一个适合初学者的环境组合是:
| 组件 | 推荐选择 | 用途 |
|---|---|---|
| 操作系统 | Linux(Ubuntu 22.04 或更新版本)或 macOS | 开发与测试 |
| 编译器 | g++ 9+ 或 clang 11+ | 编译 C++ 代码 |
| 构建工具 | CMake 3.16+ | 管理工程构建 |
| 调试工具 | GDB 或 LLDB | 排查段错误和逻辑问题 |
| IDE 或编辑器 | VS Code + C++ 插件 / CLion | 开发效率 |
| 测试数据库 | SQLite 或 MySQL / PostgreSQL | 对照验证行为 |
如果你还没有编译环境,下面的命令可以快速在 Ubuntu 上完成最小安装,具体版本以官方仓库为准:
sudo apt update sudo apt install -y build-essential cmake gdb然后创建一个最小工程:
mkdir db-tutorial && cd db-tutorial mkdir src build touch CMakeLists.txt src/main.cppCMakeLists.txt可以先用最小版本:
cmake_minimum_required(VERSION 3.16) project(DatabaseTutorial) set(CMAKE_CXX_STANDARD 17) add_executable(db_tutorial src/main.cpp)编译并运行:
cd build cmake .. make ./db_tutorial9.2 最小实验:实现一个支持增删改查的内存表
建议先从内存表开始,不碰磁盘 IO,先把逻辑跑通。一个简化实现思路如下:
#include <cstdint> #include <iostream> #include <unordered_map> #include <vector> #include <string> struct Row { int id; std::string name; int score; }; class Table { public: void Insert(const Row& row) { rows_[row.id] = row; } bool Delete(int id) { return rows_.erase(id) > 0; } bool Update(int id, int new_score) { auto it = rows_.find(id); if (it == rows_.end()) { return false; } it->second.score = new_score; return true; } Row* Find(int id) { auto it = rows_.find(id); if (it == rows_.end()) { return nullptr; } return &it->second; } private: std::unordered_map<int, Row> rows_; }; int main() { Table t; t.Insert({1, "Alice", 85}); t.Insert({2, "Bob", 62}); t.Update(2, 90); if (auto* row = t.Find(2)) { std::cout << row->name << " " << row->score << std::endl; } t.Delete(1); return 0; }这样做的好处是把“记录如何增删改查”这个最基础的问题先解决掉。当你对内存表已经很熟练时,再叠加页、磁盘文件、缓冲池、索引、事务,每层都能定位到上一个版本的差异。
9.3 性能观察方法
学习过程中,你需要建立“观察数据库行为”的习惯。最常见的观察手段有:
EXPLAIN查看执行计划,确认查询走了索引还是全表扫描。EXPLAIN ANALYZE查看实际执行时间和行数。- 用
top、htop观察 CPU 和内存占用。 - 用
iotop或dstat观察磁盘 IO。 - 自己实现的数据库则用
clock_gettime或std::chrono精确统计每个算子的执行耗时。
10. 常见问题与学习排错
数据库内核课程难度偏高,学习过程中出现挫败感是正常的。把常见问题提前列出来,能省不少时间:
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 视频里讲的术语听不懂 | 前置知识缺失 | 回顾关系代数、数据结构(B 树、哈希表) | 先补《数据库系统概念》前六章或对应中文教材 |
| C++ 代码编译报错 | 编译器版本过旧或标准库差异 | 查看编译器版本和 CMake 配置 | 升级 g++/clang,确认 C++17 标准开启 |
| 程序运行时崩溃(段错误) | 空指针、内存越界 | 用 GDB 跑bt查看堆栈 | 检查指针是否为空、数组是否越界 |
| 缓冲池替换逻辑失效 | LRU 链表维护错误 | 打印访问序列和命中率 | 写单元测试覆盖“冷热数据交替访问”场景 |
| B+ 树插入后查询不到数据 | 节点分裂逻辑有误 | 插入少量数据后逐层打印节点内容 | 实现DebugPrint()辅助函数 |
| 事务并发后数据错乱 | 锁粒度过大或漏加锁 | 写并发测试脚本,检查最终一致性 | 先全局锁跑通,再改行级锁 |
| 不了解隔离级别的实际效果 | 概念抽象 | 开两个数据库连接做对照实验 | 参考 MySQL 官方文档中的隔离级别示例 |
| 视频节奏快、跟不上 | 缺少系统性前置 | 先按中文字幕过一遍,再按英文补细节 | 每节视频写 3 条笔记:概念、实现、坑 |
| 分布式事务概念过多 | 单机事务基础不牢 | 先把本地事务、2PL、WAL 弄透 | 再学 2PC、3PC、最终一致性 |
11. 学习路线与最佳实践
11.1 推荐的 4 遍学习法
第一遍:快速过。看中文字幕,不暂停,不写代码,目标是在脑子里建立“数据库到底由哪些模块组成”的整体地图。这一遍不用记笔记,看不懂的地方跳过。
第二遍:跟着实现。对照英文字幕,把每一节的代码动手敲一遍。建议不要直接复制课程代码,而是自己先写,写不出来再看源码。这个阶段是提升最大的阶段。
第三遍:模块串联。自己画一张数据库架构图,从客户端请求到 SQL 解析、执行计划、存储引擎、事务提交,把每个模块的输入输出标出来。这张图能暴露很多你以为懂了、实际没懂的地方。
第四遍:独立扩展。给课程里实现的数据库加一个自己感兴趣的特性。比如加一个新的聚合算子、实现一种新的索引结构、给事务系统加死锁检测。真正常用的能力不是读懂别人的数据库,而是改出一个自己能跑的数据库版本。
11.2 学习顺序上的优先级建议
- 如果时间有限,优先学存储引擎和事务,这是数据库内核区别于普通 CRUD 应用的核心价值。
- 如果目标是“看懂执行计划”,优先学查询执行和优化规则。
- 如果目标是“在面试中讲清楚 MySQL 事务和 MVCC”,优先学事务、并发控制、WAL。
- 如果目标是“理解现代分布式数据库”,先把单机事务学透,再看分布式事务。
11.3 动手实践的工程化建议
- 保留一套“最小可运行”版本。每完成一个功能,立刻提交一次 Git 记录,这样改坏了随时能回退。
- 建立三个目录:
src(源码)、test(测试)、data(数据文件)。测试不用引入复杂框架,一个简单的断言宏起步就够。 - 每次改动只加一个特性。先能跑,再正确,最后才优化性能。
- 记录每次实验的耗时和显存或内存占用。自己实现的数据库也一样,性能数据是验证优化是否有效的唯一标准。
- 遇到 crash 先复现,再用调试器定位,不要靠“加打印碰运气”。GDB 的
bt命令能直接告诉你崩在哪个函数。
11.4 合规与安全边界
学习数据库内核是纯技术行为,但在学习过程中需要注意以下几点:
- 课程和开源项目材料按各自开源协议使用,不要将收费课程、带版权的材料二次分发。
- 动手实验时使用自己构建或明确授权的测试数据,不要用真实业务数据、个人隐私数据做压测或实验。
- 不要把所学的内核知识用于绕过数据库权限、破坏系统、窃取数据等场景。
- 发布学习笔记或实现代码时,明确标注参考来源,尊重课程和项目的版权。
12. 总结与下一步
这门宾州州立团队的数据库内核精讲,最值得推荐的点不只是“讲得全”,而是它提供了一个从关系模型到事务的完整实现路径。相比于零散地看 B+ 树、看 WAL、看锁机制的博客,跟着一条主线把数据库“手写”一遍,知识沉淀会更牢固。
如果只给你三个任务,我建议按这个顺序执行:
- 第一周:把关系模型和存储引擎部分过一遍,用自己写的一个内存表跑通 insert、delete、update、scan 四个操作。
- 第二周:把查询执行部分过一遍,用课程或教材里的例子画出一个 SQL 的执行计划树。
- 第三周:把事务部分过一遍,在 MySQL 或 PostgreSQL 里手工模拟脏读、不可重复读、幻读场景,并对照课程里的锁机制解释原因。
最容易踩的坑是做“收藏式学习”,视频存了很多进度永远停在 5%。数据库内核没有一个知识点是“看会”的,全部都是“写会”和“调试会”的。条件允许的话,把这个课程和一本经典教材配合使用,《数据库系统概念》和《数据库系统实现》都是很好的补充;遇到源码层面的问题,直接去翻 SQLite 或 PostgreSQL 的源码也是一个很高效的学习路径。
下一步的扩展方向也很多:想贴近业务,可以去学分布式事务、Seata 这类转账场景的解决方案;想贴近大数据,可以去对比分析型数据库的向量化执行引擎;想把关系模型理解得更透,可以研究一下国产数据库、Doris、向量数据库在这些理念上的变体。但无论往哪个方向走,这门课里的单机数据库内核基础,都会是你读源码、看文档时最坚实的那块垫脚石。