Intro-What is a Vector DB
原文链接:https://www.yuque.com/yangguangfanxing/nmhuv1/xwep8spkdtwnkluw

向量数据库为什么重要
从现代 AI 应用切入:视觉商品搜索、RAG 问答、推荐系统。这种安排很关键,因为向量数据库不是为了替代传统数据库而出现,而是为了解决一类传统数据库不擅长的问题:如何在海量高维向量中快速找“相似”的对象。
向量数据库的核心场景可以概括为:
- 把文本、图片、音频、用户行为等数据输入模型。
- 模型输出一个 embedding,也就是向量表示。
- 把向量和相关属性存入数据库。
- 查询时也先把查询对象转成向量。
- 在数据库里找与查询向量最接近的一批向量。
这里的“接近”通常不是传统数据库里的等值匹配或范围过滤,而是语义相似、视觉相似、偏好相似。


1000 个 float数值(通常为 32 位浮点数)的向量在内存中大约占 4 KB。
31 30-23 22-0
├───┬──────┬───────────────┤
│ S │ 指数 │ 尾数 │
└───┴──────┴───────────────┘
1位 8位 23位计算方式:
- 1 个
float通常为 4 字节(32 位)。 - 1000 × 4 字节 = 4000 字节 ≈ 3.91 KB。
在存储或传输时,如果使用二进制格式(如 .npy或 .bin),大小接近这个值;如果保存为文本格式(如 CSV 或 JSON),由于字符编码和分隔符,文件体积会更大。实际项目中还需考虑容器格式的额外开销。
视觉商品搜索:第一个动机场景
课件用视觉商品搜索作为第一个例子:用户拍一张照片,系统返回相似商品。
基本流程是:
- 对商品图片提取特征向量。
- 把这些向量存入数据库。
- 用户上传图片时,也提取查询图片的向量。
- 在数据库中查找最近邻商品。
这个例子看起来直观,但马上暴露出向量数据库的系统难题。以京东的视觉搜索为例,规模可能达到:
每个向量维度大约是:
如果每个维度用一个 32 位浮点数,也就是 4 字节,那么仅存储向量本身大约需要:
这说明第一个问题是存储:向量数据太大,不能简单地全部放进内存。
第二个问题是查询:如果对每个查询都暴力比较全部向量,计算量是:
代入课件中的数量级:
即使有每秒 20 TFLOPS 的计算能力,单次查询理论上也要约:
这还没有算数据读取、调度、网络和系统开销。对在线搜索来说,5 秒延迟显然不可接受。
因此,向量数据库不能只是“把向量塞进传统数据库”。问题在于:传统数据库索引通常针对单个属性或属性组合,而向量最近邻搜索要比较的是整个高维向量。

用索引加速:从全量扫描到近似搜索
接着课件回到视觉搜索例子,并引出一个朴素但重要的思路:先把向量聚类,再按簇组织数据。
查询时:
- 找到离查询向量最近的一个或几个簇。
- 只在这些簇内部搜索候选向量。
- 返回候选中距离最近的结果。
插入时:
- 判断新向量最接近哪个簇。
- 把它加入对应簇的列表。
这就是近似最近邻搜索的基本精神:放弃完全精确的全库搜索,换取大幅性能提升。
这里的设计取舍是向量数据库的主旋律:为了毫秒级查询,可以接受一定程度的近似;为了更快写入和更低成本,可以接受最终一致性或周期性重建索引。

RAG 问答:向量数据库作为 LLM 的外部记忆
第二个应用是 RAG,也就是 Retrieval-Augmented Generation。
普通 LLM 只根据模型参数和输入问题生成回答。RAG 的思路是:先从外部文档库中检索相关内容,再把这些内容作为上下文交给 LLM。
课件中的流程是:
- 为文档生成 embedding。
- 查询时为用户问题生成 embedding。
- 通过近邻搜索找到相关文档。
- 可选地进行 rerank,提高相关性排序质量。
- 把文档内容放进 prompt。
- LLM 根据问题和上下文生成回答。
在这个场景里,向量数据库承担的不是“最终回答者”的角色,而是“相关上下文检索器”的角色。它决定了模型能看到哪些外部知识,因此会直接影响回答质量。
这个例子也说明,向量数据库常常位于 AI 应用链路中间:前面接 embedding 模型,后面接 LLM、重排模型或业务逻辑。

