主流关系数据库横向对比:MySQL / PostgreSQL / Oracle / SQL Server 的架构、特性与选型

关系数据库的世界,表面上看是“都支持 SQL、都有事务、都有索引”,但真到了选型和排障的时候,MySQL、PostgreSQL、Oracle、SQL Server 之间的差异远比想象中大——连接是进程还是线程、表是堆表还是索引组织表、MVCC 把旧版本放在哪、默认隔离级别是什么……这些“底层选择”直接决定了性能特征、运维方式和适用场景。

这篇就把这四位最主流的选手放在一起做一次横向对比。不堆砌参数,而是聚焦那些“同样叫 RDBMS、实现却截然不同”的关键维度,最后给出选型建议。

顺带:本文是我数据库系列的横向补充——系列纵向讲了存储引擎、索引、事务、MVCC、复制等专题(见《数据库系列》一至十),这篇把它们横向铺开,看看四大库在每个维度上各自怎么选。

一、四位选手速览

MySQLPostgreSQLOracle DatabaseSQL Server
出身1995,Monty 创立;现属 Oracle 公司1996,伯克利 POSTGRES 衍生;社区 + EDB 等1977,Oracle 公司1989,微软(源自 Sybase 合作,后独立)
许可证GPL + 商业双许可PostgreSQL License(类 BSD,极宽松)专有商业(昂贵)专有商业
定位Web/互联网标配,简单可靠“最先进的开源 RDBMS”,功能全企业级旗舰,功能最全微软生态企业标配
谁在用海量互联网应用复杂业务 / AI / 地理 / 时序金融 / 电信 / 大型企业.NET / Windows 企业、Azure

二、一张表看全貌

维度MySQL (InnoDB)PostgreSQLOracleSQL Server
连接模型默认一连接一线程,也可使用线程池一连接一后端进程进程(dedicated)/ 共享服务器会话与工作线程解耦,由工作线程池调度请求
存储模型聚簇组织(主键叶节点存行数据)堆表堆表(默认),可选 IOT堆表或聚簇索引表
默认隔离级别REPEATABLE READREAD COMMITTEDREAD COMMITTEDREAD COMMITTED(悲观)
MVCC 旧版本存放undo log + purge堆内多版本 + VACUUMundo 段启用行版本后使用版本库;位置受版本和 ADR 配置影响
索引种类B+树、全文、空间;MEMORY 引擎支持 HashB树、Hash、GiST、GIN、BRIN、SP-GiSTB树、位图、反键、域索引聚簇/非聚簇、列存、全文、空间
复制与 HAbinlog 异步 / 半同步复制、MGR物理流复制 / 逻辑复制Data Guard / GoldenGate;RAC 属于共享数据库的集群方案Always On AG / FCI
多活MGR 多主(有限制)无原生(外部 Patroni 等)RAC(共享存储多实例)无原生多主
过程语言存储过程(SQL/PSM 风格)PL/pgSQL(+ Python/Perl…)PL/SQL(业界标杆)T-SQL
可扩展性插件式存储引擎极强(自定义类型/算子/扩展)强(官方闭源)CLR(.NET 扩展)
JSONJSON 类型 + 函数JSON / JSONB(支持多种索引方式)JSON 能力随版本持续增强传统版本以 nvarchar + JSON 函数为主;SQL Server 2025 的原生 json 类型适用性依部署平台而异
云服务Aurora MySQL / RDSAurora PG / Neon / SupabaseOCI Autonomous DBAzure SQL

下面挑几个最能体现“工程哲学差异”的维度展开。

三、架构与连接模型:进程 vs 线程

最容易感知的差异:一个连接占一个进程,还是占一个线程?

  • MySQL:默认是一连接一线程,也可按版本和发行版使用线程池。连接容量仍受每连接缓冲区、工作负载和服务器资源制约。
  • SQL Server:会话不等于固定线程。引擎使用工作线程池处理活跃请求,请求完成后工作线程可归还池中,即使连接仍保持打开。
  • PostgreSQL:一连接一后端进程。连接很多时会增加内存和调度成本;高连接并发场景通常会评估 PgBouncer 等连接池,但是否需要以及池多大必须由事务模式和压测决定。
  • Oracle:可选。dedicated server(每连接一进程)适合长连接;shared server(dispatcher + 共享服务器进程)适合海量短连接。

