你按老习惯建了张表,把模型返回的向量塞进一个字段,写进去没问题,一查就懵:这条 SQL 该怎么写?为什么换个说法就查不到?其实不是你不会写 SQL,是两类库解决的根本不是同一道题。这篇不堆概念,只讲两者的存储结构、检索方式差在哪,以及在什么条件下该用哪个、什么时候得两个一起上。
你按老习惯建了张表,把模型返回的向量塞进一个字段,写进去没问题,一查就懵:这条 SQL 该怎么写?为什么换个说法就查不到?其实不是你不会写 SQL,是两类库解决的根本不是同一道题。这篇不堆概念,只讲两者的存储结构、检索方式差在哪,以及在什么条件下该用哪个、什么时候得两个一起上。
给初学后端的建议是:先把「存什么」和「怎么查」这两件事分开想,很多选型纠结会自己消失。下面按存储、查询、建模、选型、自查五个角度拆,每段都给可执行动作,最后附一份排查顺序,出问题时照着走。
先看存的东西:行与列,还是坐标与距离
传统库存的是结构化字段,一行一条记录,值之间可以精确比较、排序、求和;向量库存的是一条记录对应一串浮点数,本身没有大小先后之分,单独看某个维度没意义。传统库靠主键、唯一索引定位「是哪一条」;向量库靠这串数字在空间里的位置定位「和谁像」,相似度是算出来的,不是比出来的。
- 结构化字段
- 有明确类型和业务含义的值,可做等值、范围、聚合等精确操作
- 向量
- 一长串浮点数,表示一段内容的语义坐标,单看某一维没有业务含义
- 相似度
- 衡量两个向量在多维空间里离得多近,由距离公式算出来,不是字段比较出来的
再看待查询方式:条件过滤 vs 最近邻
传统查询是确定性的:条件写对了结果就固定,能走索引把扫描量压下来;向量查询是近似的,默认返回最近的若干条,同一句问话在不同库、不同参数下结果可能不完全一样。所以向量检索要配 Top-K 和相似度阈值这类参数,参数调不好就是「明明有答案却召不回」或「召回的都不相关」。
- 把关键词直接拿去做向量查询是常见误区:向量匹配的是语义相近,不是字面相等,专有名词、编号、人名往往还得靠传统检索兜底
- 向量查询前先想清候选集大小,能先用元数据把范围缩小就别让近邻算法在全集上算
- 参数不要拍脑袋定,拿一批真实问题跑一轮,看命中情况再调,数字到站内页面对照当时的资料
| 对比项 | 传统数据库 | 向量数据库 |
|---|---|---|
| 存储单元 | 结构化字段,一行一记录 | 一串浮点数,一条记录一个坐标 |
| 定位方式 | 主键与索引,「是哪一条」 | 空间距离,「和谁像」 |
| 查询结果 | 确定性,条件一样结果一样 | 近似性,受参数与索引影响 |
| 典型操作 | 等值、范围、排序、聚合 | 近邻查找、相似度排序 |
| 结果可读性 | 字段值直接可读 | 向量本身不可读,要看原始文本与元数据 |
站内 /stacks/vector-dbs 可以看各类向量库的定位,/embeddings 是嵌入模型的入口,选型前建议先去核对当时的资料,别照着记忆里的印象挑。
建表和建索引的思路完全不是一套
传统库先定 schema 再写数据,改字段要走迁移;向量库通常先定向量维度,维度必须和嵌入模型输出的维度一致,换了嵌入模型基本等于重建数据。传统索引为了加速等值、范围、排序;向量索引为了加速近邻查找,属于用一点精度换速度的取舍,建索引的时机和参数会直接影响召回表现。
- 定维度确认要用的嵌入模型输出多少维,集合维度就按它建;写完记得回读一条,确认维度没被悄悄截断或补齐
- 存元数据向量之外把原始文本、来源、时间、权限这些字段一起存,越全越好,后面过滤和排查都靠它
- 建索引先写一批数据再建,观察召回和响应变化;索引不是越多越好,按查询模式选一种主用即可
- 做前置过滤查询时先用元数据把候选范围缩小,再做近邻匹配,能大幅减少无效计算
向量库的建索引不是「加个索引就快了」,而是拿召回精度换查询速度的一笔交易。
什么时候用哪个,什么时候必须一起用
纯传统库够用的场景:订单、账务、用户资料、日志明细这类要求精确和事务的数据;纯向量库适合的场景:语义搜索、推荐、去重、RAG 召回。混合是最常见形态:传统库管事实与权限,向量库管相似度,查询时先用元数据把范围缩小,再做近邻匹配,最后按业务规则排序。
| 场景 | 先用哪个 | 理由 |
|---|---|---|
| 账务、订单、权限 | 传统库 | 要求精确、可事务、可审计 |
| 语义搜索、推荐、去重 | 向量库 | 匹配的是意思相近,不是字面相等 |
| 知识库问答召回 | 两者配合 | 向量找候选,传统库补精确条件和权限过滤 |
| 候选集只有几百条 | 现有库先顶着 | 数据量小的时候加向量库多半是过度设计 |
不适用的条件也要说清:数据量很小、候选集只有几百条时,加一套向量库往往是过度设计,先在现有库里暴力算相似度就行;反过来,如果业务完全不需要「像不像」,上向量库只会增加运维负担。迁移前先想清维度、重建成本和一致性策略,否则后期换嵌入模型会很痛。
落地前的自查清单与排查顺序
- 先定三件事要匹配的是语义还是字面、需要精确结果还是可接受近似、数据规模和更新频率各是多少,三个答案决定选型
- 接入顺序准备查询语句 → 生成向量 → 建集合与索引 → 写入并回读验证 → 用真实问题跑一轮召回,看命中率再调参数
- 查不到结果时按序排嵌入模型是否和写入时一致 → 维度是否对得上 → 元数据过滤条件是否把候选全排除了 → Top-K 和阈值是否过严 → 索引是否还没建好
- 看原始数据向量本身没有可读性,出问题先看原始文本和元数据,别盯着那串数字猜
常见问题
传统数据库加一个向量字段不就行了吗,为什么还要单独的向量库?
小数据量确实可以这么干,尤其候选集只有几千条、能接受每次全量算相似度时。但数据量一上来,逐条算距离的成本会随条数线性上涨,而且传统索引帮不上近邻查询的忙。这时候专门的向量索引才有意义。判断点就一个:候选集规模和查询频率,两者都小就别折腾。
向量库能不能代替传统数据库?
不能。向量库擅长相似度,不擅长事务、精确约束、多表关联和强一致。真实系统里通常是两边并存:事实、权限、金额这类必须准确的数据放传统库,向量只作为「找候选」的一层。把账务或权限判断交给相似度结果,迟早会出事。
换了嵌入模型,原来的数据还能用吗?
基本不能直接混用。不同嵌入模型输出的维度甚至语义空间都不一样,用一边的模型编码查询、另一边编码入库数据,算出来的相似度没有意义。要么全部重新编码,要么给新旧数据分开存、分别检索。所以上线前就要把嵌入模型的更换成本算进去。