什么是向量数据库?从原理、选型到 RAG 实战
如果你接触过 RAG(检索增强生成),一定见过这样一条流程:
文档切块 → 生成向量 → 写入向量数据库 → 根据问题检索相关内容 → 交给大模型回答。
问题是:为什么要专门使用向量数据库?MySQL、PostgreSQL 不能存吗?它和普通数据库到底有什么区别?
这篇文章不仅解释向量数据库的原理,还会提供一个可以运行的中文语义检索示例。读完后,你应该能够判断自己的项目是否需要向量数据库,以及该如何选型。
先说结论:向量数据库解决什么问题?
向量数据库是一类针对高维向量存储、相似度检索和元数据过滤进行优化的数据系统。
它最擅长的不是查询“编号等于 5 的记录”,而是回答:
在几百万段文本、图片或音频中,哪些内容与当前问题最相似?
这正是语义搜索、RAG、推荐系统、以图搜图和内容去重等 AI 应用的基础能力。
需要先澄清一点:
普通数据库并非不能存、不能查向量。
向量本质上是一组浮点数,可以存进数组、JSON、BLOB 或专用向量字段。PostgreSQL 配合 pgvector、部分 MySQL 产品或版本,以及 Elasticsearch、OpenSearch 等系统,也可以提供向量索引和近邻检索能力。
真正的区别在于:
你的数据系统是否具备成熟的向量索引、元数据过滤、扩缩容、持久化和运维能力,能否在目标数据量与并发下满足延迟和召回率要求。
目录
先说结论:向量数据库解决什么问题?
一、为什么传统索引不擅长语义检索?
二、向量数据库里存的是什么?
三、“相似”究竟是怎么算出来的?
四、向量数据库为什么能更快?
HNSW:从高速公路逐级驶入目标街区
五、向量数据库在 RAG 中怎么工作?
离线建库
在线问答
六、哪些场景需要向量数据库?
七、主流向量数据库怎么选?
更实用的选择顺序
1. 先看现有技术栈
2. 再看部署要求
3. 最后用真实数据压测
八、10 分钟完成一次中文语义检索
第一步:安装依赖
第二步:写入文本并执行检索
第三步:把检索结果接入 RAG
九、上线前重点检查什么?
1. 检索质量
2. 性能与成本
3. 工程与安全
十、五个常见误区
误区一:使用向量数据库后,RAG 就会准确
误区二:相似度达到 0.8 就一定相关
误区三:top-k 越大越好
误区四:原文变化后,数据库会自动理解
误区五:向量检索可以完全替代关键词检索
总结
一、为什么传统索引不擅长语义检索?
传统关系型数据库通常使用 B+ 树索引。它很适合两类查询:
- 精确匹配,例如
id = 5; - 范围查询,例如
age > 18。
但向量检索要解决的是另一个问题:
给定一个查询向量,在高维空间中找出距离最近的 top-k 个向量。
这类问题叫作最近邻搜索。
如果没有向量索引,最直接的方法是让查询向量和数据库中的每个向量逐一计算距离,然后排序,取出最相似的前 k 条。
这种方式叫作精确搜索,也常被称为暴力搜索。
假设知识库中有 100 万个文本块,每个向量是 1536 维,仅逐维比较的规模就是:
1536 × 1,000,000 = 1,536,000,000也就是约 15.36 亿个维度参与计算。
实际耗时还会受到距离算法、数据类型、硬件、并行方式和内存带宽影响,因此不能简单断言“一定需要几秒”。
但是,随着数据量和并发继续增长,每次查询都进行全量扫描,通常会变得非常昂贵。
向量数据库的核心价值,就是借助专用索引,减少每次查询需要比较的候选数量。
二、向量数据库里存的是什么?
一条典型的向量数据库记录通常包含三部分:
{ "id": "doc-001-chunk-03", "vector": [0.012, -0.083, 0.107], "metadata": { "document_id": "doc-001", "category": "RAG", "updated_at": "2026-07-29" } }其中:
id:唯一标识,用于更新和删除数据;vector:Embedding 模型生成的高维向量;metadata:文档来源、分类、权限、时间等可过滤字段。
有些向量数据库也会保存原文;有些项目则只在向量库中保存 ID 和元数据,把完整正文放在对象存储、搜索引擎或者关系型数据库中。
因此:
向量数据库不一定是业务数据的唯一数据源。
三、“相似”究竟是怎么算出来的?
向量数据库需要通过距离或者相似度,判断两个向量是否接近。
常见的计算方式有三种:
| 度量方式 | 直观含义 | 常见场景 |
|---|---|---|
| 余弦相似度 | 比较两个向量的方向是否接近 | 文本语义检索最常见 |
| 点积 | 同时受到方向和向量长度影响 | 模型明确按点积训练,或者向量已经归一化 |
| 欧氏距离 | 比较高维空间中的直线距离 | 图像、聚类以及部分专用模型 |
具体选择哪一种,不能只凭经验,应该优先参考 Embedding 模型的官方说明。
还要特别注意:
写入和查询必须使用相同的模型、向量维度、归一化方式和距离度量。
例如,你不能使用模型 A 为文档生成向量,却使用模型 B 为用户问题生成向量。即使两个模型的维度相同,它们的向量空间通常也不兼容。
四、向量数据库为什么能更快?
大规模向量检索通常会使用 ANN。
ANN 的全称是 Approximate Nearest Neighbor,也就是近似最近邻搜索。
它不会遍历数据库中的全部向量,而是快速找到一组最有希望的候选,然后从候选中选出 top-k。
这里的关键词是“近似”。
向量数据库通常不保证每次都返回数学意义上绝对最近的结果,而是在以下几个指标之间做取舍:
- 查询延迟;
- 检索召回率;
- 内存占用;
- 索引构建时间;
- 数据写入速度。
HNSW:从高速公路逐级驶入目标街区
HNSW 是目前常见的 ANN 索引之一。
它的全称是 Hierarchical Navigable Small World,中文通常翻译为分层可导航小世界图。
名字看起来复杂,但可以把它理解为一张多层道路网络:
- 高层节点数量少、跨度大,负责快速接近目标区域;
- 越往下节点越密,搜索越精细;
- 最底层包含全部节点,用于确定最终候选。
查询时,系统会从高层入口开始,沿着“更接近查询向量”的邻居不断移动,然后逐层向下搜索。
它有点像:
- 先走高速公路到达目标城区;
- 再进入城市主干道;
- 最后进入具体街道寻找门牌号。
整个过程不需要检查城市里的每一栋房子。
HNSW 中常见的参数包括:
M:每个节点大致保留多少连接;efConstruction:建立索引时搜索的候选规模;efSearch:执行查询时搜索的候选规模。
通常来说,参数越大,召回率可能越高,但也会占用更多内存、增加建库时间或者提高查询延迟。
除了 HNSW,还有 IVF、PQ、DiskANN 等索引或者量化方案,分别适合不同的数据规模、硬件条件和精度要求。
所以,以下说法都不够严谨:
- “向量数据库一定可以在几毫秒内完成查询”;
- “HNSW 一定能够带来 100 倍性能提升”;
- “某个数据库在所有场景下都比另一个数据库快”。
真实性能必须结合自己的数据量、向量维度、过滤条件、并发量和硬件环境进行测试。
五、向量数据库在 RAG 中怎么工作?
一个完整的 RAG 检索过程,可以分为离线建库和在线问答两部分。
离线建库
- 读取 PDF、网页、Word 等原始文档;
- 按照语义或者长度切成若干文本块;
- 使用 Embedding 模型把每个文本块转成向量;
- 把向量、文本块 ID 和元数据写入向量数据库;
- 建立或者更新向量索引。
最终形成的链路是:
原始文档 ↓ 文档解析 ↓ 文本切块 ↓ Embedding ↓ 向量 + ID + 元数据 ↓ 向量数据库在线问答
- 使用同一个 Embedding 模型把用户问题转成查询向量;
- 在向量数据库中检索 top-k 个相似文本块;
- 根据用户权限、时间、分类等元数据进行过滤;
- 必要时使用 Reranker 对候选结果重新排序;
- 把筛选后的内容连同用户问题交给大语言模型;
- 大模型根据检索内容生成答案。
在线链路可以表示为:
用户问题 ↓ Embedding ↓ 向量检索 ↓ 元数据过滤 ↓ Reranker(可选) ↓ 相关文本 + 用户问题 ↓ 大语言模型生成答案需要注意:
向量数据库只负责找到候选资料,并不会自动保证答案正确。
切块策略、Embedding 模型、召回数量、过滤规则、重排模型和提示词,都会影响最终效果。
六、哪些场景需要向量数据库?
向量数据库适合以下场景:
- 企业知识库和 RAG 问答;
- 按语义而不是关键词搜索文章、商品或者代码;
- 相似商品、内容或者用户推荐;
- 以图搜图、音频检索等多模态搜索;
- 相似内容检测、聚类和去重;
- AI Agent 的长期记忆检索。
以下情况不一定需要单独引入向量数据库:
- 数据量很小,精确扫描已经足够快;
- 只需要按照 ID、状态、时间等结构化字段查询;
- 团队已经使用 PostgreSQL、Elasticsearch 或 OpenSearch,其向量能力能够满足需求;
- 项目仍处于功能验证阶段,不值得过早增加新的基础设施。
判断标准不应该是“项目使用了 AI”,而应该是:
是否真的需要从大量非结构化内容中,按照语义相似度检索候选?
七、主流向量数据库怎么选?
目前常见的向量数据库或者向量检索方案包括 Chroma、Pinecone、Milvus、Qdrant、Weaviate 和 pgvector。
| 方案 | 主要特点 | 更适合的场景 | 需要注意 |
|---|---|---|---|
| Chroma | 上手简单,Python 生态友好,可以本地持久化 | 学习、原型、小型应用 | 生产能力需要根据部署模式和实际规模验证 |
| Pinecone | 全托管服务,基础设施负担较小 | 希望快速上线、不想自建运维 | 成本、数据驻留和供应商绑定 |
| Milvus | 开源、分布式、索引选择丰富 | 大规模检索、私有化部署 | 架构和运维复杂度相对较高 |
| Qdrant | Rust 实现,过滤能力和开发体验较好 | 自托管或者云端生产应用 | 仍需规划内存、磁盘和副本 |
| Weaviate | 支持混合检索和多种模型集成 | 需要结合关键词与向量检索 | 模块配置和资源规划需要评估 |
| pgvector | 直接复用 PostgreSQL 和 SQL 生态 | 已经使用 PostgreSQL、规模和并发中等 | 超大规模和高并发前需要认真压测 |
更实用的选择顺序
1. 先看现有技术栈
如果项目已经使用 PostgreSQL、Elasticsearch 或 OpenSearch,可以优先验证现有系统的向量能力。
这样可以减少数据库数量,也能降低运维成本和数据同步复杂度。
2. 再看部署要求
如果数据必须保存在内网,可以考虑:
- Milvus;
- Qdrant;
- Weaviate;
- pgvector。
如果不希望维护服务器、扩容和备份,可以考虑托管服务。
3. 最后用真实数据压测
不要只看官方发布的性能数字。
应该使用自己的:
- 向量维度;
- 数据规模;
- 元数据过滤条件;
- 查询并发量;
- top-k;
- 目标召回率。
进行实际测试后再做决定。
八、10 分钟完成一次中文语义检索
下面使用 Chroma 和一个中文 Embedding 模型,实现一个最小可运行的语义检索示例。
第一步:安装依赖
pip install chromadb sentence-transformers首次运行时会下载模型,需要能够访问对应的模型仓库。
第二步:写入文本并执行检索
import chromadb from sentence_transformers import SentenceTransformer # 加载中文 Embedding 模型 model = SentenceTransformer("BAAI/bge-small-zh-v1.5") # 数据保存在当前目录的 chroma_db 文件夹中 client = chromadb.PersistentClient(path="./chroma_db") collection = client.get_or_create_collection( name="ai_howto", metadata={"hnsw:space": "cosine"}, ) # 准备演示数据 documents = [ "RAG 会先从外部知识库检索相关资料,再让大模型生成回答。", "提示词工程通过角色、任务、约束和示例改善模型输出。", "向量数据库可以按照语义相似度检索文本、图片等非结构化数据。", ] ids = [ "rag-001", "prompt-001", "vector-001", ] metadatas = [ {"category": "RAG"}, {"category": "Prompt"}, {"category": "RAG"}, ] # 生成文档向量 document_vectors = model.encode( documents, normalize_embeddings=True, ).tolist() # 写入向量数据库 collection.upsert( ids=ids, documents=documents, metadatas=metadatas, embeddings=document_vectors, ) # 用户问题 question = "怎样根据意思找到知识库中相关的内容?" # 查询时必须使用同一个模型和相同的归一化方式 query_vector = model.encode( [question], normalize_embeddings=True, ).tolist() # 检索最相关的两条内容 result = collection.query( query_embeddings=query_vector, n_results=2, include=["documents", "metadatas", "distances"], ) # 输出结果 for text, metadata, distance in zip( result["documents"][0], result["metadatas"][0], result["distances"][0], ): print( f"distance={distance:.4f} | " f"{metadata['category']} | " f"{text}" )虽然用户问题中没有出现“向量数据库”这个完整关键词,检索结果仍然应该优先返回与“语义检索”“知识库”相关的内容。
这就是向量搜索和单纯关键词匹配的区别。
第三步:把检索结果接入 RAG
实际项目中,可以把检索到的文本拼成上下文:
contexts = result["documents"][0] context_text = "\n\n".join(contexts) prompt = f"""请只根据参考资料回答问题。 如果参考资料不足,请明确说明无法回答。 参考资料: {context_text} 用户问题: {question} """接下来,把这个prompt传给你所使用的大模型 API,就完成了一个最小的 RAG 问答流程。
生产环境还应该为检索结果附上来源链接,并处理以下问题:
- 文档权限;
- 多租户数据隔离;
- 提示词注入;
- 敏感信息;
- 文档版本;
- 引用来源。
九、上线前重点检查什么?
1. 检索质量
建议建立一组真实问题和标准相关文档,然后评估:
- Recall@k;
- MRR;
- nDCG;
- 最终问答准确率。
同时比较:
- 不同 Embedding 模型;
- 不同切块大小;
- 不同 top-k;
- 是否加入关键词检索;
- 是否加入 Reranker。
对于人名、产品编号、错误码等精确信息,通常可以考虑混合检索,而不是只依赖向量搜索。
2. 性能与成本
压测时应该使用真实的数据规模、向量维度、过滤比例和并发量。
不要只观察平均延迟,还要关注:
- P50;
- P95;
- P99。
同时评估:
- 向量占用的内存;
- 索引占用的内存和磁盘;
- 数据副本成本;
- 托管服务调用费用;
- 新增或者更新数据后的可见时间。
3. 工程与安全
生产环境至少应该做到:
- 记录 Embedding 模型名称和版本;
- 记录向量维度、归一化方式和距离度量;
- 更换模型后重新生成全部向量;
- 在服务端执行租户、部门和文档权限过滤;
- 保留原始文档来源和版本;
- 支持数据更新和删除;
- 做好备份、监控、容量规划和故障恢复。
十、五个常见误区
误区一:使用向量数据库后,RAG 就会准确
向量数据库只负责候选召回。
最终答案还取决于:
- 原始数据质量;
- 文档切块;
- Embedding 模型;
- 检索策略;
- Reranker;
- 提示词;
- 大语言模型。
误区二:相似度达到 0.8 就一定相关
不同模型、归一化方式和距离度量产生的分数不可直接比较。
阈值必须通过自己的业务数据和评测集确定。
误区三:top-k 越大越好
召回更多内容可能提高覆盖率,但也会:
- 增加模型调用成本;
- 占用更多上下文;
- 引入不相关信息;
- 干扰大模型生成答案。
误区四:原文变化后,数据库会自动理解
原始文档发生变化后,通常需要:
- 找到受影响的文本块;
- 重新切块;
- 重新生成向量;
- 更新或者删除旧记录。
误区五:向量检索可以完全替代关键词检索
对于产品编号、人名、专有名词、错误码和精确短语,关键词检索往往更稳定。
因此,很多生产系统最终会采用:
关键词检索 + 向量检索 + Reranker
也就是混合检索方案。
总结
记住下面四句话就够了:
- 向量数据库的核心能力,是在大量高维向量中进行相似度检索,并结合元数据过滤;
- 普通数据库可以存向量,部分传统数据系统也已经支持向量检索,是否另建系统取决于规模和需求;
- HNSW 等 ANN 索引通过近似搜索降低查询延迟,但效果和速度必须使用真实数据验证;
- 在 RAG 中,向量数据库只是检索环节,Embedding、切块、混合检索、重排和权限控制同样重要。
如果只是学习和制作原型,可以从 Chroma 开始。
如果项目已经使用 PostgreSQL,可以先测试 pgvector。
如果要面向生产环境,再根据托管、私有化、团队运维能力和真实压测结果,选择 Pinecone、Milvus、Qdrant 或 Weaviate。
