向量数据库——AI 时代的语义基础设施 / Vector Databases as Semantic Infrastructure for AI
📅 创建时间:2026-05-08 🏷️ 标签:#向量数据库 #Milvus #Qdrant #pgvector #RAG #ANN #HNSW #Embedding 📚 前置知识:[[00-db-overview]] [[02-postgresql]](了解 SQL 基础) 📚 相关知识:[[03-rag-basics]](Agent 文档中的 RAG 基础)
定位速览
┌─────────────────────────────────────────────────────────────┐
│ 向量数据库在 AI 应用中的位置 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 为什么需要向量数据库? │
│ │
│ 传统数据库:找"相等"的数据 │
│ SQL: WHERE name = '张三' │
│ │
│ 向量数据库:找"相似"的数据 │
│ 语义:WHERE embedding <-> query_embedding < 0.3 │
│ │
│ 核心场景: │
│ • RAG:检索相似文档 → LLM 生成答案 │
│ • 语义搜索:找"意思相近"的文档 │
│ • 推荐系统:找"品味相似"的用户 │
│ • 图像搜索:找"视觉相似"的图片 │
│ │
└─────────────────────────────────────────────────────────────┘第1部分:向量检索基础
1.1 Embedding 向量化
┌─────────────────────────────────────────────────────────────┐
│ 什么是 Embedding │
├─────────────────────────────────────────────────────────────┤
│ │
│ Embedding = 将任意数据(文字、图片、音频)映射为向量 │
│ │
│ "苹果手机很好用" ──[Embedding Model]──▶ [0.12, -0.34, ...]
│ "iPhone 很流畅" ──[Embedding Model]──▶ [0.11, -0.33, ...]
│ "香蕉很好吃" ──[Embedding Model]──▶ [0.78, 0.92, ...] ← 远离
│ │
│ 相似度度量: │
│ │
│ 余弦相似度(最常用): │
│ cos(θ) = A·B / (|A| × |B|) │
│ 范围 [-1, 1],越接近 1 越相似 │
│ │
│ 欧氏距离: │
│ d = √(Σ(Ai - Bi)²) │
│ 越小越相似 │
│ │
│ 内积(受向量长度影响): │
│ A·B = Σ(Ai × Bi) │
│ 越大越相似 │
│ │
│ Embedding 维度: │
│ • OpenAI text-embedding-3: 1536 / 3072 维 │
│ • sentence-transformers: 384 / 768 / 1024 维 │
│ • CLIP 图片: 512 / 768 维 │
│ │
└─────────────────────────────────────────────────────────────┘1.2 ANN——近似最近邻搜索
精确的向量搜索在海量数据下不可行(O(n) 扫描),所以需要 ANN:
┌─────────────────────────────────────────────────────────────┐
│ ANN 索引算法 │
├─────────────────────────────────────────────────────────────┤
│ │
│ HNSW(Hierarchical Navigable Small World): │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Layer 2: 长边(快速定位大致区域) │ │
│ │ ○ ──────────── ○ │ │
│ │ │ │
│ │ Layer 1: 中等边 │ │
│ │ ○ ─── ○ ─── ○ ─── ○ │ │
│ │ │ │
│ │ Layer 0: 短边全覆盖(最近邻精确搜索) │ │
│ │ ○─○─○─○─○─○─○─○─○─○─○─○─○ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 搜索:从顶层入口,用长边快速跳到目标区域, │
│ 在底层精细搜索。 │
│ │
│ 特点: │
│ • 内存密集(需要把全部向量加载到内存) │
│ • QPS 高但内存占用大 │
│ • 构建慢,查询快 │
│ │
│ IVF(Inverted File Index): │
│ • 先用 K-Means 聚类成 N 个簇 │
│ • 每个向量属于某个簇(倒排索引) │
│ • 查询:先找最近的 K 个簇,再在簇内精确搜索 │
│ • 可结合 HNSW(HNSW + IVF 混合) │
│ │
│ DiskANN(磁盘索引): │
│ • 索引结构存在磁盘,内存占用大幅降低 │
│ • pgvectorscale 的 StreamingDiskANN │
│ • 适合 billion 级别的向量数据 │
│ │
└─────────────────────────────────────────────────────────────┘第2部分:Milvus——云原生向量数据库
2.1 架构
┌─────────────────────────────────────────────────────────────┐
│ Milvus 架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Milvus Client(SDK) │ │
│ │ Python / Go / Java / Node.js / REST │ │
│ └──────────────────────┬──────────────────────────────┘ │
│ │ │
│ ┌──────────────────────▼──────────────────────────────┐ │
│ │ milvus-operator (K8s) │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ Query │ │ Index │ │ Data │ │ │
│ │ │ Node │ │ Node │ │ Node │ │ │
│ │ │ (查询) │ │ (建索引) │ │ (写入) │ │
│ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │
│ │ │ │ │ │ │
│ │ ┌────▼─────────────▼─────────────▼────┐ │ │
│ │ │ Object Storage │ │ │
│ │ │ (MinIO / S3 / Azure Blob) │ │ │
│ │ └─────────────────────────────────────┘ │ │
│ │ ▲ │ │
│ │ ┌────────────────────┼────────────────────┐ │ │
│ │ │ etcd │ │ Root Coord │ │ │
│ │ │ (元数据) │ │ (协调服务) │ │ │
│ └──┴────────────────────┴────────────────────┴───────┘ │
│ │
│ 分体架构(Disaggregated): │
│ • 查询节点、索引节点、存储节点独立扩缩容 │
│ • etcd 存储元数据(Collection/Partition 路由信息) │
│ • Object Storage 存储原始向量数据 │
│ • 支持 Kafka / Pulsar 作为消息队列(解耦写入和索引) │
│ │
└─────────────────────────────────────────────────────────────┘2.2 Milvus 实战
python
# Milvus Python SDK 实战
from pymilvus import MilvusClient, model, Collection
# ================== 连接 ==================
client = MilvusClient(uri="./milvus_demo.db") # 本地文件(轻量测试)
# client = MilvusClient(uri="http://localhost:19530") # 服务器模式
# ================== 创建 Collection(表) ==================
client.create_collection(
collection_name="docs",
dimension=768, # embedding 维度
metric_type="COSINE", # 余弦相似度
# 或 "IP"(内积)/ "L2"(欧氏距离)
index_type="AUTOINDEX", # 自动选择最佳索引(HNSW/IVF)
consistency_level="Eventually", # 最终一致性(写入后立即可读)
)
# ================== 插入数据 ==================
# 1. 生成 embedding
embedding_fn = model.DefaultEmbeddingFunction()
docs = [
"PostgreSQL 是一个功能强大的开源关系型数据库",
"Redis 是高性能的内存键值数据库",
"MongoDB 是流行的文档型数据库",
"向量数据库用于语义搜索和 RAG 应用",
]
embeddings = embedding_fn.encode_documents(docs)
# embeddings.shape = (4, 768)
# 2. 插入
ids = client.insert(
collection_name="docs",
data=[
{"id": i+1, "text": docs[i], "vector": embeddings[i].tolist()}
for i in range(len(docs))
]
)
print(f"插入 {len(ids)} 条,IDs: {ids}")
# 3. 建索引(插入后需要建索引才能高效查询)
client.create_index(
collection_name="docs",
field_name="vector",
index_type="HNSW",
index_params={"M": 16, "efConstruction": 200}
)
# ================== 搜索 ==================
query = "请介绍向量数据库"
query_embedding = embedding_fn.encode_queries([query])
results = client.search(
collection_name="docs",
data=query_embedding,
limit=2, # 返回 Top-K
output_fields=["text", "id"],
)
for result in results:
print(f"ID: {result['id']}, Score: {result['distance']:.4f}")
print(f"Text: {result['entity']['text']}")
print()
# ================== 混合搜索(向量 + 过滤) ==================
results = client.search(
collection_name="docs",
data=query_embedding,
filter="id > 1", # 只搜索 id > 1 的文档
limit=3,
)
# ================== 删除 & 释放 ==================
client.drop(collection_name="docs")第3部分:Qdrant——Rust 实现的高性能向量库
┌─────────────────────────────────────────────────────────────┐
│ Qdrant 核心特点 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Rust 实现,性能极高,内存占用低 │
│ │
│ 核心能力: │
│ • HNSW + IVF 混合索引 │
│ • 二值量化(Binary Quantization)—— 内存减少 32 倍 │
│ • 过滤搜索(metadata filtering) │
│ • 原生 gRPC API + REST API │
│ • ONNX 模型集成(端到端向量处理) │
│ │
│ Qdrant vs Milvus: │
│ • Milvus: 功能更全,K8s 生态,适合大规模生产部署 │
│ • Qdrant: 轻量高性能,适合中小规模,本地部署 │
│ │
└─────────────────────────────────────────────────────────────┘python
# Qdrant Python SDK
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, Filter
client = QdrantClient("localhost", port=6333)
# 创建 collection
client.create_collection(
collection_name="products",
vectors_config=VectorParams(size=768, distance=Distance.COSINE),
)
# 插入
from qdrant_client.models import PointStruct
client.upsert(
collection_name="products",
points=[
PointStruct(id=1, vector=[...], payload={"name": "键盘", "category": "外设"}),
PointStruct(id=2, vector=[...], payload={"name": "鼠标", "category": "外设"}),
PointStruct(id=3, vector=[...], payload={"name": "显示器", "category": "配件"}),
]
)
# 搜索 + 过滤
results = client.search(
collection_name="products",
query_vector=[...], # query embedding
query_filter=Filter(
must=[{"key": "category", "match": {"value": "外设"}}]
),
limit=3,
)第4部分:PostgreSQL 原生方案(pgvector)
┌─────────────────────────────────────────────────────────────┐
│ pgvector vs 专用向量数据库 │
├─────────────────────────────────────────────────────────────┤
│ │
│ pgvector 的优势: │
│ ✅ 一个数据库搞定所有(OLTP + 向量检索) │
│ ✅ 不需要额外的服务,运维简单 │
│ ✅ 向量 + 结构化数据一起索引(JOIN + 语义搜索) │
│ ✅ LobeChat 就是这么做的 │
│ │
│ pgvector 的局限: │
│ ❌ 单机瓶颈,水平扩展需要 TiDB / Citus │
│ ❌ 亿级向量以上性能不如专用向量数据库 │
│ ❌ 索引构建慢(百万级向量可能需要数小时) │
│ │
│ 选型建议: │
│ • <100 万向量 → pgvector(最简单) │
│ • 100万-1亿向量 → Qdrant / Milvus(专用方案) │
│ • >1 亿向量 → Milvus + DiskANN / pgvectorscale │
│ │
└─────────────────────────────────────────────────────────────┘第5部分:向量数据库选型决策树
┌─────────────────────────────────────────────────────────────┐
│ 向量数据库选型决策树 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 数据规模是多少? │
│ ├── < 10 万向量 │
│ │ └── pgvector(SQL 直接查询,最简单) │
│ │ │
│ ├── 10 万 - 100 万向量 │
│ │ ├── pgvector + HNSW 索引 │
│ │ ├── Qdrant(轻量高性能) │
│ │ └── Milvus(功能全) │
│ │ │
│ ├── 100 万 - 1 亿向量 │
│ │ ├── Milvus(生产级 K8s 部署) │
│ │ └── Qdrant(独立部署) │
│ │ │
│ └── > 1 亿向量 │
│ ├── Milvus + DiskANN 索引 │
│ └── pgvectorscale + StreamingDiskANN(PostgreSQL 原生) │
│ │
│ 需要哪些能力? │
│ ├── 只要向量检索 → pgvector / Qdrant / Milvus 均可 │
│ ├── 需要 SQL JOIN → pgvector(PostgreSQL 原生) │
│ ├── 需要云服务 → Pinecone / Azure AI Search / Weaviate │
│ ├── 需要图片向量 → CLIP + Milvus / Qdrant │
│ └── 需要多模态 → Milvus(多模态支持最好) │
│ │
└─────────────────────────────────────────────────────────────┘学习状态:🟡 开始学习