# 关于此书

LLMS 索引： [llms.txt](/zh18/llms.txt)

---

<span id="internal-ru-chapter-star-3" class="pdf-anchor"></span><span id="internal-ru-page-18" class="pdf-anchor"></span>

“原来一切都这么简单！”什蓬季克（Шпунтик）叫道，“可我好像在哪儿读过，作家得有点想象，有点构思……”

“嗨，构思！”斯梅卡伊洛（Смекайло）不耐烦地打断了他，“只有书里才说要有构思。可你试着构思点什么吧，人家早就把什么都想过了！无论你想写什么，全都有人写过。”尼古拉·诺索夫，*《小无知和他的朋友们历险记》*

<span id="internal-ru-section-star-4" class="pdf-anchor"></span>

## 本书适合哪些人 {#internal-ru-p18-261}

本书适合那些不愿把数据库当作黑箱来使用的人。如果你充满好奇，不满足于权威人士的建议，想亲自弄清一切，那么我们就同路了。

我假设读者已经有一定的 PostgreSQL 使用经验，至少大致了解它是怎么回事。对完全没有经验的新手来说，本书可能有些难。例如，我不会介绍如何安装服务器、在 psql 中输入命令或修改配置参数。

我希望这本书对那些熟悉其他数据库系统的内部结构，但想转而使用 PostgreSQL 并希望了解两者之间差异的人也有所帮助。几年前，如果有这样一本书，我本可以节省很多时间。这也正是我最终写下这本书的原因。

<span id="internal-ru-section-star-5" class="pdf-anchor"></span>

## 本书不提供的内容 {#internal-ru-p18-522}

<span id="internal-ru-page-19" class="pdf-anchor"></span>

本书不是一本现成方案集。我们不可能为所有情况准备好解决方案，但理解复杂系统的内部机制，就能批判性地重新审视他人的经验，得出自己的结论。这正是我介绍那些乍看似乎没有实际用处的内部细节的原因。

本书也不是一本教材。它深入讨论了某些领域（也就是我自己更感兴趣的领域），却绕过了另一些领域。如果你正在学习 SQL，可以看看叶夫根尼·莫尔古诺夫（Евгений Моргунов）的教材 *《PostgreSQL：SQL 语言基础》*[^internal-ru-19-1]；而鲍里斯·诺维科夫（Борис Новиков）的 *《数据库技术基础》*[^internal-ru-19-2] 则能提供必要的理论基础。

本书也无意充当参考手册。我力求准确，但没有打算用它替代文档，因此会略去一些在我看来无关紧要的细节。遇到任何不明白的地方，请阅读文档。

本书不会教你如何开发 PostgreSQL 内核。我不要求读者掌握 C 语言，而是面向管理员和应用开发者。不过，我会经常引用源代码，从中你可以了解到任意多的细节，甚至比你想知道的还多。

<span id="internal-ru-section-star-6" class="pdf-anchor"></span>

## 本书提供的内容 {#internal-ru-p19-350}

在绪论中，我会简要介绍后文所依赖的基本概念。我想你几乎不会从这一章学到什么新东西，但为了让全书内容完整，还是把它放了进来。此外，它也可能对从其他数据库管理系统转来的读者有所帮助。

第一部分讨论一致性与隔离性。我先从用户的角度介绍这些问题（有哪些隔离级别，它们会带来什么影响），然后转向内部实现。为此，需要深入介绍多版本机制和基于数据快照的隔离机制的实现细节。其中，清理过期行版本的过程尤其需要仔细讨论。

<span id="internal-ru-page-20" class="pdf-anchor"></span>

第二部分介绍缓冲区缓存，以及能够在故障后恢复一致性的机制——预写式日志。

第三部分详细介绍各个层级的锁的结构和使用：用于内存的轻量级锁、用于关系的重量级锁，以及表中的行级锁。

第四部分解释服务器如何规划和执行 SQL 查询。我会介绍有哪些数据访问方式、采用了哪些连接方法，以及如何使用统计信息。

第五部分把此前局限于 B-树（B-tree）的索引讨论扩展到其他访问方法。我首先介绍可扩展性的一般原理，它们界定了索引系统核心、索引访问方法和数据类型之间的边界（为此需要引入操作符类的概念），然后详细介绍每种现有方法的特点。

PostgreSQL 自带了大量“自省”扩展，日常工作并不需要它们，但它们让我们能够窥见服务器内部的运行情况。本书使用了其中的许多扩展。除了帮助我们深入了解服务器的内部结构，这些扩展也能使复杂情况下的诊断更容易。

<span id="internal-ru-section-star-7" class="pdf-anchor"></span>

## 约定 {#internal-ru-p20-390}

<span id="internal-ru-dummy-1" class="pdf-anchor"></span>

