Skip to content

PostgreSQL 总览

PostgreSQL 不是“开源版 Oracle”,也不是“换了语法的 MySQL”。它的核心价值在于标准 SQL、复杂查询、强事务、丰富类型、扩展能力,以及和 MySQL 很不一样的 MVCC/VACUUM/WAL 机制。

学习 PostgreSQL 要抓住一条主线:

业务建模 -> SQL 与类型 -> B-tree/GIN/BRIN 索引 -> Planner 执行计划 -> heap tuple 多版本 -> VACUUM 清理 -> WAL 恢复复制 -> 锁和长事务排查。

你应该按什么顺序学

mermaid
flowchart TD
    A["1. SQL、Schema、Role"] --> B["2. 表设计和约束"]
    B --> C["3. B-tree、GIN、BRIN 索引"]
    C --> D["4. EXPLAIN ANALYZE"]
    D --> E["5. MVCC: xmin/xmax"]
    E --> F["6. VACUUM 和膨胀"]
    F --> G["7. WAL、复制、备份恢复"]
    G --> H["8. 锁、长事务、生产排查"]
    H --> I["9. 面试标准回答"]

不要把 PostgreSQL 只当 CRUD 数据库。它的很多生产问题都来自 MVCC 版本、VACUUM、统计信息和复杂计划。

专栏学习地图

页面学什么学完要会什么
基础 SQLschemabigserialjsonb、数组、upsertreturning能写 PostgreSQL 常见业务 SQL
从零到生产级掌握PostgreSQL 完整主线能把 SQL、索引、MVCC、VACUUM、WAL 和排查串起来
商业场景训练营医疗资产、抢任务、JSONB、长事务、BRIN、复制能把原理跑成项目能力
架构与存储database、schema、role、page、tuple、WAL能解释 PostgreSQL 数据怎么存
核心全过程原理Parser、Planner、Executor、MVCC、WAL、VACUUM能讲一条 SQL 和 UPDATE 怎么执行
索引与优化器B-tree、GIN、GiST、BRIN、统计信息、计划能判断为什么 Seq Scan/Index Scan/Bitmap Scan
事务与锁隔离级别、写写冲突、死锁、锁等待能排查阻塞和长事务
MVCC、VACUUM 与 WALtuple 版本、快照、dead tuple、WAL 恢复能解释表膨胀、Index Only Scan、复制恢复
备份与高可用pg_dump、基础备份、WAL、PITR、流复制能理解备份恢复边界
性能排查EXPLAIN ANALYZE BUFFERS、锁、膨胀、VACUUM能按证据排查慢 SQL
PostgreSQL 面试标准回答和追问能短答面试题,并跳回原理页

PostgreSQL 和 MySQL 最核心区别

维度PostgreSQLMySQL InnoDB
旧版本位置heap 中保留多个 tuple 版本undo log 版本链
清理机制VACUUM 清 dead tuplepurge 清 undo
执行计划验证EXPLAIN ANALYZE BUFFERS 看真实执行EXPLAIN + 慢日志 + optimizer trace
覆盖索引理解Index Only Scan 依赖 Visibility Map覆盖索引列齐即可减少回表
JSON 能力jsonb + GIN 很常用JSON 支持存在,但模式不同
运维重点VACUUM、膨胀、长事务、WALBuffer Pool、redo/binlog、主从延迟

如果你用 MySQL 思维套 PostgreSQL,最容易踩这几个坑:

  1. 以为更新会原地覆盖,不知道会产生新 tuple。
  2. 以为有索引就能完全不访问表,不知道可见性判断可能回 heap。
  3. 忽略长事务,导致 VACUUM 清不了 dead tuple。
  4. 用一个超大 JSONB 字段承载所有业务字段,导致约束、统计、索引都变差。
  5. 不看 actual rowsbuffers,只凭感觉调索引。

最小商业 Demo:医疗资产表

sql
create schema if not exists biz;

