☰
PostgreSQL AI 生态实战:向量检索、混合检索与数据管道构建指南
2026/10/20 14:41:12 网站建设 项目流程

1. 先回答一个老问题:AI 时代还需要关系型数据库吗

这两年只要一聊到 AI 应用落地,我听到最多的一个论调就是“传统数据库要被向量数据库取代了”。之前做技术选型评审的时候,好几个组都在争论要不要把核心业务数据迁到一个专门的向量库里。我当时的看法是——先别急着推翻重来,把 PostgreSQL 生态里面这几年长出来的 AI 相关能力梳理一遍再做决定。

说实话,我自己早些时候也有过类似的焦虑。大模型应用起来之后,最头疼的就是“记忆”和“知识”怎么存。文本要切块、要向量化、要能做相似度检索,传统 B+ 树索引那一套确实应付不来。但 PostgreSQL 的优势在于它不是一棵被钉死的树,它有非常成熟的扩展机制。你在数据库里"长"出一个向量检索能力,和另起炉灶搭一套新存储,完全是两种成本量级。

DeepSeek 最近帮我把 PostgreSQL 的 AI 生态串了一遍,给我的启发挺大的。它没有停留在“pgvector 可以用来做向量检索”这个表层结论,而是把整个数据链路拆开:从数据进入数据库、预处理、向量化、存储、索引、检索、再到大模型推理时的反馈闭环,每一环 PostgreSQL 都有对应生态组件。我顺着它的思路重新整理了一遍,结合自己实际做过的项目,写一篇尽量完整、又能直接落地的生态总结。

这篇内容适合谁看?主要是两类人:一类是正在做 AI 应用但还没定数据层的技术负责人,想搞清楚 PostgreSQL 这套玩法到底行不行;另一类是已经在用 PostgreSQL,但不知道 AI 相关扩展怎么选、怎么配、会踩什么坑的开发者。

2. pgvector 只是入场券,向量检索方案的完整对比

2.1 为什么 pgvector 能成为事实标准

说到 PostgreSQL 的 AI 生态,绕不开的第一个名字就是 pgvector。它做的事情很简单:在 PostgreSQL 里增加一个向量数据类型,提供相似度查询操作符,并且支持用 GiST 或 HNSW 索引加速检索。但越简单的东西越难做好,pgvector 能成为事实标准,我认为有三个底层原因。

第一,它没有另搞一套存储引擎。向量数据就和普通行数据存在同一个表里,事务、备份、权限体系全都是现成的。这意味着你不用为一个新数据库再学一遍运维,也不需要处理两套数据之间的同步问题。

第二,它的索引实现足够认真。从最初的 IVFFlat(倒排文件 + 扁平量化)到后来引入 HNSW(分层可导航小世界图),pgvector 一直在补齐自己的短板。IVFFlat 适合数据量中等、对精度要求不极端敏感的场景;HNSW 则更适合高并发、低延迟的在线检索。这个演进轨迹和专用向量数据库是同步的。

第三,SQL 生态的杠杆效应。你在 pgvector 里做向量检索,依旧可以用 WHERE 过滤业务字段、用 JOIN 关联其他表、用 ORDER BY 限定排序规则。比如“找出某个用户最近一个月点赞过的文章里,和当前问题语义最相似的前 10 篇”,这种组合过滤条件在专用向量库里写起来相当别扭,但在 PostgreSQL 里就是一个普通的 SQL 查询。

2.2 HNSW 与 IVFFlat 的选型参数与原理拆解

我见过太多人一上来就直接CREATE INDEX ... USING hnsw (embedding vector_cosine_ops)完事,根本不看参数。等线上延迟上来了才开始排查,结果发现是索引参数没调好。

先说 HNSW 的两个核心参数:m和ef_construction。m控制每个节点最多有多少邻居,默认值是 16,但这不是万能值。数据量在百万级以内时,m=32通常能显著提高召回率,代价是构建索引时的内存消耗和构建时间都会上涨。ef_construction控制构建索引时的动态列表大小,默认 64,调大到 128 或 256 会让索引质量更好,但构建时间会成倍增长。

