PostgreSQL vs MySQL

两大主流关系型数据库的全面对比:架构原理、核心差异、适用场景

🎯 核心定位对比

维度 PostgreSQL MySQL
诞生年份 1996(加州大学伯克利) 1995(MySQL AB公司)
类型 高级关系型数据库(ORDBMS) 传统关系型数据库(RDBMS)
哲学 追求功能完备与标准遵循 追求简单、高效、可靠
License PostgreSQL License(BSD) GPL / 商业许可

🏗️ PostgreSQL 架构原理

客户端层
psql / 驱动
客户端应用
↓ 客户端协议
Postmaster
:5432 主进程
连接管理 / 认证
↓ fork()
Backend 1
连接1
Backend 2
连接2
...
连接N
Shared Memory 共享内存
Buffer Pool WAL Buffer Lock Manager
Heap
表数据
Index
B-Tree/Hash...
WAL
预写日志

⚙️ 进程模型

PostgreSQL 采用"每连接一进程"模型,每个客户端连接由独立的 postgres 后端进程 处理。

  • 主进程 (postmaster):监听端口、管理连接、进行认证
  • 后端进程:处理 SQL 执行,每个连接一个
  • 后台进程:WAL 写入器、检查点、VACUUM 等

💾 共享内存

所有后端进程共享一块内存区域,避免数据不一致。

  • Buffer Pool:缓存数据页,减少磁盘 IO
  • WAL Buffer:暂存事务日志
  • Lock Manager:管理并发锁

🔄 MVCC 多版本并发控制原理

PostgreSQL 通过 MVCC 实现读写不互斥的并发控制,让读操作永不阻塞写操作。

T1
事务 A 开始

BEGIN;

T2
事务 A 执行 UPDATE

UPDATE users SET name='Alice' WHERE id=1;

旧版本: xmin=T1, xmax=T2, name='Tom'
新版本: xmin=T2, xmax=∞, name='Alice'
T2
事务 B 读取(快照隔离)

SELECT * FROM users WHERE id=1;

→ 看到 name='Tom'
(因为事务 A 还未提交)

T4
事务 A 提交

COMMIT;

T5
事务 B 再次读取

→ 仍看到 name='Tom'

(快照隔离!事务 B 的快照从 T2 就锁定了)

📋 关键概念

  • xmin:插入该行的事务 ID
  • xmax:删除/更新该行的事务 ID(未设置=活着)
  • t_ctid:行在表中的物理位置指针

👁️ 可见性判断规则

  • xmin 事务已提交
  • xmin < 当前快照的 XID
  • xmax 未提交或已回滚

📊 PostgreSQL 索引类型

🌲
B-Tree
默认索引

适用:=, <, >, <=, >=, BETWEEN, LIKE

最通用的索引类型,平衡读写性能。

#️⃣
Hash
等值查询

适用:= 精确匹配

不支持范围查询,但等值查询最快。

🗺️
GiST
几何/范围

适用:地理位置、全文检索、树形结构

PostGIS 插件使用此索引。

📑
GIN
倒排索引

适用:JSONB、数组、全文搜索

适合多值列(数组包含查询)。

📦
BRIN
块范围索引

适用:时序数据、日志、顺序写入的大表

空间极小(O(1)),适合物理顺序与值相关的场景。

🔢
Partial
部分索引

适用:只索引满足条件的行

CREATE INDEX ON orders WHERE status='pending'

各自核心优势

🎯 企业级功能

  • 完整的 ACID 支持
  • MVCC 实现真正的并发读写
  • 四种隔离级别(默认 READ COMMITTED)

🔧 扩展性极强

  • 支持自定义类型、操作符、索引、函数
  • FDW 可以把 Oracle、MongoDB 当表 JOIN
  • 插件生态:PostGIS、pgvector、TimescaleDB

📊 数据处理

  • 窗口函数、CTE、递归查询
  • 多核并行查询优化
  • 物化视图加速复杂查询

🏗️ 高级特性

  • 行级触发器(MySQL 是语句级)
  • 规则系统、咨询锁
  • 逻辑复制支持复杂拓扑

🚀 性能与简单

  • 架构简单,InnoDB 性能出色
  • 社区活跃,文档完善
  • 轻量级,资源消耗低

🌐 生态完善

  • LAMP/LEMP 标配
  • 云厂商深度优化(RDS MySQL)
  • 大量中间件支持

💰 成本效益

  • 开源免费(社区版)
  • 与 PHP/Python/Node 配合良好
  • 大量开源项目默认使用

📱 互联网基因

  • 互联网公司标配
  • 分库分表方案成熟
  • 阿里、Facebook 等大规模验证

📋 核心特性对比表

特性 PostgreSQL MySQL
MVCC ✅ 原生,所有隔离级别 ⚠️ 仅 REPEATABLE READ
数组类型 ✅ 原生支持 ❌ 需 JSON 模拟
JSONB ✅ 高性能二进制存储 ⚠️ JSON 支持
窗口函数 ✅ 完全支持 ⚠️ MySQL 8.0+
CTE/递归 ✅ 完全支持 ⚠️ MySQL 8.0+
物化视图 ✅ 支持 ❌ 需手动实现
并行查询 ✅ 多核并行 ⚠️ 有限支持
FDW ✅ 万物皆表 ❌ 不支持
GIS 支持 ✅ PostGIS 强大 ⚠️ 基础支持
向量检索 ✅ pgvector ⚠️ 需第三方

🌲 选型决策树

需要复杂数据类型(数组/JSONB/自定义类型)吗?
YES → PostgreSQL
继续判断
需要高级分析能力?
YES → PostgreSQL
是互联网项目?需要最高性能?
YES → MySQL
继续判断
是传统企业应用?
YES → PostgreSQL
团队更熟悉哪个?
PostgreSQL
MySQL

📝 总结与选型建议

✅ 选择 PostgreSQL 当

  • 需要复杂数据分析、报表
  • GIS 地理信息系统
  • 需要 JSONB 高效查询
  • AI/向量相似搜索
  • 时序数据监控(TimescaleDB)
  • 企业级应用、ERP
  • 需要从 Oracle 迁移

✅ 选择 MySQL 当

  • 传统 Web 应用、CMS、电商
  • 互联网大流量写入
  • 需要分库分表
  • 团队更熟悉 MySQL
  • 需要成熟的主从复制
  • 使用 PHP 作为后端
  • 简单 CRUD 场景
💡

核心差异一句话总结

MySQL:简单、快速、互联网标配 → PostgreSQL:功能完备、企业级、标准遵循

MySQL 追求 pragmatism(实用主义),PostgreSQL 追求 correctness(正确性)。两者都是优秀的选择,关键在于理解你的业务场景。