Appearance
4.1.1 向量数据库到底存了什么?
先给结论:向量数据库里通常存的不只是“文本变成的向量”,而是一个可被检索、过滤、更新和追溯的索引对象。
这也是为什么很多人第一次理解向量数据库时会觉得它很简单,真正做起来以后又会发现远比想象中复杂。
很多人最开始的理解为什么不够
最常见的初始理解通常是:
- 把文本做 embedding
- 得到一个向量
- 存进向量数据库
- 查询时再做相似度检索
这当然是核心流程的一部分,但如果你只停在这里,就会忽略掉生产系统里真正重要的几层内容。
向量数据库里通常至少会存什么
1. 向量本身
这是最容易理解的一层。
也就是每个 chunk 对应的向量表示,用来支持:
- 相似度检索
- 近邻搜索
- 语义召回
2. 原始文本或可回填文本
检索回来以后,系统通常不仅要知道“命中了哪个向量”,还要知道:
- 这段内容到底是什么
- 最后准备送给模型什么文本
所以很多系统里,向量对象后面都会挂着可回填的文本。
3. 稳定 ID
比如:
doc_idchunk_id
没有稳定 ID,后面的:
- 更新
- 删除
- 替换
- 回滚
都会变得很难做。
4. metadata
这是实际系统里经常比向量本身还重要的一层。
比如:
- 来源
- 标题
- 版本
- 状态
- 时间
- 租户
- 权限边界
这层信息会直接影响:
- 检索前过滤
- 检索后排序
- 来源展示
- 更新和治理
5. 索引结构本身
很多人会忽略这一点。
向量数据库里除了“数据对象”本身,通常还会维护底层近邻搜索结构,用来支持更快的相似度查询。
也就是说,它不只是“存了几条记录”,而是还在组织“以后怎么查得快”。
一个最小示意
python
vector_record = {
"id": "refund-policy-v3#chunk-03",
"vector": [0.12, -0.03, 0.88, ...],
"text": "定制类商品不支持无理由退货。",
"metadata": {
"doc_id": "refund-policy-v3",
"title": "退款规则",
"source": "/help/refund",
"version": "v3",
"status": "active",
"updated_at": "2026-04-01",
"tenant_id": "tenant-a"
}
}这个对象真正说明的不是“向量数据库会存一个数组”,而是:
它通常会存一个带身份、文本、边界和可检索结构的对象。
为什么这件事很重要
因为如果你把向量数据库理解成“只存向量”,后面就很容易在这些地方踩坑:
- 不知道怎么做 metadata filter
- 不知道怎么更新旧版本
- 不知道怎么定位来源
- 不知道怎么做权限和多租户隔离
这些问题看起来是系统后期问题,但很多时候都是从一开始对“向量数据库到底在存什么”理解太简单埋下的。
一个更准确的理解方式
你可以把向量数据库里的对象理解成:
向量:负责让系统按语义相似找回来文本:负责让系统知道找到的到底是什么内容ID:负责让系统知道它是谁metadata:负责让系统知道它能不能用、该怎么用
也就是说,真正被索引的,不只是语义表示,而是一个完整知识对象。
一个常见误区
很多人会觉得:
只要 embedding 模型够强,向量存进去以后后面自然就会好。
这通常不够。
因为很多真实问题根本不发生在“向量够不够表达语义”这一层,而是发生在:
- 这条记录有没有身份
- 有没有边界
- 能不能过滤
- 能不能更新
这些问题,不是光靠向量本身能解决的。
一句话总结
向量数据库里通常存的不只是文本向量,而是一个包含向量、文本、ID、metadata 和底层检索结构的索引对象。理解这一点,后面很多关于过滤、更新、排序和治理的问题才会变得清楚。