查询时的另一个参数ef_search不在建索引时设置,而是在查询时通过SET hnsw.ef_search = 100或pgvector的hnsw.ef_search参数指定。简单说,ef_search越大,检索时遍历的候选节点越多、召回越高,但延迟也越高。我自己的实践值是:如果单次查询的 p95 延迟预算在 20ms 以内,ef_search设在 80 到 120 之间比较合适;如果能容忍 50ms,那可以放到 200。

IVFFlat 这边,最重要的参数是lists。它表示把向量空间划分成多少个列表,建索引时会先跑一次聚类。lists设置太大,每个列表里的数据太少,检索时为了召回会扫描很多列表,性能反而差;设置太小,每个列表太大,扫描成本高。经验公式是:如果总数据量是 N,那么lists大约取sqrt(N)附近的值。但要注意,IVFFlat 有个固有缺点是召回率受列表数量影响较大,而且如果数据分布不均匀,某些列表极大某些列表极小,检索效果会很飘。所以现在新的项目我基本都是无脑上 HNSW,除非服务器内存特别紧张。

2.3 向量之外:全文检索与稀疏向量的互补

聊完 pgvector 还不够。很多 AI 应用的实际检索场景,只靠纯向量召回是远远不够的。

举一个我实际排查过的例子:某个知识库问答系统,用户问“2025 年 Q3 的营收增长率是多少”,嵌入模型把这句话编码成向量,直接去和文档切片做相似度比较。结果召回的内容是一篇泛泛讲公司战略的文档,而真正包含精确数字的财务报表片段没有被排到前面。原因在于,纯稠密向量对数字、专有名词这类精确匹配的敏感度不够。

解决这个问题,目前比较成熟的思路是混合检索。在 PostgreSQL 里,你可以把多种检索方式的结果用tsvector(全文检索)、向量相似度、甚至 BM25 相关性分数组合起来,最后用一个重排序模型统一打分。PostgreSQL 原生自带全文检索能力,配合中文分词插件或扩展,可以做到对关键词的精确命中。然后在应用层把两路结果按权重融合。

另外还有一个方向是稀疏向量。传统的 BM25 是离散的关键词匹配,而稀疏向量是把文本映射到一个高维稀疏空间,每个维度代表一个 token 或 n-gram 的权重分布。这样做的好处是能兼顾语义和精确匹配。目前已有相关扩展支持稀疏向量类型,不过生态成熟度还比不上 pgvector,我建议先用混合检索把业务跑通,等稀疏向量的工具链更稳定之后再引入。

3. 从"存储"到"计算":PostgreSQL 内部长出的机器学习能力

3.1 为什么要在数据库里直接跑机器学习

把机器学习能力直接塞进数据库,乍一听有点反直觉——训练和推理不是应该在专门的框架里做吗?我之前也这么想。但实际碰到过两个场景之后,我开始理解这个设计的价值。

第一个场景是特征工程。线上推荐系统要实时算用户特征,如果数据都在 OLTP 库里,常规做法是把数据导出来,经过 ETL 进特征平台,再由线上服务去特征平台取数。这个链路一长,实时性就没了。而如果在数据库里直接跑模型推理,特征和模型靠数据表就能关联,事务提交后立刻能拿到结果。

第二个场景是小规模、低延迟的推理任务。比如文本分类、实体抽取这类不算特别复杂的任务,单次推理的模型只有几百 MB,直接用数据库里的机器学习扩展做推理,省掉一个独立推理服务,架构会简单非常多。当然如果你要跑几百亿参数的大模型,那肯定不能指望数据库来做,这种场景还是要走外部的推理服务。

3.2 数据库内机器学习的常见模式与方法

在 PostgreSQL 生态里,数据库内机器学习不是只有一种实现方式。目前主流模式有三种。

第一种是扩展内置算法训练。某些扩展直接把经典机器学习算法实现在 SQL 层内,你可以通过 SQL 语句来训练模型、做预测。这种方式的优点是门槛低,但缺点也很明显:支持的算法有限,主要集中在线性回归、逻辑回归、K-Means 这类传统模型,深度学习基本不支持。

第二种是集成外部框架。比如通过plpython这类过程语言,在 PostgreSQL 函数的内部调用 Python 的机器学习库。这种方式灵活性高,理论上什么模型都能用,但维护成本也高,而且性能上会有函数调用的开销。适合做批量处理,不太适合高并发的在线推理。