推荐系统:向量搜索与重排结合
第三个应用是推荐系统。目标是给用户推荐商品、视频、音乐等内容。
课件给出的流程是:
- 为商品或内容创建向量。
- 为用户偏好创建查询向量。
- 搜索与用户偏好向量接近的内容向量。
- 根据近期行为、业务规则或其他模型进行重排。
推荐系统对向量数据库提出几个要求:
- 高吞吐:用户请求量很大。
- 好准确率:推荐质量依赖相似性搜索质量。
- 弹性:每天不同时间的流量会明显波动。
这类系统通常不会只依赖一次向量搜索完成推荐,而是把向量搜索作为召回阶段,再通过更复杂的排序模型做最终结果。

三个场景的共同模式
视觉搜索、RAG、推荐系统看起来很不同,但底层功能非常一致。
写入数据时:
- 把原始数据转成 embedding。
- 把 embedding 存入专门的数据库。
查询数据时:
- 把查询也转成向量。
- 在数据库中找相似向量。
- 返回对应的数据、文档、商品或其他对象。
这就是对向量数据库的第一层抽象:它是一个专门为向量存储和语义搜索服务的数据库系统。

















什么是向量数据库:鸟瞰定义
进入技术主线后,课件给出一个非常简洁的定义:
更完整地说,向量数据库负责:
- 存储大量向量。
- 存储向量关联的属性或 payload。
- 支持快速查找与查询向量相近的向量。
- 支持一些简单过滤条件。
插入时,系统创建向量:
查询时,系统创建查询向量:
然后查找与:最近的向量。
注意这里的“语义搜索”不是 SQL 中的字符串匹配,而是通过 embedding 空间中的距离表达语义相似性。例如,两段文字的词面可能完全不同,但如果 embedding 接近,系统就认为它们在语义上相关。


