PostgreSQL 与 MySQL 选型
治理与许可证、2026 年版本现状、能力与行为差异,以及什么时候选 MySQL 才是诚实的答案
PostgreSQL 和 MySQL 都是通用的开源客户端/服务器关系型数据库,都为事务负载而设计——这是少数两个系统真正在回答同一个问题的对比。真正驱动选型的差异在于治理模式、版本生命周期、SQL 语义的严格程度和可扩展性,而不是跑分数字。
2026-08 对照官方来源核对
本页的版本与支持陈述以 2026 年 8 月核对的官方生命周期页面为准:PostgreSQL 版本政策、endoflife.date 的 MySQL 页(对应 Oracle 生命周期支持政策)以及 PostgreSQL Beta 计划。涉及具体版本的细节请在依赖前复核。
治理与许可证
| PostgreSQL | MySQL | |
|---|---|---|
| 主导方 | PostgreSQL 全球开发组,分布式社区,没有单一公司控制项目 | Oracle,2010 年经收购 Sun 获得 MySQL |
| 许可证 | PostgreSQL License——宽松的类 BSD 许可证 | 双许可:GPLv2 社区版 + Oracle 出售的商业许可证 |
| 实际影响 | 任何人都可以在其上构建商业产品而无需许可证谈判;分支与衍生数据库很常见(见 PostgreSQL 血缘与兼容数据库) | 把 MySQL 嵌入对外分发的专有产品通常需要 Oracle 的商业许可;路线图由单一厂商决定 |
正常使用应用层面两种许可证都不构成限制。差异在于:当你要再分发数据库本身,或者采购上在意路线图被单一厂商控制时,它才变得重要。
版本现状(2026 年)
两个项目的发布节奏完全不同。
MySQL(据 endoflife.date/mysql):
| 版本 | 2026 年 8 月时的状态 |
|---|---|
| 8.0 | 已终止支持:Premier 支持 2025 年 4 月结束,Extended 支持 2026 年 4 月结束——社区用户不再获得任何修复 |
| 8.4 LTS | 支持中;Premier 至 2029 年 4 月,Extended 至 2032 年 4 月 |
| 9.0–9.6 Innovation | 季度功能发布,每个版本只支持到下一个版本发布;均已结束 |
| 9.7 LTS | 2026 年 4 月发布;Premier 支持至 2034 年 4 月 |
Oracle 的模式:Innovation 版本约每季度发布一次、很快过期;大约每两年指定一个 LTS 版本,提供 5 年 Premier + 3 年 Extended 支持。Extended 支持是商业项目——停在 EOL 版本上的社区用户什么也得不到。
PostgreSQL(据版本政策):
| 版本 | 支持至 |
|---|---|
| 14 | 2026 年 11 月 12 日(最后几个月) |
| 15 | 2027 年 11 月 |
| 16 | 2028 年 11 月 |
| 17 | 2029 年 11 月 |
| 18 | 2030 年 11 月 |
| 19 | Beta 阶段(2026 年 8 月时为 Beta 2);不可用于生产 |
每年一个大版本,每个大版本支持五年,所有修复免费。生命周期没有付费层级:社区发布就是唯一的发布。
能力差异
| PostgreSQL | MySQL(InnoDB) | |
|---|---|---|
| 事务与隔离级别 | 默认 READ COMMITTED;REPEATABLE READ 与 SERIALIZABLE 完全基于 MVCC(可串行化用 SSI 实现) | 默认 REPEATABLE READ,配合 next-key lock;四种标准隔离级别都可用 |
| DDL 事务性 | 多数 DDL 可随事务回滚——schema 迁移可以是原子的 | DDL 触发隐式提交;迁移中途失败可能留下应用了一半的 schema |
| JSON | jsonb 二进制存储、丰富的操作符、GIN 索引 | 5.7 起有二进制 JSON 类型;索引需借助生成列 |
| CTE 与窗口函数 | 历史悠久(递归 CTE 与窗口函数自 8.4 起,2009 年) | 8.0 起(2018 年) |
| 扩展生态 | 装载进服务器的扩展,可增加类型、索引、规划器钩子(PostGIS、pgvector、TimescaleDB);见扩展生态 | 插件 API 以存储引擎为中心;没有可比的机制来增加类型或索引方法 |
| 复制模型 | 内置物理流复制;10 起内置逻辑复制 | 基于 binlog 的复制(行/语句模式);高可用用 Group Replication / InnoDB Cluster |
| 存储引擎 | 单一引擎(heap),索引访问方法可插拔;12 起有表访问方法接口 | 可插拔存储引擎;InnoDB 是默认,也是当前实际唯一在用的支持事务的引擎 |
这张表把二十年的分叉压缩成行;没有任何一行是一票否决。真实项目里最常决定结果的行是:DDL 事务性、扩展生态、复制与高可用工具链。
行为差异陷阱
这些差异不会在选型时咬人,会在迁移时咬人:
- 隐式类型转换。 MySQL 的转换很宽松——把
'abc'插入整数列会变成0并给一个警告(只有在严格模式下才是错误);字符串列与数字比较时会悄悄转换。PostgreSQL 直接报错。在 MySQL 上"能跑"的查询到 PostgreSQL 上大声失败,而这是正确的结果。 - 严格模式。 MySQL 的很多宽松行为由
sql_mode控制;STRICT_TRANS_TABLES自 5.7 起进入默认模式,但更老的应用和更老的默认值会静默截断数据、接受'2024-02-30'这样的非法日期。PostgreSQL 没有非严格模式。 - 大小写。 PostgreSQL 把未加引号的标识符折叠为小写,字符串比较默认区分大小写。MySQL 的表名大小写敏感性取决于
lower_case_table_names和文件系统,默认排序规则(*_ci)的字符串比较不区分大小写。往哪个方向迁移都会暴露双方的隐含假设。 - 自增 vs identity/sequence。 MySQL 用
AUTO_INCREMENT列和LAST_INSERT_ID()。PostgreSQL 用GENERATED ... AS IDENTITY(SQL 标准,自 PostgreSQL 10 起),底层是 sequence;惯用写法是用RETURNING子句取回新 id,而不是会话级函数。 - GROUP BY 宽松语义。 MySQL 5.7 之前允许 SELECT 中出现不在
GROUP BY里、也未聚合的列,返回任意一行的值。ONLY_FULL_GROUP_BY自 MySQL 5.7 起默认开启,所以当前的 MySQL 与 PostgreSQL 行为一致——但按宽松语义写的遗留代码仍会在迁移时冒出来。
什么时候选哪个
选 MySQL 的正当理由:
- 应用生态说了算。 WordPress、大多数 LAMP 时代的 PHP 应用和很多商业产品只针对 MySQL/MariaDB 测试。把它们跑在 PostgreSQL 上意味着兼容性风险由你自己承担。
- 团队经验。 一支有十年 MySQL 运维伤痕的团队,把 MySQL 跑得比它不了解的数据库更安全。这是正当的、往往是决定性的理由。
- 平台可用性。 虚拟主机、cPanel 类平台和部分托管服务只提供 MySQL/MariaDB。
- 特定工具链。 InnoDB Cluster / MySQL Shell 的管理体系,或与 Oracle 的商业支持关系,本身就可能就是硬性要求。
选 PostgreSQL 的正当理由:
- 复杂 SQL 与严格完整性。 让迁移更安全的 DDL 事务性、严格类型系统、更强的约束与隔离语义——见事务。
- 一台引擎承担文档、地理或向量负载:
jsonb、PostGIS、pgvector。 - 可扩展性。 自定义类型、操作符、索引方法,以及 MySQL 没有对等物的扩展生态。
- 治理独立性。 没有单一厂商决定路线图,也没有悬在头上的商业许可证。
在这两者之间,跑分很少是诚实的决定因素;运维契合度通常才是。
迁移指路
从 MySQL 迁到 PostgreSQL 主要是语义移植而非数据拷贝:pgloader 负责搬 schema 和数据,但上文的行为差异(类型强转、大小写、GROUP BY、自增)才是需要测试的部分。相邻的决策参考:如果同时涉及 Oracle,见 Oracle 迁移到 PostgreSQL 指南;选型问题的简答汇总见对比常见问题。
相关页面
- PostgreSQL 与 MariaDB 选型——MySQL 血脉上的另一个对比
- PostgreSQL 血缘与兼容数据库——复用 PostgreSQL 本身的系统
- 事务——上文引用的隔离级别与 DDL 语义
- PostgreSQL 版本政策——更详细的支持生命周期
Last updated on