MySQL vs PostgreSQL
MySQL vs PostgreSQL 最全对比
MySQL 和 PostgreSQL 是当今最主流的两个开源关系数据库。本章从架构、功能、性能、生态四个维度进行深度对比,并给出明确的选型建议。基准版本:MySQL 8.4 LTS vs PostgreSQL 16。
**结论先行:**两者都是优秀的生产级数据库,90% 的场景任选其一都行。真正的差异体现在:复杂 SQL/JSON/地理空间 → PG 更强;Web 应用/云生态/极高并发读 → MySQL 更广泛支持。
1. 背景与定位
| MySQL | PostgreSQL | |
|---|---|---|
| 创始 | 1995年,Sun → Oracle 收购 | 1986年,加州大学伯克利分校,真正的开源 |
| 许可 | GPL v2(Oracle 商业版另计) | PostgreSQL License(极宽松,类 BSD) |
| 定位 | "Web 数据库",简单高效,广泛普及 | "世界最先进开源 RDBMS",功能完整,SQL 标准 |
| 市场份额 | 全球第一(Web/云领域) | 增长最快,企业级渗透率快速提升 |
| 知名用户 | Facebook/字节/阿里/YouTube | Apple/Instagram/Reddit/Heroku |
2. 架构核心差异
2.1 MVCC 实现方式
| MySQL InnoDB | PostgreSQL | |
|---|---|---|
| 旧版本存储 | Undo Log 段(分离存储) | 行内存储(同一堆文件中的 dead tuple) |
| 读操作 | 从 Undo Log 重建旧版本 | 直接读 dead tuple(物理上就在那里) |
| 写放大 | 较低(旧版本只写一次 Undo) | 较高(UPDATE = 写新行 + 旧行标记删除) |
| 清理机制 | Purge 线程清理 Undo Log | VACUUM 清理 dead tuples(需要维护) |
| 表膨胀 | 不会(Undo 独立) | 高写入场景下表文件膨胀(需定期 VACUUM FULL) |
**PostgreSQL VACUUM 问题:**高频 UPDATE/DELETE 场景下,PG 表文件会快速膨胀,必须定期 autovacuum 回收空间。MySQL 的 Undo Log 独立,不存在此问题。这是 PG 在高频写场景的一个重要运维成本。
2.2 存储引擎
- **MySQL:**可插拔存储引擎(InnoDB/MyISAM/Memory/Archive)。InnoDB 是默认且唯一推荐的。
- **PostgreSQL:**单一存储引擎,统一架构,但支持通过扩展(Extension)定制。
2.3 进程模型
- **MySQL:**多线程模型,每个连接一个线程(或线程池)
- **PostgreSQL:**多进程模型,每个连接 fork 一个 Backend 进程。连接开销更高,必须使用 PgBouncer 连接池。
3. 功能特性对比
| 特性 | MySQL 8.4 | PostgreSQL 16 | 胜出 |
|---|---|---|---|
| SQL 标准合规 | 较低(部分标准行为不同) | 较高(SQL:2016 大部分合规) | PG |
| 窗口函数 | 8.0+ 支持,完整 | 完整,更早支持 | 持平 |
| CTE / 递归 CTE | 8.0+ 支持 | 支持(更早,性能更好) | PG |
| JSON 支持 | JSON 列 + 函数(较弱的索引) | JSONB(二进制,GIN 索引,查询超强) | PG |
| 全文检索 | 基础 FTS(ngram 中文) | 完整 FTS + tsvector(更强) | PG |
| 地理空间(GIS) | 基础 Geometry 类型 | PostGIS 扩展(行业标准) | PG |
| 分区 | RANGE/LIST/HASH/KEY + 分区裁剪 | RANGE/LIST/HASH(更灵活,支持附着) | 持平 |
| 外键约束 | 支持 | 支持(更严格) | 持平 |
| CHECK 约束 | 8.0.16+ 真正强制 | 一直支持且严格 | PG |
| 自定义类型 | 基础 | 丰富(ENUM/Range/自定义类型/Domain) | PG |
| 存储过程语言 | 只有 SQL/MySQL 专有语法 | PL/pgSQL / PL/Python / PL/Perl 等多语言 | PG |
| 并行查询 | 有限支持 | 完整并行 Seq/Index/Agg/Join Scan | PG |
| LATERAL | 8.0+ 支持 | 一直支持 | 持平 |
| Online DDL | Instant DDL,大多数操作无锁 | 部分操作需要重写(pg_repack 弥补) | MySQL |
| 复制 | 成熟(GTID/组复制) | 逻辑复制(15+增强),物理复制 | 持平 |
| 向量搜索 | 9.x VECTOR 类型(实验性) | pgvector 扩展(成熟,广泛用于 AI) | PG |
4. 性能对比
4.1 读性能(OLTP 点查询)
两者差异不大,主要取决于硬件和配置。MySQL InnoDB 在极高并发简单查询(如 sysbench oltp_read_only)上略有优势,主要因为线程模型比进程模型上下文切换少。
4.2 写性能(高并发写)
MySQL 在高并发 INSERT 场景略优,因为 Undo Log 机制的写放大较小。PG 在高频 UPDATE 后需要 VACUUM,可能影响写入峰值。
4.3 复杂查询(OLAP)
PostgreSQL 明显更强:并行查询、更好的 Hash Join 实现、更精确的统计信息、BRIN 索引等。MySQL 的复杂分析查询性能较差。
4.4 JSON 操作
PostgreSQL JSONB + GIN 索引远超 MySQL JSON 列。PG 可以对 JSON 字段内任意路径建 GIN 索引,MySQL 只能建有限的函数索引。
5. 生态与工具对比
| 方向 | MySQL | PostgreSQL |
|---|---|---|
| 云原生 | RDS/Aurora(AWS)、Cloud SQL、阿里云 RDS — 成熟托管 | RDS for PG、Aurora PG、Supabase、Neon、Tembo |
| ORM 支持 | Hibernate/MyBatis/GORM/Sequelize — 全覆盖 | 同上,全覆盖 |
| BI/分析工具 | 广泛支持 | 广泛支持 |
| CDC/流处理 | Canal/Maxwell/Debezium 成熟 | Debezium PG connector 成熟 |
| AI/向量 | HeatWave ML(商业) | pgvector(免费,成为 AI 应用标配) |
| 扩展生态 | 有限 | 丰富(PostGIS/TimescaleDB/Citus/pgvector/pgroonga等) |
| 国内普及度 | 极高(互联网行业首选) | 正在快速增长(尤其出海/SaaS/AI 应用) |
6. 选型建议
优先选 MySQL 的场景
- 传统互联网 Web 应用(LAMP/LNMP 技术栈)
- 国内团队,运维人才储备更多
- 需要极高并发读(搭配读写分离)
- 已有大量 MySQL 运维经验和工具链
- 使用 AWS Aurora MySQL 或阿里云 RDS MySQL
优先选 PostgreSQL 的场景
- 需要强 JSON/文档存储(替代 MongoDB)
- 地理空间数据(PostGIS 无对手)
- 复杂分析查询(OLAP 混合)
- AI 应用(pgvector 存储 Embedding)
- 出海 SaaS(国际团队更熟悉 PG,Supabase/Neon 生态更现代)
- 需要严格 SQL 标准合规
- TimescaleDB 时序数据场景
**最终建议:**如果你是新项目,团队对两者都有一定了解,且有 AI 功能规划 → 选 PostgreSQL(pgvector + 更完整的功能集)。如果是国内业务扩展、已有 MySQL 团队经验、或互联网高并发读场景 → MySQL 依然是安全选择。两者都很好,选择取决于你的具体约束,而非哪个"更好"。