PostgreSQL 扩展生态:不止是数据库
PG 的杀手锏不只是 SQL,是扩展——pgvector 做向量检索、PostGIS 做地理、TimescaleDB 做时序、zhparser 中文分词。本文讲清 PG 扩展的价值、10 个最常用扩展各自解决什么、怎么安装管理,以及"一个 PG 替代多个组件"的架构思维。
本文要点
- 主题聚焦:DevOps
- 适合人群:独立开发者、全栈工程师、AI 应用开发者
- 核心价值:快速理解背景、实践路径、常见误区和工程建议
PostgreSQL 扩展生态:不止是数据库
很多人对 PostgreSQL 的印象停留在"一个开源关系型数据库,比 MySQL 多几种数据类型"。这个判断在 2015 年可能成立,今天已经严重过时。
PG 真正的杀手锏不是 SQL 引擎本身,而是它背后庞大的扩展生态。通过 CREATE EXTENSION,你可以在不换数据库、不动连接串、不引入新组件的前提下,让 PG 突然学会向量检索、地理空间计算、时序聚合、中文分词、UUID 生成、自动分区。别的数据库是"一个数据库",PG 是"一个数据库 + 一个生态市场"。
这篇文章讲清三件事:PG 扩展到底解决什么、TOP 10 常用扩展怎么选、"一个 PG 替代多组件"这种架构在小团队里到底省不省心。
一、PostgreSQL = 数据库 + 扩展生态
先纠正一个误区:PG 的扩展不是"插件"那种可有可无的小工具,而是深入到 SQL 引擎层的核心机制。一个扩展可以注册新的数据类型、新的操作符、新的索引方法(AM)、新的函数、甚至新的规划器行为。
这意味着:
pgvector注册了vector类型和<->操作符,于是你可以ORDER BY embedding <-> $1 LIMIT 10,优化器会自动用上 HNSW 索引。PostGIS注册了geometry类型和一大堆空间函数,于是你可以ST_DWithin(geom, point, 1000)查"一公里内的点"。zhparser注册了一个分词器,于是to_tsvector('chinese', '机器学习入门')能正确切词。
这种机制的好处是:扩展和原生功能享受同等地位。你的 ORM、连接池、迁移工具、备份脚本、监控面板,通通不需要改。对比一下:要在 MySQL 上做向量检索,你得引入一个独立的 Milvus;在 MongoDB 上做地理,你得装 Atlas Search。PG 把这些都吸收进了 SQL 的世界观里。
这就是 PG 在过去几年重新成为"开发者最喜爱数据库"的根本原因——它不是赢在 SQL,是赢在扩展。
二、常用扩展 TOP 10
下面这 10 个是我经手过几十个项目后,真正会在生产里反复装的。每个都附一句话定位和最小示例。
1. pgvector — 向量检索 / RAG 的标配
AI 应用爆火之后,pgvector 几乎成了新的"必装扩展"。它让 PG 直接当向量数据库用,支持 ivfflat 和 hnsw 两种近似最近邻索引。
CREATE EXTENSION vector;
CREATE TABLE docs (
id bigserial PRIMARY KEY,
content text,
embedding vector(1536)
);
CREATE INDEX ON docs USING hnsw (embedding vector_cosine_ops);
-- 找最相似的 10 条
SELECT id, content
FROM docs
ORDER BY embedding <=> $1
LIMIT 10;
一个 1536 维的小型知识库(几十万条),pgvector + HNSW 完全够用,不用上 Milvus / Pinecone。
2. PostGIS — 地理空间 / GIS 的事实标准
PostGIS 是 PG 生态里最老牌、最成熟的重量级扩展。外卖配送、网约车、LBS、地图可视化,凡是涉及"经纬度 / 形状 / 距离 / 区域"的,基本绕不开它。
CREATE EXTENSION postgis;
CREATE TABLE stores (
id bigserial PRIMARY KEY,
name text,
geom geometry(Point, 4326)
);
CREATE INDEX ON stores USING gist(geom);
-- 5 公里内的店,且按距离排序
SELECT name,
ST_Distance(geom::geography,
ST_MakePoint(116.4, 39.9)::geography) AS dist
FROM stores
WHERE ST_DWithin(geom::geography,
ST_MakePoint(116.4, 39.9)::geography, 5000)
ORDER BY dist;
ES 也能做地理,但复杂度和精度跟 PostGIS 不在一个量级。
3. TimescaleDB — 时序数据 / IoT / 监控
监控指标、传感器数据、股票行情这类"写多读少、按时间聚合"的场景,TimescaleDB 的 hypertable 自动按时间分区,带连续聚合和压缩。
CREATE EXTENSION timescaledb;
CREATE TABLE metrics (
ts timestamptz NOT NULL,
host text,
cpu double precision
);
SELECT create_hypertable('metrics', 'ts');
-- 自动每小时聚合,查询秒级返回
CREATE MATERIALIZED VIEW metrics_hourly
WITH (timescaledb.continuous) AS
SELECT host,
time_bucket('1 hour', ts) AS bucket,
avg(cpu)
FROM metrics
GROUP BY host, bucket;
中小团队用它替代 InfluxDB / Prometheus 长期存储,运维心智成本省一大截。
4. pg_trgm — 模糊匹配 / 相似度搜索
LIKE '%keyword%' 用不上索引,是 PG 里经典的慢查询来源。pg_trgm 提供三元组相似度和 GIN 索引,做"模糊搜索框 / 拼写纠错"非常顺手。
CREATE EXTENSION pg_trgm;
CREATE INDEX ON products USING gin(name gin_trgm_ops);
SELECT name, similarity(name, 'iphne') AS sim
FROM products
WHERE name % 'iphne'
ORDER BY sim DESC
LIMIT 10;
没上 ES 之前,pg_trgm 就是你的全文搜索引擎。
5. unaccent — 无重音搜索
做国际化业务必备。让 café 和 cafe、Müller 和 Muller 等价匹配。
CREATE EXTENSION unaccent;
SELECT * FROM users
WHERE unaccent(name) ILIKE unaccent('%cafe%');
6. zhparser / pg_jieba — 中文全文分词
PG 内置全文检索对中文不友好,因为默认分词器按空白切词。zhparser(基于 SCWS)和 pg_jieba(基于 jieba)补上这一刀。
CREATE EXTENSION zhparser;
CREATE TEXT SEARCH CONFIGURATION chinese (PARSER = zhparser);
ALTER TEXT SEARCH CONFIGURATION chinese
ADD MAPPING FOR n,v,a,i,j,l WITH simple;
-- 建索引
CREATE INDEX ON articles USING gin(
to_tsvector('chinese', content)
);
SELECT * FROM articles
WHERE to_tsvector('chinese', content) @@ to_tsquery('机器 & 学习');
中小内容站、文档搜索,直接用 PG 内置 FTS + zhparser,不必引入 ES。
7. pg_stat_statements — 慢查询统计
这个不是"业务功能",而是"运维必备"。它记录每条 SQL 的执行次数、总耗时、IO、行数,定位慢查询全靠它。
-- 需要先在 shared_preload_libraries 里加载
-- shared_preload_libraries = 'pg_stat_statements'
CREATE EXTENSION pg_stat_statements;
SELECT query, calls, mean_exec_time, total_exec_time
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 20;
不开这个扩展去调优 PG,等于盲开。
8. uuid-ossp / pgcrypto — UUID 与加密
分布式系统主键、API token 生成、密码哈希,这两个扩展覆盖大半场景。
CREATE EXTENSION "uuid-ossp";
CREATE EXTENSION pgcrypto;
SELECT uuid_generate_v4();
SELECT crypt('password123', gen_salt('bf', 10));
注意 uuid-ossp 名字要带引号,新手第一次都会踩。
9. pg_partman — 分区自动管理
PG 原生声明式分区是手动建分区。pg_partman 自动按时间 / ID 滚动创建新分区、归档老分区,配合 TimescaleDB 之外的分区表用。
CREATE EXTENSION pg_partman;
SELECT partman.create_parent(
'public.events', 'created_at', 'native', 'weekly'
);
日志表、事件表、审计表用得最多。
10. Citus — 分布式 PostgreSQL
当单机 PG 扛不住写入或存储量时,Citus 把多台 PG 拼成一个分布式数据库,自动分片 + 分布式查询。微软收购后已经成为 Azure 上的托管服务。
CREATE EXTENSION citus;
SELECT create_distributed_table('events', 'user_id');
Citus 的边界很清晰:如果到不了"几十 TB / 千万 QPS"这个量级,不要上,单机 PG + 读写分离就够。
三、安装与管理
PG 扩展的安装,本质上是两步:把扩展的二进制放进 PG 的 libdir,把控制文件 + SQL 脚本放进 extensiondir。然后你才能在数据库里 CREATE EXTENSION。
-- 看有哪些扩展可装
SELECT * FROM pg_available_extensions;
-- 看 PG 内置扩展目录
SELECT name, default_version, installed_version
FROM pg_available_extensions
WHERE installed_version IS NOT NULL;
-- 装扩展(大部分扩展需要 superuser 或 trusted 权限)
CREATE EXTENSION IF NOT EXISTS pgvector;
-- 指定版本(扩展版本和 PG 版本必须匹配)
CREATE EXTENSION pgvector WITH VERSION '0.7.0';
-- 升级
ALTER EXTENSION pgvector UPDATE TO '0.7.0';
-- 看当前库装了哪些
\dx
几个容易踩的坑:
- shared_preload_libraries:
pg_stat_statements、auto_explain、pg_cron这类需要在postgresql.conf里shared_preload_libraries = '...'预加载,然后重启 PG 才生效。CREATE EXTENSION单独做没用。 - 版本对齐:扩展是针对特定 PG 大版本编译的,PG 14 的
pgvector.so不能直接用到 PG 16。升级 PG 大版本时,所有扩展都要重装。 - trusted 扩展:PG 13+ 引入了
trusted标记,允许普通用户安装特定扩展(比如pg_trgm、unaccent、pgcrypto),不需要 superuser。云数据库常常只放开 trusted 这一小撮。 - 依赖冲突:有些扩展依赖特定的共享库(libicu、libprotobuf、proj4 for PostGIS),少装一个系统包就启动失败。
四、"一个 PG 替代多组件"的架构思维
这是我推荐小团队认真考虑的一种思路:与其维护 PG + Redis + ES + InfluxDB + Milvus 五个组件,不如先看 PG 扩展能覆盖多少。
具体替换关系:
- 全文搜索 → PG 内置 FTS + zhparser + pg_trgm,替代 ES(注意:复杂聚合、相关性调优上 ES 仍占优)
- 时序数据 → TimescaleDB,替代 InfluxDB / Prometheus 长期存储
- 向量检索 → pgvector,替代 Milvus / Pinecone(千万级以下向量)
- 地理空间 → PostGIS,替代专门的 GIS 服务
- 缓存 → PG 的
UNLOGGED表 + 合理索引,在 QPS 不极端的场景下能扛住
这样做的收益是实打实的:
- 运维复杂度断崖式下降:一套备份、一套监控、一套权限模型、一套连接池配置。
- 数据一致性天然保证:全文检索和数据表在同一个事务里,不存在 ES 和 DB 对不上的经典难题。
- 迁移成本接近零:加一个
CREATE EXTENSION就开新能力,不需要评估新中间件、改部署架构、培训团队。 - 机器成本下降:少跑三五个独立服务,内存和 CPU 省下来给真正需要的组件。
当然前提是:你的数据量、QPS、查询复杂度还在 PG 能舒服扛住的范围内。一旦超出——比如向量到亿级、时序到 TB/天、ES 需要复杂聚合和打分——该上专门组件就上,不要硬撑。
五、不是无脑装:扩展的代价
说了这么多好处,也要泼盆冷水。扩展不是装得越多越好,它带来的代价是真实的:
第一,版本兼容性是个长期负担。 每升一次 PG 大版本,所有扩展都要同步升级验证。PostGIS 这种"巨石扩展"尤其麻烦,跟 GDAL、GEOS、PROJ、Protobuf 等一票 C 库耦合,编译失败是家常便饭。CI 里一定要跑扩展回归。
第二,性能影响不一定可控。 部分 DDL 操作会拿全表锁:
CREATE INDEX CONCURRENTLY大多数扩展支持,但ALTER TYPE ADD VALUE、某些扩展的CREATE EXTENSION会锁表。- pg_repack、pg_squeeze 这类"在线重建表"的扩展,运行期间会显著增加 IO 和 WAL。
- pg_stat_statements 本身吃 shared memory,默认 5000 条记录在高 QPS 系统上会被刷掉,需要调大。
第三,扩展引入的安全面要审视。 plpython3u、plperlu 这类 untrusted 语言扩展允许任意系统调用,在多租户 / 用户可建扩展的场景下是高危项。生产库里原则上是:不用的扩展一律 DROP EXTENSION。
第四,迁移到云时的隐性成本。 这就引出下一节。
六、云 vs 自托管:扩展支持差异
这是选型时最容易忽略的一环。云数据库对扩展的支持是受限且各家不同的。
- AWS RDS / Aurora PG:维护了一份白名单,大概支持 100+ 扩展,包括 pgvector、PostGIS、TimescaleDB(早期版本)。但
plpython3u、pg_cron在不同版本支持程度不一样,自定义扩展完全不允许。 - 阿里云 RDS PG / 腾讯云 TDSQL-C PG:有自己的白名单,中文场景的 zhparser / pg_jieba 通常支持得比 AWS 好,但新出的扩展上线慢半拍。
- GCP Cloud SQL for PG / AlloyDB:AlloyDB 对分析型扩展支持更激进,有列存引擎。
- Supabase / Neon / Crunchy Bridge 这种"开发者友好型"云 PG:扩展支持列表一般更宽,Supabase 把 pgvector、PostGIS、pg_cron 都做了进去。
- 自托管:全可控,你能装任何社区扩展,甚至自己写。代价是运维、备份、监控、HA、升级全部自己扛。
实战建议:
- 项目初期就锁定云厂商,把"目标云支持哪些扩展"写进架构评审,别等到上线才发现要用 PostGIS 而云不支持。
- 如果扩展需求超出云的限制(比如要
pg_cron跑定时 SQL、要自定义 C 扩展),考虑自托管或换云。 - 把"使用了哪些扩展"在文档里登记清楚,这是未来迁移云时的关键评估输入。
小结
- PG 的真正护城河是扩展生态,不是 SQL。 同样的连接串、同样的 ORM,加个
CREATE EXTENSION就多一种能力,这是别家数据库给不了的体验。 - TOP 10 实战清单:pgvector、PostGIS、TimescaleDB、pg_trgm、unaccent、zhparser/pg_jieba、pg_stat_statements、uuid-ossp/pgcrypto、pg_partman、Citus——业务问题先在这个列表里找答案,大概率有现成的。
- 小团队优先考虑"一个 PG 替代多组件":运维成本断崖下降,数据一致性天然保证,前提是没撞到 PG 的容量 / QPS 天花板。
- 扩展不是免费午餐:版本兼容、锁表风险、安全面、云限制都要纳入考量,装之前想清楚,不用就 DROP 掉。
- 云 PG 的扩展白名单是选型硬约束:架构评审阶段就要对齐,别让扩展需求成为上线前最后一公里的拦路虎。
一句话总结:PostgreSQL 不是"一个数据库",而是一整套"用 SQL 串起来的数据基础设施"。把扩展用熟,PG 能替你省掉半打独立组件——前提是你知道每个扩展的边界在哪。
Related
相关推荐
文章
Docker 部署 Next.js 社区项目的注意事项
围绕 DevOps、Next.js 的技术趋势、工程实践和独立开发视角。
文章
OpenTelemetry 如何帮助你观察 AI 应用?
围绕 DevOps、AI 的技术趋势、工程实践和独立开发视角。
文章
长运行工具调用:Operation、Poll 与 Cancel 的终态协议
初始请求超时后,工具可能仍在服务端运行;发出取消也不等于副作用已停止。本文为单次长运行工具调用建立 operation 身份、轮询水位、取消竞态和唯一终态接受点。
文章
Agent 记忆删除传播:从用户遗忘请求到可验证清除
删除主表一行不会清掉向量、摘要、缓存和恢复后的备份。本文用删除状态机、代际墓碑、派生血缘与端到端 canary 验证真正遗忘。