这一条会影响连接数规划和内存占用,但“线程一定轻、进程一定重”不是完整的选型结论。四种数据库的连接池、每会话状态、并行执行和工作负载模型同样重要。

四、存储模型:堆表 vs 索引组织表

这是理解四大库性能差异的钥匙(《数据库系列(二)》详细讲过,这里横向对照)。

  • 索引组织表(IOT / 聚簇):数据本身就存在主键的 B+ 树叶节点里,主键即数据
    • MySQL InnoDB、建立了聚簇索引的 SQL Server 表、Oracle 可选的 IOT。
    • 优点:主键点查 / 范围扫极快;代价是二级索引存的是主键值,往往要“回表”。
  • 堆表(heap):数据和索引分离,索引指向行的物理位置(PG 的 ctid / SQL Server 的 RID)。
    • PostgreSQL(默认)、Oracle(默认)、SQL Server(无聚簇索引时)。
    • 优点:无主键也能存、二级索引直接定位行、更新更灵活(配合 MVCC,新版本可写到任意空闲块)。

一句话:InnoDB 表按聚簇主键组织;SQL Server 表可以是 Heap 或按一个 Clustered Index 组织,主键约束通常默认创建聚簇索引,但并非无条件如此;PostgreSQL / Oracle 普通表默认是 Heap。 这些选择会影响主键查询、二级索引回表和更新行为。

五、事务与 MVCC:同一个思想,四种实现

四大库都实现了 MVCC(读不阻塞写),但旧版本放在哪、谁来清理各不相同——这是最见功底的地方:

  • MySQL InnoDB:数据页内就地更新,旧版本写入 undo log;读旧版本时用 undo 重构。后台 purge 线程清理不再需要的 undo。
  • PostgreSQL:旧版本直接作为新元组留在表堆里(用 xmin/xmax 标记可见性),表会“膨胀”,靠 VACUUM(autovacuum)回收空间。“PG 要调 autovacuum”是运维必修课。
  • Oracle:DML 的前镜像写入 undo 表空间(undo 段),读一致性从 undo 重构。最成熟的实现,也是 InnoDB / PG 思路的“祖师爷”。
  • SQL Server:传统的锁式 READ COMMITTED 依赖共享锁;启用 RCSI / SI 后使用行版本。SQL Server 2019 及以前主要把版本放在 tempdb;启用 Accelerated Database Recovery 后,相关版本由用户数据库中的 Persistent Version Store 管理,不能再一概写成只在 tempdb

默认隔离级别也值得注意(经典考点):

数据库默认隔离级别
MySQL InnoDBREPEATABLE READ(一致性读使用快照;锁定读和写入还涉及记录锁、间隙锁 / next-key 锁)
PostgreSQLREAD COMMITTED
OracleREAD COMMITTED(只支持 RC 与 SERIALIZABLE)
SQL ServerREAD COMMITTED(悲观;可切 RCSI)

MySQL 默认 RR 是个“异类”——大多数库默认 RC。做跨库迁移时,这点锁行为差异要特别留心(RR + 间隙锁容易引发意料外的锁冲突)。

六、索引能力

  • PostgreSQL 索引最丰富:B-tree、Hash、GiST(范围 / 几何)、GIN(数组 / 全文 / JSONB 利器)、BRIN(海量有序数据)、SP-GiST;还支持部分索引、表达式索引、覆盖索引。配合 JSONB / 数组,PG 能干很多“NoSQL 的活”。
  • MySQL:以 B+ 树为主,加全文、空间索引,以及 8.0+ 的降序 / 函数 / 不可见索引;类型相对少,但 InnoDB 聚簇 B+ 树在主键点查和范围扫上极高效。
  • Oracle:B 树、位图索引(适合低基数列,数据仓库利器)、反键索引(消除热点)、域索引;分区与索引组合极其丰富。
  • SQL Server:聚簇 / 非聚簇、列存索引(列式,OLAP 利器)、全文、空间;内存优化表(Hekaton)还有专属的哈希 / 非聚簇索引。

