从零开始的 PostgreSQL 学习笔记,覆盖安装、SQL 基础、高级特性、运维管理。
图表在
/PostgreSQL学习笔记/diagrams/目录。
📌 MySQL vs PostgreSQL:MySQL 简单易用、生态广、Web 场景占比高。PostgreSQL 功能更全、SQL 标准更严格、复杂查询性能更好、支持 JSON/GIS/全文检索。简单 Web 用 MySQL,复杂分析/GIS/JSON 用 PG。
| 优势 | 说明 |
|---|---|
| SQL 标准合规 | 最接近 SQL 标准的数据库 |
| 丰富的数据类型 | JSON/JSONB、数组、范围类型、几何、UUID、枚举 |
| 强大的扩展性 | PostGIS(GIS)、pgvector(向量)、TimescaleDB(时序) |
| MVCC | 多版本并发控制,读写互不阻塞 |
| CTE / 窗口函数 | 复杂分析查询的利器 |
| 可编程 | PL/pgSQL、PL/Python、PL/Perl 存储过程 |
📌 PG vs MySQL 内存参数:MySQL 的 innodb_buffer_pool_size 建议 60-70%,PG 的 shared_buffers 建议 25%。因为 PG 还依赖操作系统文件缓存,effective_cache_size(75%)反映总可用缓存。
| 特性 | MySQL | PostgreSQL |
|---|---|---|
| 引擎 | 多引擎(InnoDB/MyISAM) | 单引擎(统一) |
| 大小写敏感 | 不敏感 | 敏感(需加引号) |
| 自增 | AUTO_INCREMENT |
SERIAL / GENERATED ALWAYS AS IDENTITY |
| 字符串拼接 | CONCAT(a, b) |
`a |
| 引号 | 双引号/单引号都可 | 双引号=标识符,单引号=字符串 |
| 布尔类型 | 无(用 0/1) | TRUE / FALSE |
| 默认事务隔离 | REPEATABLE READ | READ COMMITTED |
📌 DISTINCT ON 是 PG 独有功能:DISTINCT ON (department) 按部门去重,每组保留排序后的第一条。等价于 MySQL 的窗口函数 ROW_NUMBER() OVER(PARTITION BY department ORDER BY salary DESC) = 1,但写法更简洁。
| 类型 | 说明 | 适用场景 |
|---|---|---|
| B-Tree(默认) | 平衡树 | 等值、范围、排序 |
| Hash | 哈希表 | 仅等值查询 |
| GIN | 倒排索引 | JSONB、数组、全文搜索 |
| GiST | 通用搜索树 | 几何、范围、最近邻 |
| BRIN | 块范围索引 | 大表、有序数据(时间序列) |
| SP-GiST | 空间分区 | 非平衡数据结构 |
📌 GIN 索引是 PG 的杀手锏:JSONB + GIN 可以高效查询 JSON 文档中的任意字段。@>(包含)操作符配合 GIN 索引,让 PG 可以当文档数据库用。
📌 部分索引:只索引满足条件的行,索引更小更快。比如只索引活跃用户 WHERE is_active = TRUE,跳过大量历史数据。
📌 PG 的 MVCC:每行数据有 xmin(创建事务 ID)和 xmax(删除事务 ID)。UPDATE 不是原地修改,而是标记旧行为删除 + 插入新行。读操作只看到在当前事务之前已提交的版本,读不阻塞写,写不阻塞读。
📌 MVCC 的代价:死元组(dead tuples)需要 VACUUM 清理。定期运行 VACUUM 和 ANALYZE 是 PG 运维的核心任务。
📌 VACUUM vs VACUUM FULL:普通 VACUUM 标记空间可复用但不还操作系统(不锁表)。VACUUM FULL 物理回收空间但锁表。生产环境用普通 VACUUM,低峰期偶尔 VACUUM FULL。
| 类型 | 说明 | 示例 |
|---|---|---|
UUID |
唯一标识 | gen_random_uuid() |
JSONB |
二进制 JSON | {"name": "alice", "age": 30} |
TEXT[] |
文本数组 | {admin, user, guest} |
INET |
IP 地址 | 192.168.1.1 |
INTERVAL |
时间间隔 | '1 day'::INTERVAL |
MONEY |
货币 | $19.99 |
POINT |
几何点 | (1.5, 2.3) |
HSTORE |
键值对 | "key"=>"value" |
ENUM |
枚举 | CREATE TYPE status AS ENUM ('active', 'inactive') |
📌 JSON vs JSONB:JSON 存原始文本(保留空格/顺序),JSONB 存解析后的二进制(更快查询、支持索引)。生产环境用 JSONB。
PG 的 JSONB 支持让它可以兼做文档数据库:
📌 递归 CTE:PG 的递归 CTE 可以遍历树形结构(组织架构、评论回复、分类树)。MySQL 8.0 也支持了,但 PG 的实现更早更成熟。
📌 分区表的好处:① 查询只扫描相关分区(分区裁剪)② 可以快速删除整个分区(DROP PARTITION 比 DELETE 快)③ 每个分区可以独立维护。
📌 PG 流复制 vs MySQL 主从:原理类似(基于 WAL/binlog),但 PG 支持同步复制(数据零丢失)和级联复制。PG 14+ 增加了逻辑复制(可选择性复制表)。
| 关键指标 | 关注点 |
|---|---|
| Seq Scan | 全表扫描,大表需优化 |
| Index Scan | 索引扫描 |
| Index Only Scan | 覆盖索引(最佳) |
| Hash Join | 哈希连接(大表) |
| Nested Loop | 嵌套循环(小表) |
| Sort | 排序,大数据量需关注 |
| 功能 | MySQL | PostgreSQL |
|---|---|---|
| 自增 | AUTO_INCREMENT |
SERIAL / IDENTITY |
| 布尔 | TINYINT(1) |
BOOLEAN |
| 字符串拼接 | CONCAT() |
|| |
| 类型转换 | CAST() |
:: |
| 日期函数 | NOW() |
NOW() / CURRENT_TIMESTAMP |
| 分页 | LIMIT offset, count |
LIMIT count OFFSET offset |
| JSON | JSON 类型 |
JSONB(更强大) |
| 数组 | 无 | TEXT[] 等 |
| 窗口函数 | 8.0+ | 早就支持 |
| 递归 CTE | 8.0+ | 早就支持 |
| GIS | 较弱 | PostGIS(业界标准) |