前言
最近在搞 RAG(检索增强生成)项目,技术选型的时候碰到一个问题:向量存哪儿?
搜了一圈,Milvus、Qdrant、Weaviate、Chroma......名字一个比一个酷,文档一个比一个长。然后我看到一个方案说可以直接用 PostgreSQL + pgvector 搞定,心想:这不就是常用的那个关系型数据库吗?
研究了一圈,踩了些坑,把心得分享出来,希望对同样在做选型的同学有帮助。
先说清楚三个东西
在开始之前,先把几个名词捋清楚,不然后面看着容易晕。
PostgreSQL 是什么?
PostgreSQL,圈内人喜欢叫它 PG 或者 Postgres,是一个开源的关系型数据库。
如果你用过 MySQL,那理解起来很简单------PG 跟 MySQL 是同类东西,但年纪更大(1976 年就有了),功能更全,标准更严格,在数据库圈子里属于那种"学霸型"选手。
国内可能用 MySQL 的更多,但在国外,PG 的地位非常高。很多大厂的核心业务都在跑 PG,比如 Instagram、Discord。
PG 最大的特点是能装插件。它有一个扩展机制,允许你给它加各种能力,比如全文检索、地理空间数据处理、甚至是向量搜索。这个特性后面会反复提到,因为它跟 pgvector 有直接关系。
一句话:MySQL 的老大哥,功能更全、更严谨、更工程化。
核心特点:
- ACID 事务:数据一致性有保障
- SQL 标准支持极好:窗口函数、CTE、JSONB、全文检索全都有
- 可扩展性强:支持自定义类型、函数、操作符、扩展插件(这是关键)
- 稳:金融级可靠性,崩溃恢复能力强
- 许可友好:PostgreSQL License(类 BSD),商用无限制
pgvector 是什么?
pgvector 就是 PG 的一个插件,全称可以理解为 "PostgreSQL Vector Extension"(向量扩展)。
它干的事情很简单:让 PG 能够存储向量数据,并且能够做相似度检索。
你可能知道,RAG 的核心流程是这样的:
typescript
用户提问 → 把问题转成向量 → 去向量库里找最相似的内容 → 把找到的内容喂给大模型 → 大模型生成回答
pgvector 就是让 PG 能胜任**"向量库"**这个角色。你往表里存一堆向量,然后给它一个查询向量,它帮你把最相似的几条找出来。
用法也非常直觉,就是普通的 SQL:
sql
-- 建表时加一个 vector 类型的列
CREATE TABLE docs (
id bigserial PRIMARY KEY,
content text,
embedding vector(1536) -- 存 1536 维的向量
);
-- 查询:找跟给定向量最相似的 5 条记录
SELECT content, embedding <=> '[0.1, 0.2, ...]' AS distance
FROM docs
ORDER BY embedding <=> '[0.1, 0.2, ...]'
LIMIT 5;
<=> 这个操作符表示余弦距离,除此之外还支持欧氏距离(<->)和内积(<#>)。
看到这里你可能会想:就这?对,就这。不需要学新的查询语言,不需要装新的服务,写 SQL 就完事了。
一句话:给 PostgreSQL 装上"向量搜索"的翅膀,让它能做语义检索。
核心能力:
- 存储
float4[]/vector类型的向量(支持 1536 维等常见 embedding 尺寸) - 支持精确检索(L2 距离、内积、余弦相似度)
- 支持近似检索(HNSW 索引、IVFFlat 索引)
- 用标准 SQL 就能查询,学习成本极低
RAG 里的向量检索到底在干嘛?
再补一个背景,怕有些同学刚接触 RAG。
大模型(GPT、Claude 等)本身的知识是"冻结"在训练数据里的,它不知道你公司的内部文档、不知道你最新的产品手册。RAG 的思路就是:先检索,再生成。
把你的文档切成一段一段的,每一段都用 embedding 模型转成一个向量(可以理解为一串数字,这串数字编码了这段文本的语义),存到向量库里。用户提问的时候,把问题也转成向量,然后在向量库里找语义最接近的几段文档,把它们拼到 prompt 里喂给大模型。
向量检索的本质就是:在海量高维向量中,快速找到跟查询向量最相似的 K 个 。这跟传统的 SQL WHERE 查询完全不同,它不是精确匹配,而是"找最近的"。
向量数据库都有哪些选择?
| 向量数据库 | 类型 | 优势 | 劣势 | 适用场景 |
|---|---|---|---|---|
| PostgreSQL + pgvector | 关系库扩展 | 一库多用,事务+向量+全文检索,部署维护省事 | 超大规模(亿级)性能不如专业向量库 | 需同时处理关系数据和向量检索的项目,中小规模 |
| Milvus | 专业向量库 | 性能强大,支持亿级向量,分布式架构 | 单独部署维护复杂,学习成本高 | 大规模向量检索场景 |
| Qdrant | 专业向量库 | Rust实现,性能高效,API友好,过滤功能强 | 独立组件,需额外集成 | 中大规模项目,需要高效过滤的场景 |
| Weaviate | 专业向量库 | 内置多种模块,功能丰富,开箱即用 | 部署复杂 | 复杂AI应用,需要丰富功能的项目 |
| Chroma | 轻量向量库 | Python生态完善,简单易用,原型开发快 | Java支持弱,性能一般 | Python项目原型,快速开发 |
| Elasticsearch | 搜索引擎 | 支持全文+向量混合检索,功能全面 | 运维成本高,资源消耗大 | 需要全文和向量混合检索的场景 |
| Redis Stack | 内存库 | 检索速度快,延迟低 | 内存成本高,数据持久化复杂 | 对速度要求极高,数据量不大的实时检索场景 |
| FAISS | 向量索引库 | Meta出品,纯索引,高性能,不带存储管理 | 存储管理需外部处理,功能相对单一 | 已有存储方案,需要高性能索引的场景 |
在做选型之前,先看看市面上有哪些方案。我大致分了三类:
第一类:专业向量数据库
专门为向量检索设计的,从底层存储到索引到查询引擎,全都是为向量优化的。
| 方案 | 语言 | 特点 | 适用场景 |
|---|---|---|---|
| Milvus | Go/C++ | 国产开源,性能强,支持亿级向量,支持分布式 | 大规模向量检索,企业级应用 |
| Qdrant | Rust | 轻量高效,过滤能力很强,API 友好 | 中大规模,注重过滤的场景 |
| Weaviate | Go | 功能丰富,内置多种模型,开箱即用 | 快速搭建,不想折腾嵌入逻辑 |
| Chroma | Python | 主打轻量,API 简洁 | Python项目原型,快速开发、原型验证、轻量级应用 |
第二类:现有数据库加向量扩展
不是专门的向量库,但通过扩展获得了向量检索能力。
| 方案 | 基础 | 特点 | 适用场景 |
|---|---|---|---|
| pgvector | PostgreSQL | SQL 查询,事务一致,混合检索方便 | 已有 PG 基础设施,中小规模 |
| ES dense_vector | Elasticsearch | 全文检索 + 向量检索一体化 | 已有 ES,需要混合搜索 |
| RediSearch | Redis Stack | 内存级速度,延迟极低 | 对延迟要求极高,数据量不大 |
第三类:纯索引库
只做索引和检索,不管存储、不管持久化、不管分布式。适合嵌入到自己的系统里用。
| 方案 | 语言 | 特点 |
|---|---|---|
| FAISS | C++ | Meta 开源,性能极强,纯索引库,需要自己管存储 |
| ScaNN | C++ | Google 开源,擅长各向异性量化 |
选哪一类,取决于你的项目阶段、数据量、团队技术栈和运维能力。下面重点聊 pgvector。
pgvector 的优势
1. 架构简单,不用多部署一个服务
这可能是最实际的优势。
如果你用 Milvus,你的架构大概是这样的:
typescript
传统方案:应用 → PostgreSQL(业务数据)+ Milvus(向量数据)+ 可能还有 ES(全文检索)
↑ 三个数据库,三套运维
pgvector:应用 → PostgreSQL(业务数据 + 向量数据 + 全文检索)
↑ 一个数据库搞定所有事情
三个数据库,三套部署,三套监控,三套备份恢复方案。光运维就够喝一壶的。
用 pgvector,一个数据库搞定所有事情。部署简单了,运维简单了,出问题的概率也小了。
对于中小团队或者早期项目来说,这个优势是非常明显的。你不想在项目还没验证商业模式的时候,就花一个星期去搭 Milvus 集群吧。
2. 业务数据和向量数据在同一个事务里
这个点很多人会忽略,但在实际开发中非常重要。
假设你有一个文档管理系统,用户上传一个文档后,你需要:
- 把文档内容存到数据库
- 调用 embedding API 生成向量
- 把向量也存到数据库
- 更新文档状态为"已索引"
如果用专业向量库,步骤 1 在 PG 里,步骤 3 在 Milvus 里,你没办法保证它们在同一个事务里。万一步骤 3 失败了,步骤 1 已经提交了,你的业务数据和向量数据就不一致了。
用 pgvector,全部在 PG 里,一个事务搞定,要么都成功,要么都回滚:
sql
-- 文档和向量在同一事务里一起写入,要么都成功,要么都回滚
BEGIN;
INSERT INTO docs (content, embedding) VALUES ('文档内容', '[0.1, 0.2, ...]');
UPDATE doc_status SET status = 'indexed' WHERE doc_id = 42;
COMMIT;
这种数据一致性保障,专业向量库很难做到。
3. 混合检索特别方便
RAG 场景下,纯向量检索其实不够用。很多时候你需要"向量相似度 + 关键词匹配 + 元数据过滤"的组合。
举个例子:用户问"2024年发布的关于 PostgreSQL 的技术文章",你需要:
- 用向量检索找语义相关的内容
- 用全文检索确保包含"PostgreSQL"关键词
- 用时间过滤只保留 2024 年的
用 pgvector,一条 SQL 就搞定了:
sql
SELECT content, embedding <=> $1 AS distance
FROM docs
WHERE created_at >= '2024-01-01'
AND content @@ to_tsquery('PostgreSQL') -- 全文过滤
ORDER BY embedding <=> $1 -- 向量排序
LIMIT 10;
这种组合查询在专业向量库里要么不支持,要么写起来很别扭。而在 PG 里,这就是一个普通的带 WHERE 的 SELECT。
4. 运维和生态成熟
PostgreSQL 跑了几十年了,周边工具链非常成熟,你团队里大概率有人会运维 PG,但 Milvus 估计得从头学。
| 运维维度 | PG 方案 | 学习成本 |
|---|---|---|
| 备份恢复 | pg_dump、pg_basebackup、WAL 归档 | 团队大概率已会 |
| 监控告警 | Prometheus + postgres_exporter | 现成方案,开箱即用 |
| 高可用 | Patroni、repmgr、流复制 | 成熟方案多 |
| 托管服务 | AWS RDS、阿里云 RDS 等均支持 pgvector | 一键开通 |
5. 性能够用
pgvector 从 0.5 版本开始支持 HNSW 索引(一种图结构的近似最近邻索引),查询性能有了质的飞跃,在百万级到千万级向量场景下,性能完全可以接受。
实际测试下来,在百万级向量规模下,HNSW 索引的查询延迟在毫秒级,完全够用。千万级也可以,但需要好好调参。
要记住,不是所有 RAG 项目都需要处理亿级向量。你公司有几万篇文档?几十万?这离 pgvector 的天花板远着呢。
6.成本友好
不需要额外服务器,不需要额外内存(Milvus 很吃内存),一个 PG 实例搞定。
pgvector 的劣势
说完优点,也得说说缺点了
1. 规模上限
这是最大的短板。
| 向量规模 | pgvector 表现 | 说明 |
|---|---|---|
| 百万级 | 游刃有余 | HNSW 索引查询毫秒级,无需特别调优 |
| 千万级 | 能用,需要调优 | 调大内存参数,合理设置索引参数 |
| 亿级 | 别想了 | 架构决定了不适合,上 Milvus / Qdrant |
PG 的单机架构决定了它不适合超大规模向量检索。如果你的场景是"全网图片搜索"或者"十亿级商品相似度匹配",请直接上专业向量库。
2. 索引构建慢,占空间
HNSW 索引的构建速度比专业向量库慢,而且索引文件比较大。建索引的时候要注意把 maintenance_work_mem 调大,不然会很慢甚至内存不够。
我之前建一个百万级向量的 HNSW 索引,默认参数下跑了快一个小时,调大内存后缩短到十几分钟。专业向量库通常有更高效的索引构建策略。
3. 算法选择少-查询优化不如专业库
pgvector 目前支持两种近似检索索引:
| 索引类型 | 原理 | 特点 |
|---|---|---|
| HNSW | 分层小世界图 | 查询快,构建慢,内存占用大 |
| IVFFlat | 倒排文件 + 扁平量化 | 构建快,查询精度一般,适合中等规模 |
而专业向量库通常有更多选择:
| 算法 | 说明 | 谁支持 |
|---|---|---|
| PQ(乘积量化) | 压缩向量,节省内存 | Milvus、Qdrant |
| SQ(标量量化) | 降低精度减少存储 | Milvus、Qdrant |
| IVF-SQ | 倒排 + 标量量化组合 | Milvus |
| DiskANN | 磁盘索引,超大规模 | Milvus |
专业向量库在 ANN(近似最近邻)算法上更激进,有更多优化策略(PQ 量化、IVF-SQ 等)。pgvector 目前只有 HNSW 和 IVFFlat 两种。不过对大多数应用来说,HNSW 已经够好了。
4. 高并发写入有瓶颈
大量并发写入向量时,PG 的 MVCC(多版本并发控制)机制加上索引更新,吞吐量会有瓶颈。如果你的场景是每秒写入几万条向量,pgvector 可能扛不住。专业向量库的写入吞吐量通常更高。
不过反过来想,RAG 场景下向量写入通常是批量的、低频的(比如每天定时索引新文档),实时高并发写入的场景不多。
5. 没有分布式原生支持
专业向量库有分片和副本机制,可以水平扩展。PG 要做分布式得靠 Citus 之类的方案,复杂度一下就上去了。
6.内存管理不是为向量设计的
PG 的 shared_buffers 不一定适合向量工作负载。专业向量库可以更精细地控制向量数据的内存映射。
什么时候选 pgvector?什么时候换专业向量库?
根据我的经验,给一个简单的判断标准:
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 向量数量 < 1000万 | ✅ pgvector | 性能够用,运维省心 |
| 已有 PostgreSQL 基础设施 | ✅ pgvector | 零新增服务,直接装插件 |
| 需要事务一致性 | ✅ pgvector | 业务数据和向量同库同事务 |
| 需要复杂混合检索 | ✅ pgvector | SQL 一条搞定向量+关键词+过滤 |
| 项目早期、快速验证 | ✅ pgvector | 最快跑通 RAG 的方式 |
| 团队不想多维护服务 | ✅ pgvector | 一个 PG 实例全搞定 |
| 向量数量达到亿级 | ❌ Milvus / Qdrant | pgvector 架构上限不够 |
| 对查询延迟要求极高(亚毫秒) | ❌ Redis / Qdrant | 内存级方案更快 |
| 写入吞吐量极大 | ❌ Milvus | 专业向量库写入优化更好 |
| 纯向量存储,无关系数据 | 可考虑专业向量库 | 不需要 PG 的关系型能力 |
| 需要水平扩展 | ❌ Milvus / Qdrant | 原生分布式支持 |
我的建议是:先用 pgvector 起步,不够了再迁移。 90% 的 RAG 项目,向量量级根本到不了 pgvector 的瓶颈。等真正撞到墙了再换,到时候你的检索逻辑、排序策略都已经跑通了,迁移的只是底层存储。
pgvector vs 专业向量库:核心能力对比
最后给一张总对比表,方便你快速做决策:
| 对比维度 | pgvector | Milvus | Qdrant | Chroma |
|---|---|---|---|---|
| 向量规模上限 | 千万级 | 亿级+ | 亿级 | 百万级 |
| 查询性能 | 毫秒级(HNSW) | 亚毫秒级 | 亚毫秒级 | 毫秒级 |
| 写入吞吐 | 中等 | 高 | 高 | 中等 |
| 事务支持 | ✅ 完整 ACID | ❌ | ❌ | ❌ |
| 混合检索 | ✅ SQL 天然支持 | ⚠️ 有限支持 | ⚠️ 过滤较强 | ⚠️ 基础过滤 |
| 全文检索 | ✅ 内置 + 扩展 | ❌ | ❌ | ❌ |
| 部署复杂度 | 低(装插件即可) | 高(集群部署) | 中(单机/集群) | 低(开箱即用) |
| 运维成本 | 低 | 高 | 中 | 低 |
| 学习成本 | 低(会 SQL 就行) | 中(需学 SDK) | 中(需学 API) | 低(Python 友好) |
| 分布式 | ❌(需 Citus) | ✅ 原生 | ✅ 原生 | ❌ |
| 托管云服务 | ✅ AWS/阿里云 RDS | ✅ Zilliz Cloud | ✅ Qdrant Cloud | ✅ Chroma Cloud |
| 适合阶段 | 中小规模 / 已有 PG | 大规模 / 企业级 | 中大规模 / 注重过滤 | 原型 / 轻量级 |
顺便聊聊 PostgreSQL 的其他扩展
既然提到了 pgvector,不得不感叹一下 PG 的扩展生态是真的强。pgvector 只是冰山一角,还有几个实用的聊聊。
1.RAG / AI 相关
| 扩展 | 用途 |
|---|---|
| pgvector | 向量存储与检索 |
| pg_embedding | 另一种向量索引(早期竞品,已被 pgvector 主流取代) |
| pg_trgm | 模糊匹配、相似度计算(trigram) |
| pg_bm25 | BM25 全文检索排名(比内置 ts_rank 更准) |
| pgvectorize | 端到端 RAG 框架,自动化 embedding 管道 |
2. 全文检索 / 搜索相关
| 扩展 | 用途 | 一句话点评 |
|---|---|---|
| pg_trgm | 模糊匹配、相似度计算 | 做搜索框联想特别好使,输入"postgrs"能匹配到"postgresql" |
| zhparser | 中文分词 | PG 全文检索默认对中文不友好,装上它就行了 |
| rum | RUM 索引 | 比默认 GIN 索引更快的全文检索,性能要求高时用 |
| unaccent | 去除重音符号 | 多语言场景下有用,café → cafe |
3.性能调优相关
| 扩展 | 用途 | 一句话点评 |
|---|---|---|
| pg_stat_statements | SQL 执行统计 | 几乎必装,找慢查询全靠它 |
| hypopg | 虚拟索引 | 不真正建索引就能看执行计划变化,避免白建索引 |
| auto_explain | 自动记录慢查询计划 | 排查线上问题的时候很方便 |
4. 运维相关
| 扩展 | 用途 | 一句话点评 |
|---|---|---|
| pg_repack | 在线清理表膨胀 | 不锁表就能清理 bloat,生产环境必备 |
| pg_cron | PG 内置定时任务 | 直接在数据库里写 cron 表达式执行定时 SQL |
| pg_partman | 自动分区管理 | 时序数据场景几乎是必需品 |
| pgaudit | 审计日志 | 合规要求场景下用得上 |
5. 数据类型与互操作
| 扩展 | 用途 | 一句话点评 |
|---|---|---|
| hstore | 键值存储 | JSONB 出现前的老方案,某些场景仍有用 |
| uuid-ossp | UUID 生成 | 分布式 ID 生成常用 |
| pgcrypto | 加密函数 | 需要在数据库层做加密时用 |
| citext | 大小写不敏感文本 | 不用每次写 LOWER() 了 |
| fuzzystrmatch | 模糊字符串匹配 | Levenshtein 距离等算法,做数据清洗好用 |
| postgres_fdw | 跨 PG 数据库查询 | 联邦查询利器 |
6. 地理 / 空间数据
| 扩展 | 用途 | 一句话点评 |
|---|---|---|
| PostGIS | 地理信息系统 | GIS 领域的事实标准,功能强到离谱 |
| pgRouting | 路径规划 | 最短路径、导航类需求 |
7. 有趣的扩展
| 扩展 | 用途 | 一句话点评 |
|---|---|---|
| TimescaleDB | 时序数据库 | IoT、监控数据场景很合适 |
| Citus | 分布式 PostgreSQL | 需要水平扩展时考虑 |
| pg_graph | 图查询 | 在 PG 里做图查询,不用再引 Neo4j |
可以看到,PG 的扩展生态覆盖了从全文检索到地理空间到时序数据再到向量检索的方方面面。这也是为什么很多人说 PG 是"最全能的开源数据库"。
最后总结
这篇文章聊了三个事情:
第一,PostgreSQL 是一个功能强大、极其稳定、扩展性极强的开源关系型数据库。pgvector 是它的一个向量检索扩展,让你可以用 SQL 做向量相似度搜索。
第二,在 RAG 向量库选型上,pgvector 的核心优势是架构简单、事务一致、混合检索方便、运维成本低。核心劣势是规模上限和性能天花板。对于绝大多数中小规模 RAG 项目,pgvector 是性价比最高的选择。
第三,PG 的扩展生态非常丰富,除了 pgvector,还有一堆实用扩展可以让 PG 变成一个"全能数据库"。
综合来看,PostgreSQL + pgvector 是 RAG 场景下"性价比最高"的向量存储方案。 它不是最快的、不是最大规模的,但它是最省心、最灵活、最适合中小规模项目的。先用它,等数据量真正撑不住了再迁移到专业向量库------而且到时候你的检索逻辑已经跑通了,迁移的只是存储层。