七、SQL 方言与可扩展性

  • 过程语言:Oracle PL/SQL 是业界标杆、功能最全;SQL Server T-SQL 在微软生态根深蒂固;PostgreSQL PL/pgSQL 仿照 PL/SQL,还能装 PL/Python、PL/V8 等多语言;MySQL 的存储过程相对朴素。
  • 可扩展性(PG 的杀手锏):PostgreSQL 允许自定义类型、操作符、索引方法、聚合,并通过 CREATE EXTENSION 装载扩展——于是有了 PostGIS(地理空间)、pgvector(AI 向量)、TimescaleDB(时序)等“长在 PG 上的专用数据库”。这种“一个内核、千变扩展”的生态,是其它三者没有的。
  • CLR(SQL Server):可以用 C# / .NET 写存储过程、类型、函数,和微软技术栈无缝衔接。
  • Oracle:功能强但闭源,扩展主要靠官方和 PL/SQL 包。

八、复制与高可用

复制方式多活能力
MySQLbinlog 异步 / 半同步复制、MGR 组复制、InnoDB ClusterMGR 多主模式(有冲突与工作负载约束)
PostgreSQL物理流复制(WAL,同步 / 异步)、逻辑复制(10+);HA 靠 Patroni / repmgr 等外部编排无原生多主
OracleData Guard(物理 / 逻辑备库)、Active Data Guard(只读备库)、GoldenGate(逻辑);RAC(共享数据库 + 多实例)RAC 可让多个实例同时提供服务,但不是多份数据库之间的多主复制
SQL ServerAlwaysOn AG(日志同步,可读次要副本)、FCI(故障转移集群)无原生多主

亮点:Oracle RAC 让多个实例访问同一个数据库,重点是实例级高可用和横向扩展;它不是把多份数据做多主复制。MySQL MGR 是成员之间复制并认证事务的组复制,两者的数据架构、冲突模型和故障语义不同,不能把 MGR 简称为“开源版 RAC”。PostgreSQL 提供物理/逻辑复制能力,自动故障转移通常还需要 Patroni 等外部编排。

九、生态与云

  • MySQL:互联网事实标准,配合 Vitess / PlanetScale、Aurora MySQL,云原生方案最成熟。
  • PostgreSQL:开源生态最活跃,Aurora PG、AlloyDB、Neon、Supabase 百花齐放;AI 时代因 pgvector 重新翻红。
  • Oracle:企业级护城河深,Exadata 一体机、OCI Autonomous DB,但云转型相对慢。
  • SQL Server:和 Windows / .NET / Azure 深度绑定,Azure SQL 是云上主力。

十、选型建议(按场景)

  • 互联网 / Web 应用,读多写多,追求简单和生态MySQL。运维资料最多、人才最多、云方案最成熟。
  • 业务逻辑复杂,要 JSONB / 数组 / 全文 / 地理空间 / AI 向量,追求 SQL 标准与扩展性PostgreSQL。“一个 PG 顶好几个专用库”。
  • 金融 / 电信 / 大型企业,需要 RAC 共享数据库多实例、Data Guard 等成熟能力,且预算和团队经验匹配 → 可重点评估 Oracle。具体许可和 TCO 要按版本、选件、核数及部署方式核算。
  • 微软技术栈(.NET / Windows / Azure),企业 OLTP + BI 一体SQL Server。和现有基础设施最贴合。
  • 嵌入式 / 移动端 / 边缘SQLite(不在四位之列,但几乎无处不在)。
  • 评估 MySQL 的开源分支 → 可考察 MariaDB。它源自 MySQL 分叉,但经过长期独立演进后,功能、复制、认证插件、系统表和部分 SQL 行为已有差异;迁移前必须按目标版本做兼容性验证,不能把它视为无条件替换。

结语

四大关系数据库,表面都是“SQL + 事务 + 索引”,底层却是四套不同的工程哲学:连接用进程还是线程、表是堆还是树、MVCC 旧版本放哪、默认隔离多激进、复制怎么做多活、能不能长出扩展生态。这些差异没有绝对优劣,只有“和你的场景、团队、基础设施是否匹配”。

选型的本质,不是选“最好的数据库”,而是选“约束下最合适的数据库”——数据规模、一致性要求、HA 形态、团队技能栈、预算,共同决定了答案。理解了这张横向对比,你就能在“为什么是它而不是另一个”这个问题上,给出有底气的回答。