k-Nearest Neighbors (kNN)
k近邻算法是一种基于实例的惰性学习(lazy learning)算法,既可用于分类任务,也可用于回归任务。其核心思想是"物以类聚,人以群分":一个数据点的类别或数值可以通过其周围最近邻的数据点来推断。
基本特点
- 无显式训练:不进行模型训练,只存储训练数据
- 基于距离:通过距离度量判断样本相似性
- 参数简单:主要参数只有k值和距离度量方式
- 直观易懂:决策过程易于理解和解释
形式化定义
给定训练集 包含
个样本:
其中:
是
维特征向量:
是对应的标签(分类任务为类别标签,回归任务为连续值)
对于查询点 ,预测其标签
。
算法步骤
- 计算距离: 计算
与
中每个样本的距离
- 排序选择: 将距离按升序排序,选择前
个最小距离对应的样本,构成
-近邻集合
- 决策预测: 根据
中邻居的标签,通过特定规则预测
距离度量
- 欧几里得距离(Euclidean Distance)
最常用的距离度量,即多维空间中的直线距离:
特点:
- 各维度贡献平等
- 对特征的量纲敏感
- 需要特征标准化处理
- 曼哈顿距离(Manhattan Distance)
各维度绝对差之和:
特点:
- 计算效率高于欧氏距离
- 对异常值相对不敏感
- 适用于网格状数据
- 闵可夫斯基距离(Minkowski Distance)
欧氏距离和曼哈顿距离的推广:
其中:
:曼哈顿距离
:欧几里得距离
:切比雪夫距离
- 余弦相似度(Cosine Similarity)
衡量向量方向的相似性,忽略大小:
转换为距离:
适用场景:文本分类、推荐系统等高维稀疏数据
距离度量选择指南
| 距离度量 | 适用场景 | 注意事项 |
|---|---|---|
| 欧几里得 | 连续特征,各维度同等重要 | 需特征标准化 |
| 曼哈顿 | 高维数据,计算效率要求高 | 对异常值较鲁棒 |
| 余弦相似度 | 文本、图像等高维稀疏数据 | 关注方向而非大小 |
| 汉明距离 | 分类特征,二进制数据 | 仅适用于离散特征 |
k值选择
k值的影响
| k值 | 模型复杂度 | 决策边界 | 偏差-方差 | 适用场景 |
|---|---|---|---|---|
| k值小 | 高复杂度 | 崎岖不平 | 低偏差,高方差 | 数据干净,噪声少 |
| k值大 | 低复杂度 | 平滑 | 高偏差,低方差 | 噪声较多,数据量大 |
选择策略
- 经验法则: 通常从较小的奇数开始尝试(如 3, 5, 7),避免分类投票时出现平局
- 交叉验证: 通过交叉验证选择在验证集上性能最好的
值
- 启发式方法:
,其中
是训练样本数量
极端情况
- 当
时:1-近邻,完全依赖最近的一个样本
- 当
时:
决策规则
(1) 分类:多数投票法(Majority Voting)
其中:
遍历所有可能的类别
是指示函数:
示例: 假设 ,邻居的类别为
:
- 类别 A 出现 3 次
- 类别 B 出现 1 次
- 类别 C 出现 1 次
预测结果:
(2) 分类:加权多数投票法(Weighted Majority Voting)
为更近的邻居分配更高的权重:
其中 是一个很小的正数,防止分母为零。
预测公式:
(3) 回归:简单平均法(Simple Average)
示例: 假设 ,邻居的值为
:
(4) 回归:加权平均法(Weighted Average)
其中权重 通常与距离成反比。
算法伪代码
基本 kNN 分类算法
输入:
- 训练集
- 查询点
- 近邻数量
- 距离函数
输出:
- 预测标签
步骤:
- 对于训练集中的每个样本
: a. 计算距离
- 从
中选择 k 个距离最小的样本,构成近邻集合
其中
- 统计
中各类别的频数:
对于每个类别 c
- 返回出现次数最多的类别:
加权 kNN 分类算法
步骤1-2同基本kNN
- 为每个近邻计算权重:
或其他权重函数
- 计算每个类别的加权票数:
对于每个类别 c
- 返回加权票数最高的类别:
重要注意事项
- 特征缩放的重要性
由于距离度量对特征的尺度敏感,使用 kNN 前通常需要对特征进行标准化或归一化。
标准化(Z-score 标准化):
其中 是特征
的均值,
是标准差。
归一化(Min-Max 缩放):
- 维度灾难
在高维空间中,kNN 算法面临"维度灾难"问题:
- 随着维度增加,数据点之间的距离变得相似
- 最近邻与最远邻的区分度降低
- 需要更多的数据来维持相同的密度
解决方案:
- 特征选择
- 特征提取(如 PCA)
- 使用更适合高维数据的距离度量
算法复杂度
| 指标 | 复杂度 | 说明 |
|---|---|---|
| 训练复杂度 | 惰性学习,仅存储数据 | |
| 预测复杂度 | ||
| 空间复杂度 | 需要存储所有训练数据 |
示例1:分类问题
假设有一个简单的二维数据集,包含两个类别(红色和蓝色),想要预测绿色点的类别():
- 红色点:
- 蓝色点:
- 查询点:
计算欧氏距离:
到红色点的距离:
到蓝色点的距离:
最近 3 个邻居:红色(1.41), 蓝色(1.41), 红色(2.24)
红色:2 票,蓝色:1 票 预测为红色
示例2:回归问题
预测房屋价格():
| 房屋 | 面积 | 价格 | 到查询点距离 |
|---|---|---|---|
| 房屋1 | 100 m² | 300 万 | 1.2 |
| 房屋2 | 120 m² | 360 万 | 0.8 |
| 房屋3 | 90 m² | 280 万 | 1.5 |
| 房屋4 | 110 m² | 320 万 | 2.0 |
- 查询点:105 m²
- 最近 3 个邻居:房屋2 (0.8), 房屋1 (1.2), 房屋3 (1.5)
简单平均:
加权平均:
权重:



RDBMS 与 VDBMS 的总体差异
接下来系统比较传统关系数据库和向量数据库。
传统 RDBMS 面向的是 record,也就是有结构的行。查询语言是关系代数和 SQL,支持 join、group、foreign key、cursor、事务等复杂能力。
VDBMS 面向的是 vector,也就是高维数值数组。查询核心是最近邻搜索和简单过滤。它通常没有复杂 join,没有传统意义上的查询优化器,也不强调事务语义。
可以这样理解:
- RDBMS 擅长精确结构化查询。
- VDBMS 擅长高维相似性查询。
- RDBMS 的数据语义来自字段名、类型、约束和关系。
- VDBMS 的数据语义来自整个向量在 embedding 空间中的位置。

Record 与 Vector 的差异
传统数据库中的一行记录通常有少量属性,比如商品 ID、卖家 ID、价格、颜色等。每个属性有名字、类型和意义,可以独立比较、过滤、聚合。
向量则是一个很长的标量列表。单个维度通常没有人类可解释的语义。第 17 个维度或第 203 个维度本身不代表“颜色”或“价格”,意义来自整个向量。
比较两条记录通常很便宜,因为只看几个字段就够了。但比较两个向量需要遍历维度:
这就是为什么向量查询成本高。维度越大,单次距离计算越贵;向量数量越多,全量扫描越不可行。

