上周一个学员跑来找我,说他搭的RAG系统"感觉什么都搜不到"。
我看了下他的架构:所有文档扔进MySQL,用户提问时 SELECT * FROM docs WHERE content LIKE '%关键词%',然后把结果拼给LLM。
"这就是你的RAG?"
"对啊,不是检索增强生成吗?"
我沉默了五秒钟。
他犯了一个所有RAG初学者都会犯的错误:用传统数据库做语义检索。
传统数据库的"死穴":它根本不认识语义
先看一个场景。用户问客服:
"我怎么退钱?"
你的知识库里有一段文档写着:
"退款流程:进入订单详情页,点击'申请退货/退款'按钮..."
在MySQL里:
SELECT * FROM docs WHEREcontentLIKE'%退钱%';
-- 结果:0条
为什么找不到?因为文档写的是"退款",用户说的是"退钱"——两个词,一个意思,但数据库把它们当成完全不同的东西。
这不是MySQL的错。传统数据库的设计哲学就是"精确匹配":
WHERE name = '张三'→ 必须一模一样LIKE '%关键词%'→ 必须包含完全相同的字符索引的本质:B+Tree,按值排序,快速定位
而AI场景的需求是"语义匹配":
用户说"退钱",要能找到"退款流程" 用户说"怎么弄",要能结合上下文理解意图 用户说"那个红色按钮在哪",要找图片里的红色按钮
传统数据库是"查字典",向量数据库是"查意思"。
向量数据库到底做了什么?
一句话:把文字变成一串数字,语义相近的文字,数字也相近。
举个例子(简化版):
"退款流程"和"退货步骤"的向量距离很近(语义相近),而"如何购买"的向量离它们很远(语义不同)。
向量数据库就是专门为这种"向量相似度搜索"优化过的存储系统:
存:高效存储百万/千万条向量 搜:用ANN(近似最近邻)算法,毫秒级找到最相近的向量 管:支持元数据过滤、分片、副本等生产特性
核心应用场景三剑客
这三个场景有一个共同点:不是找"等于",是找"像"。
Java开发者怎么上手?5分钟跑通pgvector
大多数Java团队的数据库已经是PostgreSQL了,装个扩展就能用向量检索:
Step 1:安装pgvector扩展
CREATE EXTENSION IFNOTEXISTS vector;
Step 2:建表,embedding列的类型是vector
CREATETABLE documents (
idSERIAL PRIMARY KEY,
contentTEXTNOTNULL,
embedding vector(768) -- 768维向量,跟Embedding模型输出匹配
);
Step 3:写入数据(Java + Spring Boot)
@Repository
publicclassDocumentRepository{
@Autowired
private JdbcTemplate jdbcTemplate;
publicvoidinsert(String content, float[] embedding){
String sql = "INSERT INTO documents (content, embedding) VALUES (?, ?::vector)";
// 将float[]转成pgvector格式的字符串:"[0.1,0.2,0.3,...]"
String vectorStr = Arrays.toString(embedding)
.replace("[", "[")
.replace("]", "]");
jdbcTemplate.update(sql, content, vectorStr);
}
public List<Document> search(float[] queryEmbedding, int topK){
String sql = """
SELECT id, content,
embedding <=> ?::vector AS distance
FROM documents
ORDER BY distance
LIMIT ?
""";
String vectorStr = Arrays.toString(queryEmbedding)
.replace("[", "[")
.replace("]", "]");
return jdbcTemplate.query(sql,
(rs, rowNum) -> new Document(
rs.getInt("id"),
rs.getString("content"),
rs.getDouble("distance")
),
vectorStr, topK
);
}
}
Step 4:给向量列建索引(关键!)
-- pgvector的IVFFlat索引,List数量=文档总数平方根
CREATEINDEXON documents
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);
不建索引?10万条向量搜一次要好几百毫秒。建了索引?降到个位数毫秒。
向量数据库 ≠ 替代传统数据库
很多人以为用了向量数据库就可以把MySQL扔了,这是错的。
向量数据库和传统数据库是互补关系:
WHERE id = 123 | 找到跟这句话意思最像的5条记录 | |
实际生产架构:
用户提问 → Embedding模型 → 向量检索(向量DB)→ 召回Top-K文档ID
→ 用文档ID去MySQL查原文 → 拼上下文 → LLM生成答案
向量数据库只负责"搜到最相关的文档ID",具体内容还是存在传统数据库里。
面试必问2题
Q1:为什么RAG不用MySQL的LIKE做检索?
标准答案:LIKE是字符级别的精确匹配,"退钱"找不到"退款流程","Python教程"找不到"Python入门指南"。RAG需要的是语义级别的相似度匹配,向量数据库把文字映射到高维空间,语义相近=向量距离近,这才是正确方案。
加分答案:LIKE在百万级数据量下性能极差(全表扫描),向量数据库通过HNSW/IVF等近似最近邻算法能在毫秒级完成搜索。而且LIKE不支持多语言(中文分词都搞不定),向量数据库天然跨语言。
Q2:pgvector和专用向量数据库(Milvus/Qdrant)怎么选?
标准答案:团队已经有PostgreSQL且数据量在百万级以下 → pgvector,零运维成本,SQL生态无缝。数据量千万级以上,或者需要极致性能/分布式架构 → Milvus或Qdrant。
加分答案:pgvector的IVFFlat索引在百万级数据下QPS能到1000+,大部分场景够用。而且pgvector PG17已经支持HNSW索引,差距在缩小。Qdrant的优势在于原生HNSW + 混合检索(向量+关键词),RAG场景下这两点是刚需。
🎯 踩坑清单
❌ 用MySQL的LIKE做RAG检索——字符匹配≠语义匹配,召回率不到30% ❌ 向量数据库不建索引——10万条以上必须建索引,否则搜一次几百毫秒 ❌ 把向量数据库当唯一数据源——向量DB存向量+元数据,原文还是放传统DB ❌ Embedding模型和向量数据库维度不匹配——模型输出768维,建表用了512维,数据写不进去 ❌ 不验证检索结果就直接用——向量检索返回的Top-5不一定都相关,需要Rerank
📌 下篇预告
知道了"向量数据库存的是向量",但计算机怎么判断"两个向量像不像"?余弦相似度、欧氏距离、点积——三种度量方式,选错了你的检索结果全是乱的。
第2篇:《向量距离选错了,你的RAG检索一直在跑偏》
📊 课与文对比卡
⏰ 限时福利
「向量数据库速查表」免费领:转发本文到朋友圈/技术群,截图私信公众号,赠送《向量数据库选型决策树 + HNSW调参速查表》PDF。
早鸟价倒计时:Java Agent架构师训练营早鸟价 ¥499(限30名),原价 ¥3999。
💬 互动引导
你现在用的什么做RAG检索?是pgvector、Qdrant、还是还在用MySQL的LIKE?欢迎在评论区说说,帮你看看选型对不对。
🎓 Java Agent架构师训练营 · 系统掌握RAG+Agent
如果你读到这里觉得有收获,但还想知道怎么真正把RAG做进生产系统——
我的「Java Agent架构师训练营」就是为你准备的。
这门课跟你在外面看到的不一样:
| 纯Java/Spring AI | ||
| 8篇公众号系列同款深度 | ||
| 9大设计模式 | ||
课程大纲(节选):
第1-3章:Agent基础架构(ReAct范式手写实现)
第4-5章:Tool Calling设计 + Multi-Agent协作
第6-7章:RAG完整实战(8大模块,含生产级优化)
第8-9章:Agent记忆系统 + 安全与监控
第10-14章:项目实战 + 面试冲刺(含RAG/Agent高频面试题库)
适合人群:
想转AI方向的Java工程师 面试被问RAG/Agent答不上来的 想做AI落地项目但不知道从哪下手的 已经有基础,想往生产级深度走的
价格:
早鸟价 ¥499(限30名,原价 ¥3999) 报名即送:《RAG高频面试题库》+《Agent设计模式速查表》PDF
感兴趣的话,公众号后台回复「训练营」获取详细大纲和报名方式。
夜雨聆风