Q916RAG 检索增强真题解析RAG(检索增强生成)AgentAlpha 社区真题库约 7 分钟更新 2026-09-29

向量数据库到底存了什么

1 向量数据库到底存了什么

P0 · rag

🏷 标签:vector-database, embedding, indexing

1️⃣ 考察意图

面试官想确认你是否真正理解向量数据库的内部存储结构,而不是只会调 API 调包。表面是问“存了什么”,实际考察三个层次:存储的物理组成(向量、元数据、索引)、存储的逻辑分层(原始数据 vs 索引结构)、工程取舍(为什么不能只存向量)。刁钻点在于:很多人答“存 embedding”就停了,漏掉了索引结构和元数据过滤的存储开销。答好了能展示你对 RAG 整条链路存储模型的理解,以及处理亿级向量时的工程直觉。

2️⃣ 标准答

向量数据库存储的是 四层结构,缺一不可:

  • 向量(Vector / Embedding):核心数据,通常是 768-1536 维的 float32 数组(如 text-embedding-3-small 输出 1536 维)。存储格式是二进制浮点数组,单条向量占 1536×4 = 6KB。为什么不能压缩成 float16? 精度损失在 top-K 召回时可能漏掉关键文档,但亿级场景下可用 PQ(Product Quantization)压缩到 1/4 大小,代价是召回率降 1-3 个点。
  • 原始数据(Payload / Document):用户最终要返回的文本、图片 URL 或 JSON 对象。实际落地的坑:很多人把整篇 10KB 的文档原文存进去,导致存储膨胀 10 倍。解法是只存文档 ID 和摘要(<500 字符),正文放对象存储(S3/MinIO),查询时用 ID 回源拉取。
  • 索引结构(Index):加速搜索的数据结构,最常用 HNSW(Hierarchical Navigable Small World)和 IVF(Inverted File Index)。HNSW 额外存储多层图结构,每个节点存邻居列表,索引大小通常是向量的 1.2-1.5 倍(100 万条 768 维向量,HNSW 索引约 1.2GB)。工程取舍:HNSW 的 efConstruction 参数(构建时搜索宽度)调大能提高召回率,但索引构建时间从 10 分钟暴涨到 2 小时,且内存占用翻倍。
  • 元数据(Metadata):用于过滤的字段,如时间戳、文档类型、权限标签。存储格式是倒排索引或 B-tree(如 Milvus 用 Tantivy 做标量索引)。为什么不能只靠向量搜索? 假设你要查“2024 年 3 月的技术文档”,纯向量搜索会把所有时间段的相似文档都召回,再在内存里过滤,百万级数据下过滤耗时从 5ms 涨到 200ms。正确做法是建标量索引(如时间戳的 B-tree),在搜索时做“向量相似度 + 标量过滤”的混合查询。

总结一句话:向量数据库存的是 向量 + 原始数据 + 索引 + 元数据 的复合体,四者协同才能实现毫秒级混合搜索。

3️⃣ 答题模板(30 秒电梯版)

“这个问题我从存储组成、索引结构、元数据过滤三个层面回答。第一,核心存的是 embedding 向量,但必须同时存原始数据(payload)和元数据(时间戳等)。第二,为了加速搜索,额外存了 HNSW 或 IVF 索引结构,索引大小通常是向量的 1.2-1.5 倍。第三,元数据用倒排索引或 B-tree 存储,支持混合查询。总结一句:向量数据库不是只存向量,而是向量+原始数据+索引+元数据的四层存储体系。”

4️⃣ 高频追问 & 应对

追问 1:那如果我只存向量,不存原始数据,行不行?

技术上可以,但工程上不可行。只存向量意味着你只能返回“相似向量”,无法拿到原始文本。实际场景中用户要的是文档内容,不是向量。正确做法是存向量 + 文档 ID,正文放外部存储(如 S3),查询时先向量搜索拿到 ID 列表,再批量回源拉取。这样存储成本降低 80%,但多了一次网络 IO,延迟从 5ms 涨到 15ms,可接受。

追问 2:HNSW 索引和 IVF 索引,你选哪个?为什么?

看数据规模和延迟要求。百万级以下选 HNSW,因为它搜索延迟稳定在 1-10ms,召回率 99%+。千万级以上选 IVF,因为 HNSW 的内存占用随数据量线性增长,1 亿条 768 维向量需要 120GB 内存,而 IVF 通过聚类(如 4096 个中心)把搜索范围缩小到 1/4096,内存降到 30GB,但召回率降到 95% 左右。实际落地的坑:IVF 的 nprobe 参数(搜索时访问的聚类数)设太小会漏召回,设太大延迟爆炸。经验值:nprobe=16 时召回率 97%,延迟 20ms。

追问 3:元数据过滤是在搜索前还是搜索后做?为什么?

必须搜索前做(pre-filter),否则性能崩。搜索后过滤(post-filter)意味着先召回 top-1000 向量,再在内存里按时间戳过滤,如果只有 10 条符合条件,那 990 条都是无效计算。正确做法是建标量索引(如时间戳的 B-tree),在 HNSW 搜索时直接跳过不满足条件的节点。Milvus 的“混合查询”就是通过 Bitmap 索引实现的,过滤条件在搜索阶段就生效,延迟从 200ms 降到 5ms。

5️⃣ 避坑 · 常见错误答法

  • ❌ “向量数据库存的是 embedding 向量,用来做相似度搜索。” → ✅ 必须补充:还存了原始数据(payload)、索引结构(HNSW/IVF)和元数据(时间戳等),四者缺一不可。只答向量说明你没做过工程落地。
  • ❌ “索引结构是自动生成的,不需要手动管理。” → ✅ 索引参数(如 HNSW 的 M 和 efConstruction)需要根据数据量和召回率要求手动调优,默认参数在亿级场景下可能内存溢出或召回率暴跌。
  • ❌ “元数据过滤用 SQL 就行,向量数据库不擅长这个。” → ✅ 现代向量数据库(Milvus、Qdrant)都内置了标量索引引擎(如 Tantivy),支持在向量搜索的同时做等值/范围过滤,不需要外挂数据库。

6️⃣ 简历呼应

  • 如果你有 RAG 项目:从“存储结构影响检索延迟”切入,举例你如何通过只存文档 ID + 摘要(而非全文)将存储成本降低 60%,同时用 HNSW 索引将 top-5 召回延迟从 50ms 压到 8ms。
  • 如果你只做过传统 NLP:用“倒排索引 vs 向量索引”类比迁移,说明传统 ES 存的是 term-document 矩阵,而向量数据库存的是 embedding + HNSW 图结构,两者本质都是“数据 + 索引”的存储模式。
  • 如果你是校招无项目:聚焦 FAISS 官方文档中的“存储结构”章节,复现一个 demo:用 text-embedding-ada-002 生成 1000 条新闻标题的向量,存为 FAISS IndexFlatIP + 外部 JSON 文件存元数据,对比纯向量搜索 vs 混合搜索的召回差异。
  • FAISS 官方文档:Index structure and storage format(IVF / HNSW / PQ 的存储细节)
  • Milvus 论文:Milvus: A Purpose-Built Vector Data Management System(存储架构章节)
  • Qdrant 博客:How Qdrant stores vectors and payloads(元数据索引实现)
  • HNSW 原论文:Efficient and robust approximate nearest neighbor search using Hierarchical Navigable Small World graphs
  • 工程实践:Pinecone 的“Understanding Vector Database Storage”系列博客

—— 本场面试完 ——

我们不做玩具级 Demo 教学。训练营的作业是开源项目和论文——我们想陪伴你,做出能改变生活、最后改变世界的项目。