写作时，我尽量让这本书能够按顺序逐页阅读。但很难一次把所有事情讲清楚，所以同一话题不得不反复出现。如果每次都写“后面还会讨论”，书就会厚上许多。因此，遇到这种情况，我会在页边标出继续讨论该话题的页码。同样，指向前文的页码表示前面已有相关讨论。（*第 [19](/zh18/about-this-book/#internal-ru-page-20) 页*）

<span id="internal-ru-page-21" class="pdf-anchor"></span>

本书正文和全部示例均适用于 PostgreSQL 18。有些段落在页边标注了版本号，表示该段内容从所标注的 PostgreSQL 版本起成立，而更早的版本要么没有所述功能，要么采用了不同的实现。这些标记可能对尚未升级到最新版本的读者有用。（v. 18）

页边还会标出所讨论参数的默认值。参数名（包括普通参数和存储参数）以斜体表示：*work\_mem*。（*默认值：* `4MB`）

我在脚注中经常引用一手资料。这类资料有好几种，首先是蕴含丰富信息的文档[^internal-ru-21-1]。文档是项目的有机组成部分，始终由开发者亲自维护更新。不过，最根本的资料无疑是源代码[^internal-ru-21-2]。即使不懂 C 语言，仅从注释和 README 文件中就能找到如此多问题的答案，实在令人惊叹。我偶尔也会引用 commitfest 条目[^internal-ru-21-3]：在 pgsql-hackers 的通信中，总能追溯变更的历史，理解开发者作出决定的思路，代价则是需要阅读海量讨论。

> [!NOTE]
> 有些题外话和说明可能让人偏离主线，但我还是忍不住把它们写进书里。这些内容会采用这样的形式标出，方便读者跳过。

当然，本书有很多代码片段，主要使用 SQL。代码以 `=>` 作为提示符；必要时，后面还会给出服务器的响应：

```text {label="psql"}
=> SELECT clock_timestamp();
        clock_timestamp
-------------------------------
 2026-04-05 20:51:34.767686+03
(1 row)
```

如果在 PostgreSQL 18 中仔细执行书中的所有命令，应该能得到相同的结果（当然，事务编号等无关紧要的细节可能不同）。至少，本书中的所有代码都是执行一个脚本所得的结果，而该脚本包含的正是这些命令。

需要展示多个事务同时运行时，在另一会话中执行的代码会以缩进和竖线标出：

<span id="internal-ru-page-22" class="pdf-anchor"></span>

```text {label="psql"}
=> SHOW server_version;
 server_version
----------------
 18.3
(1 row)
```

要重现这些命令，打开两个 psql 终端会很方便（和任何实验一样，这对自学很有帮助）。

单独提到的命令和各类数据库对象名称（如表、列、函数和扩展）采用等宽字体：`UPDATE`、`pg_class`。

从操作系统调用工具时，使用以 `$` 结尾的提示符：

```text
postgres$ whoami
postgres
```

我使用 Linux，但没有涉及它的特有功能；掌握最基本的知识就足够了。

<span id="internal-ru-section-star-8" class="pdf-anchor"></span>

## 致谢 {#internal-ru-p22-360}

一个人无法独力完成一本书，这正是向那些热心人道谢的好机会。

感谢 Pavel Luzanov，他在恰当的时候建议我做一点真正有价值的事。

感谢 Postgres Professional 公司，让我不必只在业余时间写作这本书。公司是由人组成的，我尤其要感谢 Oleg Bartunov 源源不断的精力和想法，也要感谢 Ivan Panchenko 的全面支持和 L<sup>A</sup>TEX。

感谢教育部门的同事们营造的创作氛围，以及大家的讨论。培训课程的内容和讲授方式正是在这些讨论中逐渐形成的，也体现在了本书中。感谢 Pavel Tolmachev 对草稿的仔细审读。

<span id="internal-ru-page-23" class="pdf-anchor"></span>

本书许多章节最初以文章形式发表于 Habr[^internal-ru-23-1]，感谢读者的意见和反馈。这些反馈让我看到了这项工作的必要性，发现自己知识中的空白，也让书稿得以改进。

感谢 Liudmila Mantrova，她为打磨本书的语言付出了大量心血。如果你读起来不至于每隔一句就磕绊一次，那都是她的功劳。

书中没有逐一提到这些人的名字，但我介绍的每个函数和每项功能背后，都有具体的人为之付出了多年的劳动。我敬佩 PostgreSQL 的开发者，也格外荣幸能称其中许多人为我的同事。

[^internal-ru-19-1]: [postgrespro.ru/education/books/sqlprimer](<https://postgrespro.ru/education/books/sqlprimer>).
[^internal-ru-19-2]: [postgrespro.ru/education/books/dbtech](<https://postgrespro.ru/education/books/dbtech>).
[^internal-ru-21-1]: [postgrespro.ru/docs/postgresql/18/index](<https://postgrespro.ru/docs/postgresql/18/index>).
[^internal-ru-21-2]: [git.postgresql.org/gitweb/?p=postgresql.git;a=summary](<https://git.postgresql.org/gitweb/?p=postgresql.git;a=summary>).
[^internal-ru-21-3]: [commitfest.postgresql.org](<https://commitfest.postgresql.org>).
[^internal-ru-23-1]: [habr.com/ru/company/postgrespro/blog](<https://habr.com/ru/company/postgrespro/blog>).
