#DevOps

PostgreSQL 扩展生态:不止是数据库

PG 的杀手锏不只是 SQL,是扩展——pgvector 做向量检索、PostGIS 做地理、TimescaleDB 做时序、zhparser 中文分词。本文讲清 PG 扩展的价值、10 个最常用扩展各自解决什么、怎么安装管理,以及"一个 PG 替代多个组件"的架构思维。

本文要点

  • 主题聚焦:DevOps
  • 适合人群:独立开发者、全栈工程师、AI 应用开发者
  • 核心价值:快速理解背景、实践路径、常见误区和工程建议
作者 @admin·发布于 2026年3月28日·更新于 2026年7月23日

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 两种近似最近邻索引。

sql
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、地图可视化,凡是涉及"经纬度 / 形状 / 距离 / 区域"的,基本绕不开它。

sql
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 自动按时间分区,带连续聚合和压缩。

sql
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 索引,做"模糊搜索框 / 拼写纠错"非常顺手。

sql
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 等价匹配。

sql
CREATE EXTENSION unaccent;

SELECT * FROM users
WHERE unaccent(name) ILIKE unaccent('%cafe%');

6. zhparser / pg_jieba — 中文全文分词

PG 内置全文检索对中文不友好,因为默认分词器按空白切词。zhparser(基于 SCWS)和 pg_jieba(基于 jieba)补上这一刀。

sql
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、行数,定位慢查询全靠它。

sql
-- 需要先在 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 生成、密码哈希,这两个扩展覆盖大半场景。

sql
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 之外的分区表用。

sql
CREATE EXTENSION pg_partman;

SELECT partman.create_parent(
  'public.events', 'created_at', 'native', 'weekly'
);

日志表、事件表、审计表用得最多。

10. Citus — 分布式 PostgreSQL

当单机 PG 扛不住写入或存储量时,Citus 把多台 PG 拼成一个分布式数据库,自动分片 + 分布式查询。微软收购后已经成为 Azure 上的托管服务。

sql
CREATE EXTENSION citus;
SELECT create_distributed_table('events', 'user_id');

Citus 的边界很清晰:如果到不了"几十 TB / 千万 QPS"这个量级,不要上,单机 PG + 读写分离就够。

三、安装与管理

PG 扩展的安装,本质上是两步:把扩展的二进制放进 PG 的 libdir,把控制文件 + SQL 脚本放进 extensiondir。然后你才能在数据库里 CREATE EXTENSION。

sql
-- 看有哪些扩展可装
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 扩展),考虑自托管或换云。
  • 把"使用了哪些扩展"在文档里登记清楚,这是未来迁移云时的关键评估输入。

小结

  1. PG 的真正护城河是扩展生态,不是 SQL。 同样的连接串、同样的 ORM,加个 CREATE EXTENSION 就多一种能力,这是别家数据库给不了的体验。
  2. TOP 10 实战清单:pgvector、PostGIS、TimescaleDB、pg_trgm、unaccent、zhparser/pg_jieba、pg_stat_statements、uuid-ossp/pgcrypto、pg_partman、Citus——业务问题先在这个列表里找答案,大概率有现成的。
  3. 小团队优先考虑"一个 PG 替代多组件":运维成本断崖下降,数据一致性天然保证,前提是没撞到 PG 的容量 / QPS 天花板。
  4. 扩展不是免费午餐:版本兼容、锁表风险、安全面、云限制都要纳入考量,装之前想清楚,不用就 DROP 掉。
  5. 云 PG 的扩展白名单是选型硬约束:架构评审阶段就要对齐,别让扩展需求成为上线前最后一公里的拦路虎。

一句话总结:PostgreSQL 不是"一个数据库",而是一整套"用 SQL 串起来的数据基础设施"。把扩展用熟,PG 能替你省掉半打独立组件——前提是你知道每个扩展的边界在哪。

Related

相关推荐