第三种是通过推理函数或外部模型推断服务。PostgreSQL 通过扩展能力,把模型注册到数据库内,然后通过 SQL 查询直接调用外部大模型或模型部署的接口。这种方案的优点在于:模型本身在外部,数据库只负责传入参数、接收结果,可以是推理请求的“路由层”。这种方式是现在 AI 应用里比较常用的,数据不需要导出,业务逻辑全部走 SQL,由数据库充当了一个模型编排的网关角色。

我个人的判断是,数据库内跑机器学习最合适的场景是:模型不太大、推理频率中等、对端到端延迟有一定要求但又不至于到微秒级。如果模型逻辑复杂、需要 GPU 集群、训练频繁迭代,那还是别硬塞到数据库里。数据库的强项是数据管理和事务,不是大规模算力调度。

4. 数据管道与实时化:让 AI 应用的数据"活"起来

4.1 逻辑复制与实时数据管道

AI 应用里最容易被低估的一块,是数据管道。模型效果好不好,七成取决于喂进去的数据对不对、够不够准、够不够快。PostgreSQL 在这方面的生态比很多人想象中成熟。

逻辑复制(Logical Replication)是 PostgreSQL 原本就有的功能,走的是发布/订阅模型。你可以把一张表或者一个数据库的变更事件实时推送给消费者。这个能力在 AI 场景里非常重要——比如用户对话记录、行为日志都实时写进 PostgreSQL,下游有一个向量化服务订阅这些变更,把新写入的文本切块、向量化、写入向量表。整个过程是异步的,但通过逻辑复制可以做到秒级甚至毫秒级延迟。

相比基于触发器的方案,逻辑复制的优势在于它不产生额外的业务写入开销,而且复制位点可管理、可回溯。触发器方案在写入量一大就会出现性能急剧下降,而且如果触发器逻辑出错,排查起来非常痛苦。所以我现在做 AI 数据管道,第一优先就是看能不能用逻辑复制。

4.2 向量化的时机选择:同步还是异步

向量化是 AI 数据管道里的核心步骤。是把文本切成块、用嵌入模型生成向量、再写回数据库。这里有一个常见问题:到底是在写入时同步完成向量化,还是通过异步任务去处理?

同步方案是业务写入的时候,数据库通过触发器或应用代码直接调用嵌入模型,拿到向量一起落库。优点是数据一写入就能立刻被检索到,一致性很好。缺点是嵌入模型调用是网络 IO,会拖慢写入延迟,而且如果模型服务不稳定,写入就会直接失败。

异步方案是用逻辑复制捕获变更,在数据库外面跑一个消费者程序,做切块、向量化、回写。优点是写入链路稳定,向量化失败可以重试,不会影响业务。缺点是数据会有一个短暂的“不可检索窗口期”。

我目前的做法是:对写入量小、且对一致性要求高的场景用同步;对写入量大、允许秒级延迟的场景用异步。多数 AI 应用实际上都能容忍秒级延迟,所以异步更常见。

4.3 批处理与实时计算的边界

除了实时管道,批处理场景也不能忽略。很多 AI 应用需要定期对全量数据重新向量化,比如你换了一个效果更好的嵌入模型,或者调整了文本切块策略,那么历史数据的向量就得全部重新生成。这种任务用逻辑复制的实时管道是干不了的,因为它是全量重放。

这种全量重算的场景,一般会在 PostgreSQL 外面起一个定时任务,比如用 cron 或者类似分布式任务调度的方案,扫描一批 ID,逐个取文本、调用模型、写回新的向量字段。在处理过程中有个关键注意点:重新索引时,HNSW 索引会占用额外内存,如果表很大,建议先删掉旧索引,等数据更新完再重新建索引,可以节省不少资源。

实时和批处理之间还有一个中间态:微批。比如每 5 分钟批量处理一次增量数据。微批的优点是可以在业务低峰期集中调用嵌入模型,节省 API 费用,也方便做失败重试。如果你的场景对实时性要求不是特别高,我建议直接用微批,比逐条实时调用更省钱、更稳定。

5. 实操层面的硬核细节:我从真实项目中踩过的坑

5.1 维度、距离函数与归一化的选择

向量检索的第一大坑是“不知道自己该用多少维”。维度过低语义表达能力不够,维度过高索引体积和查询延迟都上去了。我做过一次对比实验:同样 100 万条数据,用 768 维向量的 HNSW 索引体积比 384 维大将近一倍,查询延迟大概增加 40%,但召回率只提升了不到 2%。所以我现在的原则是:先问嵌入模型能不能降维输出,能用低维就用低维,不要盲目追高维。