RDBMS 查询:表达能力强,但系统复杂
RDBMS 的查询通常只触碰一个或几个属性,但表达能力非常强。SQL 可以做:
- 过滤。
- 聚合。
- 分组。
- 多表连接。
- 子查询。
- 游标。
- 多行复杂结果生成。
这种能力背后需要复杂的数据模型、schema、索引、优化器和执行器。数据库需要判断不同执行计划的代价,选择高效路径。
所以 RDBMS 的强大来自复杂性:复杂 API、复杂查询计划、复杂执行机制。

VDBMS 查询:简单 API 下的高成本相似搜索
VDBMS 查询通常触碰整个向量。最常见操作包括:
- 按 key 获取对象。
- 最近邻搜索。
- 带简单属性过滤的最近邻搜索。
- 范围查询:找出距离阈值内的向量。
- 混合查询:向量搜索加属性过滤。
- 多向量或多空间搜索。
最近邻搜索可能是精确的,也可能是近似的。实际系统中为了性能,近似搜索更常见。
常见相似度度量包括:
- 欧氏距离。
- 余弦相似度。
- 内积。
VDBMS 目前没有统一的 SQL 等价标准。不同产品的 API 差异明显,常见形式是 HTTP 或 REST,并提供 Python、Java、Go 等语言绑定。
一些扩展型向量数据库会继承已有数据库的 SQL 能力。例如在 SQL 中加入向量距离运算:
这类系统的优点是能保留成熟数据库的事务、SQL、数据模型和生态,但可能在纯向量搜索性能上不如原生 VDBMS。


索引:VDBMS 性能的关键
RDBMS 的索引通常建立在一个属性或多个属性组合上。常见索引包括 B-tree、hash、文本索引等。它们用于加速过滤、比较和范围查询。更新通常较快。
VDBMS 的索引针对整个向量建立。常见类型包括:
- 图索引。
- LSH。
- 表结构。
- flat 索引。
- 树结构。
向量索引的核心目的不是加速属性过滤,而是加速最近邻搜索。
但这里有一个重要代价:向量索引更新可能很慢,有时甚至需要周期性重建。于是 VDBMS 经常采用:
- 近似最近邻。
- 周期性索引重建。
- 最终一致性模型。
从复杂度对比看,VDBMS 的索引更新可能是:或:
而传统索引更新常见成本可能接近:或:
这也是 VDBMS 写入和索引维护比 RDBMS 更棘手的原因。

更新:为什么 VDBMS 不像 RDBMS 那样灵活
RDBMS 可以更新单个属性,也可以基于复杂查询更新多行。事务可以保证多个读写操作的一致性。
VDBMS 通常不这么做。原因是向量的单个维度没有独立业务意义,因此“只更新某一个标量”通常没有价值。更新一个向量更像是:
- 删除旧向量。
- 插入新向量。
关联属性可以单独更新,但向量本身通常按整体处理。
这会带来两个后果:
- 向量更新不一定立即反映在索引中。
- 系统更倾向于最终一致性,而不是强事务一致性。

存储:结构化行 vs 不透明向量
RDBMS 的存储选择很多,因为它知道每行有哪些属性、属性类型、取值范围和查询方式。它可以选择:
- 行式存储。
- 列式存储。
- LSM 结构。
- 每个属性单独建索引。
这使得 RDBMS 比较容易按属性分区、按查询模式优化。

VDBMS 面对的是 dense vector,也就是密集向量。单个向量整体上是不透明 blob,系统很难利用“第几个维度”的语义来分区或优化。
因此 VDBMS 常见做法是:
- 向量存入 KV、块存储或 blob 存储。
- 索引放在内存中,部分系统支持磁盘索引。
- 属性或 payload 存在另一套结构中。
- 分区通常依赖向量索引或聚类结构。
这解释了为什么 VDBMS 的存储系统常常更定制化,也更依赖索引设计。

硬件与架构:GPU 改变了系统设计
RDBMS 的主要资源通常是 CPU、内存和存储。不同操作的成本虽然不同,但整体资源画像相对统一,所以单体架构或粗粒度扩展比较常见。
VDBMS 增加了一个非常重要的资源:GPU。
GPU 可能用于:
- 批量向量计算。
- 索引构建。
- 大规模相似度搜索。
- embedding 生成或模型推理。
但 GPU 昂贵,功耗高,而且不同任务对资源需求差异很大。比如:
- 查询需要低延迟。
- 插入需要处理新数据。
- 索引构建可能是批处理重任务。
- embedding 生成可能依赖模型推理。
因此 VDBMS 更容易走向 disaggregated architecture,也就是把不同功能拆开独立扩展。查询、写入、索引构建、存储、推理可以使用不同资源池。
提醒,这些都是 generalization:现实中也有分离式 RDBMS,也有单体式 VDBMS。不过 VDBMS 是在现代云环境中成长起来的,所以更自然地接受细粒度扩展和服务拆分。

