别空站队:按事务、复制与运维边界选 MySQL 或 PostgreSQL

别空站队:按事务、复制与运维边界选 MySQL 或 PostgreSQL

别空站队:按事务、复制与运维边界选 MySQL 或 PostgreSQL

源微信页常见验证码拦截。正文不沿用「谁更强 / 为什么还用」的口号句式,而以 MySQL 8.4 参考手册、PostgreSQL 17 文档 与社区公认工程事实为准,把选型落在场景边界:事务与隔离、复制与故障切换、JSON 与半结构化、生态与招人、运维成本。

两边都是成熟的关系型数据库,都能扛住绝大多数业务。真正浪费时间的,是用「功能清单谁更长」代替「你的团队今晚 3 点能不能修复制延迟」。

封面:按边界选型,不按口号


一、先停在场景,而不是停在信仰

选型争论通常从结论开始:「新项目一律 PostgreSQL」或「互联网就该 MySQL」。更稳妥的问法是四句:

1. 查询是简单主键 / 索引查找为主,还是多表 JOIN、窗口函数、分析型报表?

2. 一致性要求是「最终一致可接受」,还是「金融级可审计、可点时间恢复」?

3. 团队现成的 DBA / 监控 / 备份剧本写在哪一套工具链上?

4. 半结构化数据是偶尔塞 JSON,还是要当一等公民做检索与约束?

场景倾向 更常先看 MySQL 更常先看 PostgreSQL
读多写少、简单 CRUD、LAMP / WordPress 遗留 工具链与招人密度高 也能做,迁移成本要算
复杂 SQL、GIS、数组 / 范围类型、行级安全 能力相对薄 扩展与类型系统更完整
高并发写入 + 复杂事务 InnoDB 行锁成熟,但间隙锁要懂 MVCC 实现路径不同,默认隔离级别也不同
半结构化文档检索 8.0 JSON + 多值索引够用到一定规模 JSONB + GIN / 表达式索引更顺手
向量 / 地理扩展 生态有方案,但不是默认叙事 pgvector / PostGIS 事实标准感更强

没有「绝对赢家」。只有「当前团队、当前负载、当前故障剧本」下的可运维选择。


二、事务与并发:默认隔离级别差一级,行为就不一样

两边都宣称 ACID,但默认配置与 MVCC 实现路径不同,踩坑点也不同。

MySQL(InnoDB)

别空站队:按事务、复制与运维边界选 MySQL 或 PostgreSQL

  • 事务能力绑定存储引擎:真正谈 ACID,默认指 InnoDB;历史 MyISAM 不能当事务引擎用。
  • 默认隔离级别常见是 REPEATABLE READ。间隙锁(gap lock)、临键锁(next-key lock)在「防幻读」与「插入并发」之间拉扯,死锁与锁等待日志是日常功课。
  • Undo 日志承担版本链;长事务会拖住清理,表现为 undo 膨胀与历史版本读取变慢。

PostgreSQL

  • 默认隔离级别是 READ COMMITTED。同一事务里两次 SELECT 可能看到不同已提交快照——这是设计选择,不是「更弱所以落后」。
  • 行版本写在堆表上,旧版本靠 VACUUM / autovacuum 回收。长事务、大量更新、索引膨胀是运维主线,而不是「有没有间隙锁」。
  • 需要更强隔离时可用 REPEATABLE READ 或 SERIALIZABLE(SSI);金融级强一致场景要明确选隔离级别并压测冲突率,而不是只看默认值。

实践对照口诀:

关注点 MySQL 侧先查什么 PostgreSQL 侧先查什么
锁冲突 performance_schema / innodb_lock_waits、死锁日志 pg_locks、pg_stat_activity、等待事件
长事务副作用 undo 历史长度、purge 延迟 xmin horizon、autovacuum 积压、表膨胀
「读是否挡写」 受隔离级别与锁类型影响更大 读通常不阻塞写,但 vacuum 与 IO 会间接影响

别把「PostgreSQL 更正确」当成免责声明:默认 RC 下业务若假设可重复读,会自己埋雷。反过来,MySQL 默认 RR 也不是「更安全就无痛」——间隙锁会让高并发插入路径变得难调。


三、复制与高可用:物理流复制 vs binlog 生态

两边都能做主从与故障切换,差异在复制介质与工具成熟度。

MySQL

  • 经典路径是 binlog(语句 / 行 / 混合格式)。异步复制简单;半同步、组复制(MGR)把「丢数据窗口」和「多主冲突」往工程化推。
  • 故障切换与编排常用 Orchestrator、MHA、各类云托管的自动 failover。互联网公司剧本多,招人时「做过 MySQL 主从」几乎是标配。
  • 点时间恢复(PITR)依赖 binlog 保留策略与备份工具(如 xtrabackup)配合;能做,但流程要写进 runbook。

PostgreSQL

  • 主路径是 WAL 流复制(物理复制),延迟通常很低;逻辑复制适合迁表、部分表同步、跨大版本。
  • 高可用常用 Patroni + etcd/ZooKeeper、repmgr 等;pg_rewind 处理「旧主回退」是常见话术。
  • 原生 PITR 与 base backup 叙事清晰:归档 WAL + 基础备份即可回到时间点。代价是你必须认真对待归档磁盘与 slot 膨胀。