距离函数的选择也是一个容易被忽视的细节。pgvector 支持三种:L2 距离、内积、余弦距离。很多人直接用余弦距离,觉得语义相似度就应该是余弦。但要注意,余弦距离对向量模长不敏感,如果你的嵌入模型生成的向量本身带有“置信度”信息,比如模长表示确定程度,那么余弦距离会丢掉这层信息。这种场景可能更适合用内积。

另外就是归一化。如果在插入之前统一对向量做 L2 归一化,那么内积和余弦距离是等价的。归一化的好处是能缩小向量值域,某种程度上让索引划分更均匀。我个人的习惯是:统一在写入前做归一化,然后在查询时用余弦或内积,尽量减少后续排查时的变量。

5.2 数据写入与索引维护的时序问题

另一个我踩过的大坑是索引维护的时机。有一次我在一张已经有两亿多行的表上,直接执行了创建 HNSW 索引的语句,结果数据库内存瞬间飙高,直接导致同一实例上的业务查询变慢。后来查了文档和社区讨论才发现,HNSW 索引构建需要在内存中构建图结构,对内存的需求和m参数及数据量强相关。后来我的做法是先备份、把目标表单独放到一个连接里、临时调大maintenance_work_mem,并且选在业务低峰期执行建索引操作。

写入和索引的相互作用也需要小心。HNSW 索引本身是增量可更新的,但随着不断插入新向量,图结构可能会渐进地变得不那么最优。有些团队的做法是定期对全表做一次REINDEX,把索引质量恢复到刚构建时的水平。我实测下来,如果每天新增数据量超过总量的 5%,每周一次 REINDEX 会比较合理;如果新增量很小,一个月一次就够了。

还有一个小细节是更新向量时不要直接 UPDATE。我见过有同学在向量表上做频繁的 UPDATE,导致表的膨胀率暴涨,索引性能也跟着恶化。正确的做法是:把向量表设计成可追加的,每条记录都带版本号或创建时间,查询时按“最新版本”过滤。这不仅能避免膨胀,还能保留历史数据用于效果对比分析。

5.3 与外部嵌入模型协作时的连接与超时控制

PostgreSQL 里的 AI 应用免不了要调外部嵌入模型。调模型就得发 HTTP 请求,这一块的稳定性直接决定了整个管道的可靠性。

在数据库写进外部请求时,有几个关键参数必须设对:连接超时、读取超时、重试次数和重试退避策略。连接超时我一般设 5 秒,读取超时 30 秒。为什么读取超时要比连接超时长那么多?因为嵌入模型的推理时间往往和输入文本长度强相关,长文本可能要十几秒。如果读取超时设太短,经常会出现明明模型还在算、但数据库这边已经报错的情况。

重试策略也不能大意。我之前做异步消费者的时候,遇到模型服务偶发 5xx 错误,一开始用固定间隔重试,结果在服务恢复的瞬间,大量积压的重试请求一起打过去,把服务又打挂了。后来改成指数退避加抖动,第一次重试等 1 秒、第二次 2 秒、第三次 4 秒,最大到 30 秒,并且每次加一个随机 0 到 500 毫秒的偏移,这个问题就基本消失了。

5.4 备份恢复与向量索引的兼容性

向量数据的备份恢复,也有一个很多人不知道的坑。普通的全量备份 + WAL 归档方案对向量表是有效的,但如果只用pg_dump导出、再pg_restore导入,HNSW 索引会因为缺少原始构建参数而在重建时使用默认值,导致索引质量和原来不一样。我遇到过导完数据之后查询变慢的情况,排查到最后才发现是索引重建参数没有带过去。

解决方案有两种。一种是恢复后用脚本重新执行原生索引构建语句,把m和ef_construction显式指定。第二种是直接复制数据目录做物理备份,物理备份会把索引原样保留,但前提是上下游的 PostgreSQL 主版本要一致,扩展版本也要一致。

向量数据的备份频率也需要单独考虑。普通业务数据可能一天备份一次就够了,但向量表如果有高频写入,增量备份的粒度要细化。我建议把向量表的 WAL 归档独立设置,不要和业务表混在一起,这样在做时间点恢复时可以避免把大量向量写入的 WAL 也一起重放,节省恢复时间。