create table biz.medical_asset (
  id bigserial primary key,
  asset_no varchar(64) not null,
  hospital_id bigint not null,
  department_id bigint,
  status varchar(20) not null,
  asset_name varchar(128) not null,
  attrs jsonb not null default '{}',
  created_at timestamp not null default now(),
  updated_at timestamp not null default now(),
  constraint uk_medical_asset_no unique (asset_no),
  constraint ck_medical_asset_status
    check (status in ('IDLE', 'USED', 'REPAIR', 'SCRAPPED'))
);

create index idx_asset_hospital_status_created
on biz.medical_asset(hospital_id, status, created_at desc);

create index idx_asset_attrs_gin
on biz.medical_asset using gin(attrs);

查询计划:

sql
explain (analyze, buffers)
select id, asset_no, asset_name, status
from biz.medical_asset
where hospital_id = 1001
  and status = 'USED'
order by created_at desc
limit 20;

JSONB 查询:

sql
explain (analyze, buffers)
select id, asset_no
from biz.medical_asset
where attrs @> '{"deviceType":"CT"}';

状态更新:

sql
begin;

update biz.medical_asset
set status = 'USED',
    updated_at = now()
where asset_no = 'A001'
  and status = 'IDLE';

commit;

这个 Demo 背后的原理:

  1. uniquecheck 是数据库最后防线。
  2. B-tree 联合索引支撑列表查询。
  3. GIN 索引支撑 JSONB 包含查询。
  4. update 会生成新 tuple,旧 tuple 之后由 VACUUM 清理。
  5. EXPLAIN (ANALYZE, BUFFERS) 能看到真实行数和页访问。

PostgreSQL 最容易被问的原理

问题你应该跳到哪里
PostgreSQL 为什么需要 VACUUMMVCC、VACUUM 与 WAL
xminxmax 是什么MVCC、VACUUM 与 WAL
Index Only Scan 为什么还可能访问 heap索引与优化器
WAL 做什么MVCC、VACUUM 与 WAL
EXPLAIN ANALYZE BUFFERS 看什么性能排查
jsonb 为什么用 GIN索引与优化器
长事务为什么危险事务与锁
表膨胀怎么排查性能排查

商业项目中 PostgreSQL 怎么用

适合:

场景为什么适合
复杂 SQL 和报表窗口函数、CTE、复杂 Join 能力强
GISPostGIS 生态成熟
半结构化属性jsonb + GIN 适合灵活字段查询
数据治理平台类型、约束、扩展能力强
审计和查询平台SQL 表达能力强

不建议:

  1. 把 PostgreSQL 当 Redis 缓存。
  2. 把无限日志写入都塞进普通表,不做分区和归档。
  3. 所有字段都放 JSONB,放弃关系约束。
  4. 长事务导出大报表,阻止 VACUUM。
  5. 不维护统计信息和 autovacuum,只靠加索引解决慢。

学完 PostgreSQL 专栏的验收标准

你要能讲清:

  1. database、schema、role、table 是什么关系。
  2. heap page 和 tuple 是什么。
  3. 更新为什么生成新 tuple,而不是简单覆盖。
  4. xminxmax 和 snapshot 怎么判断可见性。
  5. VACUUM 清什么,为什么长事务会阻止清理。
  6. WAL 为什么能支持崩溃恢复、复制和 PITR。
  7. B-tree、GIN、BRIN 分别适合什么查询。
  8. EXPLAIN ANALYZE BUFFERS 中估算行数、实际行数、Buffers 怎么看。
  9. Index Only Scan 为什么还依赖 Visibility Map。
  10. 表膨胀、锁等待、从库延迟、WAL 暴涨怎么排查。

面试标准回答

text
PostgreSQL 是功能完整、SQL 标准和扩展能力很强的开源关系型数据库,适合复杂查询、JSONB、GIS、报表和强约束业务。它和 MySQL 最大区别之一是 MVCC 实现:PostgreSQL 更新通常生成新 tuple,旧 tuple 通过 xmin/xmax 和快照判断可见性,之后由 VACUUM 清理;MySQL InnoDB 更多依赖 undo log 版本链。PostgreSQL 使用 WAL 支持崩溃恢复、流复制和时间点恢复。生产排查要重点看 EXPLAIN ANALYZE BUFFERS、统计信息、长事务、锁、dead tuple、VACUUM、表膨胀和 WAL。