
2025年9月25日,PostgreSQL 18 正式发布。如果你是在冲刺计划中间隙扫了一眼发布说明,然后把它归档为"小版本升级",建议回头再看看。这版本里落地的五件事,恰好就是你们团队 2023 年在 Confluence 上建的那个"可能需要把部分业务迁移到 Mongo / Dynamo / Cassandra"文档的五个理由。
现在你可以停更那个文档了。你当初标记的那些场景,大部分现在在 Postgres 里都有可行方案了——一套 schema、一套操作符、一套备份策略,全搞定。
这次最重头的功能是异步 I/O 子系统。Postgres 现在可以同时处理大量请求,Xata 和 Crunchy Data 报告在 NVMe 上能达到 2~3 倍的加速。
这个功能直接干掉的场景是:"我们需要 Cassandra 来处理写入密集型时序数据摄入"。有了 AIO,分析侧的扫描已经足够快,你不需要再维护第二套存储了。
但它干不掉的:真正跨区域的大规模水平扩展。AIO 是单节点层面的特性,别指望它来解决全球化问题。
PG18 内置了 uuidv7() 函数。UUIDv7 在高位嵌入毫秒级时间戳,生成的 ID 天然按创建时间排序。这解决了 UUIDv4 主键最让人头疼的 B 树碎片化问题。
这个功能对应的典型场景是:"我们用 Mongo 是因为需要能在客户端生成 ID,不用每次都跟服务器往返"。Postgres 生成的 UUIDv7 同样能做到这一点,而且不需要引入另一套数据库。
JSON_TABLE 在 PG17 就出现了,现在 PG18 里已经稳妥到可以上生产了。把 JSON_TABLE 和现有的 JSONB 操作符(@>、?、#>>)以及带 jsonb_path_ops 操作类的 GIN 索引结合起来,你就拥有了一个有索引的路径查询语言,在无 schema 文档场景下跟 MongoDB 有一战之力。
CREATE TABLE user_events (
id uuid PRIMARY KEY DEFAULT uuidv7(),
user_id bigint NOT NULL,
event_type text NOT NULL,
occurred_at timestamptz NOT NULL DEFAULT now(),
props jsonb NOT NULL
);
CREATE INDEX user_events_props_gin ON user_events
USING GIN (props jsonb_path_ops);
查询场景:"过去一天内,购物车总价超过 50 美元且设备是 iOS 的所有 checkout 记录"——
SELECT e.id, e.user_id, e.occurred_at, j.total, j.promo, j.os
FROM user_events e
CROSS JOIN LATERAL JSON_TABLE(
e.props, '$' COLUMNS (
total numeric PATH '$.cart.total',
promo text PATH '$.promo',
os text PATH '$.device.os'
)
) AS j
WHERE e.event_type = 'checkout'
AND e.occurred_at > now() - interval '1 day'
AND e.props @> '{"device": {"os": "ios"}}'
AND j.total > 50;
这个组合直接干掉的场景是:"我们需要 Mongo 是因为要灵活 schema"。JSONB 给过你灵活 schema、读取时类型投影、还有 GIN 索引。
但它干不掉的:文档结构差异极大、任何索引都帮不上忙的那些极端场景。
PG18 修掉了之前让逻辑复制用起来像 beta 功能的那些坑。生成列可以复制了,冲突会报在 pg_stat_subscription_stats 里,并行 apply 默认开启。
对应的典型场景是:"我们用 DynamoDB Streams 是因为 Postgres 的 CDC(Change Data Capture)太痛苦了"。现在逻辑复制是一等的 CDC 数据源,接上 Debezium 或者原生订阅者就能拿到变更流了。
仍然是 NoSQL 领地的情况:跨区域主动-主动写入场景。逻辑复制目前是主从模式,除非你在上面自己构建冲突解决逻辑。
PG18 还有一堆小的改进,方向都一样:
单独拎出来哪个都不够震撼,但每个都去掉一个小理由——让你留在 Postgres 的理由又多了一条。
除了这三处,2026 年还要从 Postgres 搬出去的理由,大多是历史惯性,而不是真正的需求。
回去重读你那份"想迁移到 NoSQL 的清单",逐条问自己一个问题:是跨区域写入吞吐吗?是的话继续规划。如果不是——是要灵活 schema、要客户端 ID、要 CDC 流、要快速时序读取——那就留下来,PG18 已经有你要的功能了。
真正无聊但价值巨大的收益在运维侧:一套数据库、一套备份工具、一套认证模型、一套你的分析师已经熟悉的查询语言。
无聊,但正确。
原文:https://dev.to/gabrielanhaia/postgres-18-just-made-80-of-your-nosql-migration-plan-pointless-g2a