6. 生态标准化的方向:AI 能力正在成为数据库的"新默认值"

6.1 SQL 层面的向量规范

观察 PostgreSQL 的 AI 生态,有一个趋势值得关注:AI 相关的功能正在从“外部插件”变为“核心能力”,而且社区正在推动 SQL 规范层面的标准化。向量类型、向量索引、向量运算这些以前只有专用数据库才有的能力,正在成为 PostgreSQL 内置的“新默认值”。

这种标准化的直接好处是降低了迁移成本。以前从 PostgreSQL 迁到专用向量库,要把数据导出、转换、再导入,业务代码也要从 SQL 改成向量库的 SDK。如果 PostgreSQL 生态内部统一了向量操作的 SQL 语法,那么你只需要改连接串,业务代码几乎不用动。这一点对已经在 PostgreSQL 上积累了大量业务逻辑的团队来说,价值是巨大的。

6.2 扩展仓库与服务组件的生态接力

PostgreSQL 还拥有一个覆盖了大量扩展的生态仓库。这个生态让用户不需要从头造轮子。以前想在 PostgreSQL 里做某种新能力,常常要自己写 C 扩展,成本很高。现在你可以在扩展仓库里寻找到成熟方案,直接安装启用,生产可用性比自研高一个量级。同时,服务组件的生态接力也在加速:数据分析工具、BI 平台、甚至模型训练框架都开始原生支持 PostgreSQL 作为数据源。

这种“核心数据库 + 丰富扩展”的模式,是我比较看好的一种 AI 数据基础设施形态。它既保持了数据库内核的稳定和事务能力,又能通过扩展快速吸收 AI 领域的新需求。AI 技术迭代太快,如果每一次新需求都要改写数据库内核,那根本跟不上节奏。扩展机制的价值就在于把“稳定”和“快速变化”这两件事解耦。

6.3 社区动向:从“能用”到“好用”的关键一步

开源社区的活跃度是生态成熟度的重要信号。我观察 PostgreSQL 的 AI 相关扩展,最近的变化是:文档越来越详实、示例越来越多、GitHub 上的 issue 响应速度明显加快。这说明新的能力正在被更多团队在真实场景中打磨,而“被大量生产环境验证过”恰恰是技术选型时最看重的一点。

我也注意到,很多 AI 相关的扩展开始重视观测性。比如,向量检索的耗时、召回数量、索引构建进度这些指标,正在逐步整合到 PostgreSQL 的监控体系里。这一步的意义很大——以前你在生产环境用向量检索,基本是黑盒,出了问题只能靠猜。现在至少能拿到一些明确的监控数据来做排查和优化。

7. 我的最终结论与给同行的建议

整理完整个生态之后,我的判断其实已经比较坚定了:PostgreSQL 在 AI 时代不会边缘化,相反它会成为很多 AI 应用的数据底座。它的定位不是去替代专门的向量数据库或推理服务,而是把这些能力“吸收”进来,让数据层和应用层之间的鸿沟变得更窄。

如果你正在做技术选型,我的建议是先别急着搭一套复杂的 AI 数据架构。把 PostgreSQL 先跑起来,装好扩展,用混合检索解决一个核心痛点,比如“让知识库问答的召回率提上去”。等这个闭环跑通了,再逐步演进:加异步管道、加数据库内推理、加微批策略。大多数团队其实不需要一开始就上分布式向量库那种重型方案。

最后分享一个我个人的使用技巧:在配置索引参数时,不要直接照搬默认值,也不要去网上抄所谓的最佳实践。每个人的数据分布、查询模式、并发量都不一样。比较靠谱的做法是自己写一个小的压测脚本,用真实数据在你的 PostgreSQL 实例上跑一轮,分别测默认参数和调整后的参数,对比召回率和延迟,用数据去决定。这样折腾半天之后得出的参数,往往比任何网上教程都可靠。

我踩过的最深的一个坑就是太相信默认配置。默认配置是给“各种场景都差不多能用”准备的,但你的场景如果恰好特殊,默认值就会让你在最意想不到的时候出问题。把索引参数调好、把写入模式设计对、把超时和重试策略设好,这三件事做好了,PostgreSQL + AI 这套组合能给你的稳定性,超出你的预期。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询