选型时不要只比「谁支持同步复制」,而要比:

1. 可接受的 RPO(丢多少秒数据)?

2. 切换是否要应用层改连接串,还是有 Proxy / VIP?

3. 跨机房延迟下,半同步 / 同步复制会不会把写入拖死?

复制与故障切换边界示意


四、JSON 与半结构化:都能存,不等于同样好查

「要不要用文档库」经常被简化成「MySQL / PostgreSQL 也有 JSON」。工程上要拆成三层:存得下、查得快、约束得住。

能力 MySQL 8.x PostgreSQL
存储 JSON 类型(内部有校验) JSON(文本)与 JSONB(二进制)
索引 生成列 + 二级索引;数组场景可用多值索引(8.0.17+) GIN / 表达式索引 / 部分索引,对嵌套查询更自然
运算符习惯 -> / ->>、JSON_EXTRACT、JSON_TABLE @>、?、路径操作符与 jsonb_path_query 等
约束 可用生成列 + CHECK,复杂文档约束仍偏应用层 CHECK + 域类型 + 更丰富的表达式,但仍建议文档形状稳定

本地对照脚本见 practice/compare_json.sql。结论很务实:

  • 文档是「附属字段、偶尔过滤」→ 两边都行,优先跟主库走。
  • 文档是「主查询入口、频繁嵌套包含查询」→ PostgreSQL 的 JSONB + GIN 通常少写胶水。
  • 文档形状天天变、还要跨文档事务与强关系 → 先怀疑数据模型,而不是先换引擎。

五、生态、招人与扩展:规模优势 vs 扩展面

MySQL 的规模优势仍然真实

  • PHP / WordPress / 大量国内中间件默认示例是 MySQL。
  • 监控、备份、审核、SQL 优化器周边工具与文章密度高。
  • 招聘市场上「会 MySQL」的候选人池更大;这意味着故障时更容易找到人。

PostgreSQL 的扩展面同样真实

  • 扩展机制把数据库变成「可装配平台」:PostGIS、pgvector、TimescaleDB、Citus 等把 GIS、向量、时序、分布式往外推。
  • 许可证是 PostgreSQL License(类 BSD),商业嵌入与云厂商改版摩擦相对小。
  • 连接模型是多进程:高连接数几乎必然要 PgBouncer / 连接池;这不是可选优化,是默认运维件。

云托管时代两边都能一键开实例。真正差的是:你们现有的告警规则、慢查询平台、备份校验剧本写在哪边。换引擎 = 换一整套操作记忆。


六、运维边界:连接、膨胀、参数与「看起来能跑」

把运维差异写成可检查清单,比口号有用。

MySQL 常见边界

  • max_connections、缓冲池(innodb_buffer_pool_size)、redo / undo 磁盘。
  • binlog 保留天数 vs 磁盘;从库延迟与并行复制配置。
  • 大表 DDL:在线 DDL / pt-online-schema-change 类工具的窗口与锁行为。
  • 字符集必须默认 utf8mb4,别再踩三字节 utf8 的历史坑。

PostgreSQL 常见边界

  • 连接数与进程内存:宁可池化,也不要「应用直接打满 max_connections」。
  • autovacuum 是否跟得上写入;大表是否需要手动 vacuum / reindex 策略。
  • WAL 归档与 replication slot:slot 滞后会撑爆磁盘。
  • 统计信息与 ANALYZE:优化器强,但也依赖统计新鲜度。

运维清单对照

practice/docker-compose.yml 提供一对可丢弃实例(MySQL 8.4 :3307,PostgreSQL 17 :5433),方便本地验证连接与 JSON 语法差异,不是性能基准。压测要对齐硬件、数据集、连接池与隔离级别,否则数字没有可比性。


七、给决策者的收敛路径

1. 存量系统:业务稳定、工具链成熟 → 继续 MySQL,把精力花在复制、备份校验与慢 SQL,而不是为了「追新」迁移。

2. 绿地项目且查询会变复杂:GIS / 向量 / 复杂分析 / 严格约束 → 优先评估 PostgreSQL,并预算连接池与 vacuum 运维。

3. 团队只会一边:先用会的那一边把备份、监控、演练做扎实;能力债比引擎债更贵。

4. 双库长期并存:可以,但要写清「系统级边界」——谁写主、谁做分析、如何避免双写一致性地狱。

5. 别用博客结论代替压测:用你们真实的 Top SQL、峰值连接、故障切换演练结果说话。

一句话收束:PostgreSQL 功能面更宽,不等于你的下一张工单更短;MySQL 生态更大,不等于复杂查询会自动变简单。 选边界,不选阵营。

💻 配套实训环境与动手练习

本文涉及的相关技术指令、开发环境与工具链已内置在边学边练在线实验室中,无需繁琐安装配置,随时在浏览器中实践体验:

文章版权声明:除非注明,否则均为边学边练网络文章,版权归原作者所有

最新文章

热门文章

本栏目文章