真实数据库内部是如何工作的?

发布: (2026年1月31日 GMT+8 18:28)
6 min read
原文: Dev.to

Source: Dev.to

请提供您希望翻译的正文内容,我会按照要求将其翻译成简体中文并保留原有的格式。

真正的数据库不是这样

  • 一个巨大的内存表
  • 一堆 CSV 文件的集合
  • 一个简单的键值映射

核心组件

  • 解析器
  • 计划器 / 优化器
  • 执行引擎
  • 存储引擎
  • 缓冲缓存
  • 事务管理器
  • 恢复系统

查询处理流水线

当你执行类似下面的语句时:

SELECT name FROM users WHERE age > 30;

数据库并不会立即扫描表。它遵循严格的流水线:

解析与校验

  1. 将 SQL 文本转换为 抽象语法树 (AST)
  2. 检查:
    • 语法是否正确
    • 表名和列名是否有效
    • 用户权限

此阶段不访问任何数据。

优化

查询优化器决定:

  • 使用哪些索引
  • 连接顺序
  • 扫描方式(索引扫描 vs. 顺序扫描)
  • 基于统计信息的成本估算

常见的决策:

  • 顺序扫描 100 万行是否更便宜?
  • 还是使用随机 I/O 的索引更划算?

现代数据库采用:

  • 基于成本的优化器
  • 统计信息(直方图、基数)
  • 基于规则的重写

这一步往往决定了性能,而不是硬件。

执行

优化器生成 执行计划。执行引擎随后:

  • 通过运算符(扫描 → 过滤 → 投影)拉取行
  • 使用迭代器或向量化执行
  • 流式输出结果,而不是一次性加载到内存

重要概念: 数据库以流水线方式处理数据,而不是一次性全部处理。

存储布局

页面

数据以固定大小的页面存储(通常为 4 KB–16 KB)。
每个页面包含:

  • 页面头部
  • 行槽
  • 元数据

页面是 I/O 的最小单位。

行式存储 vs. 列式存储

存储类型典型用途特点
行式(PostgreSQL,MySQL)OLTP插入快速且点查询快
列式(ClickHouse,Redshift)Analytics压缩优秀,向量化扫描

索引

索引是独立的数据结构,最常见的有:

  • B‑树 – 保持数据有序,最小化磁盘寻道,平衡读/写成本
  • 哈希索引
  • LSM 树(RocksDB,Cassandra)

重要事实: 索引加快读取速度,但会减慢写入,因为每次插入/更新都必须同时修改表数据和所有相关索引。

Buffer Cache and Durability

数据库从不只信任内存。经常使用的页面会被缓存到 RAM 中,而 dirty pages 则会在以后使用替换策略(LRU 变体)写回磁盘。

如果电源失效,内存会丢失,因此磁盘必须保持一致性。

Source:

ACID 保证

真实的数据库通过 Write‑Ahead Log (WAL) 来确保 Atomicity, Consistency, Isolation, Durability

  1. 在修改数据之前,先将更改写入日志。
  2. 将日志刷新到磁盘。
  3. 然后才更新内存中的页面。

如果数据库崩溃,会重新播放 WAL 以恢复数据。日志往往比数据文件本身更为关键。

并发控制

数据库通过以下方式支持成千上万的并发用户:

  • 锁(行、页、表)
  • MVCC(多版本并发控制)

使用 MVCC 时:

  • 读取者不会阻塞写入者。
  • 写入者会创建新版本。
  • 旧版本由真空/垃圾回收清理。

这就是像 PostgreSQL 这样的系统能够在不加锁的情况下读取,并在负载下良好扩展的原因。

恢复过程

  1. 读取最近的检查点。
  2. 重放 WAL 记录。
  3. 撤销未完成的事务。
  4. 恢复一致性。

该过程是确定性的且可重复的——无需猜测或启发式方法。

为什么理解内部工作原理很重要

  • 编写更快的查询
  • 设计更好的模式
  • 选择正确的索引
  • 避免危险的假设
  • 调试性能问题

大多数“慢数据库”问题源于:

  • 糟糕的查询计划
  • 错误的索引
  • 对内部机制的误解

…而不是硬件。

结论

真实的数据库更像操作系统,而不是一个简单的库。它管理内存、存储、并发、恢复和调度。把它当作黑盒使用只会让你受罚;了解其内部机制则能把它变成软件工程中最强大的工具之一。

Back to Blog

相关文章

阅读更多 »

开启 RUST

我的 Java 到 Rust 的转变之路:更换 technology stack 你好,我叫 Garik,今天我想与大家分享我决定更换 technology stack 的故事。