两类 VDBMS:原生型与扩展型
向量数据库分成两大类。
原生 VDBMS
原生 VDBMS 从一开始就是为向量数据库设计的。它们通常有专门架构和高性能向量索引。例子包括:
- Vearch。
- Pinecone。
- Azure AI Search。
- Milvus。
- Qdrant。
- Weaviate。
- Chroma。
优点:
- 向量搜索性能高。
- 架构能围绕向量索引和相似搜索优化。
缺点:
- 查询语言和数据模型有限。
- 通常没有成熟 SQL、事务和复杂查询。
- 可能和原始业务数据系统分离,导致数据同步问题。
扩展型 VDBMS
扩展型 VDBMS 是在已有关系数据库或 NoSQL 数据库上加入向量能力。例子包括:
- pgvector。
- Vespa。
- Timescale。
- CosmosDB。
- Redis。
- PASE。
优点:
- 继承原数据库的数据模型。
- 可以保留 SQL、事务、ACID、权限和生态。
- 可以把源数据和向量放在同一个系统中。
缺点:
- 可能不如原生系统快。
- 向量索引和事务结合会让更新更慢。
- 某些系统有功能限制,例如维度上限或索引能力不足。
这一组对比说明:选型不是“哪个产品最好”,而是看业务更需要高性能向量搜索,还是更需要成熟数据库能力。

总结: 关键挑战
第一,向量大而密集。存储、读取、比较都贵。
第二,高维空间难以索引。这对应常说的维度灾难:维度极高时,距离分布、空间划分和索引剪枝都会变得困难。
第三,向量没有天然结构或顺序。传统数据库可以按价格、时间、ID 排序或分区,但向量整体没有天然排序。
第四,搜索条件模糊。SQL 的条件通常清晰,比如价格大于某个值;向量搜索则是“相似”,而相似性的含义依赖 embedding 模型、距离函数和业务目标。
第五,向量搜索很难和属性过滤完美结合。例如先过滤再向量搜索,可能候选太少;先向量搜索再过滤,可能结果不够。如何平衡两者是系统设计难点。
第六,索引更新昂贵。和传统数据库相比,VDBMS 的写入、删除和更新往往更难做到立即可见且高性能。

逻辑组件:一个向量数据库系统大致长什么样
最后给出 VDBMS 的逻辑组件图。它不是某个产品的真实架构,而是概念框架。
主要组件包括:
- API:接受读写请求。
- Index:处理向量,支持快速检索。
- Storage:持久化存储向量、属性,有时也存储索引。
- Liveness:临时保存新写入数据,缓解索引更新慢的问题。
- Planner:决定查询如何执行。
- Executor:执行查询,收集结果。
- Storage manager:管理底层存储。
其中 Liveness 很有意思。它的存在是因为索引更新可能慢,新插入的数据不能总是马上进入主索引。系统可以先把新数据放在临时结构里,查询时同时查主索引和临时数据,从而让新数据尽快可见。
实际生产系统会比这复杂很多,还会有:
- 监控。
- 备份。
- 编排。
- 推理服务。
- 多租户。
- 安全与合规。
- 插件式存储或索引。
- 分布式协调。
所以这张图更适合理解概念边界,而不是照着实现一个生产系统。

核心 takeaway
真正想建立的是一个系统视角:
- 向量数据库不是“带向量字段的普通数据库”,而是围绕高维相似搜索重新设计的系统。
- 它的核心操作是最近邻搜索,不是关系代数。
- 它的核心瓶颈来自向量规模、维度、索引更新和查询延迟。
- 它通常接受近似结果和最终一致性,以换取性能和可扩展性。
- 原生 VDBMS 与扩展型 VDBMS 分别代表两种路线:性能优先和数据库生态优先。
- 在现代 AI 应用中,VDBMS 往往连接 embedding 模型、LLM、推荐系统、搜索系统和业务数据。
一句话总结:
向量数据库是为“在海量高维向量中快速找到语义相似对象”而设计的数据库系统;它牺牲一部分传统数据库能力,换取 AI 应用所需要的相似搜索性能。