477 字
1 分钟
向量数据库深度解析
一、向量数据库概述
1.1 为什么需要向量数据库
flowchart TB
subgraph Traditional[" 传统数据库"]
direction TB
T1[" 结构化数据<br/>表格/关系"]
T2[" 精确匹配<br/>SQL = WHERE"]
T3[" 固定 Schema<br/>预定义字段"]
T4[" 局限性<br/>无法理解语义"]
end
subgraph Vector[" 向量数据库"]
direction TB
V1[" 高维向量<br/>Embedding"]
V2[" 相似性搜索<br/>KNN/ANN"]
V3[" 灵活 Schema<br/>动态元数据"]
V4[" 优势<br/>语义理解能力"]
end
Traditional -->|"演进"| Vector
style Traditional fill:#ffe6e6,stroke:#ff6666
style Vector fill:#e6ffe6,stroke:#66cc66
graph TB
subgraph "传统数据库局限"
A["结构化数据"]
B["精确匹配"]
C["SQL 查询"]
end
subgraph "向量数据库优势"
D["非结构化数据"]
E["相似性搜索"]
F["语义理解"]
end
A --> D
B --> E
C --> F
| 维度 | 传统数据库 | 向量数据库 |
|---|---|---|
| 数据类型 | 结构化 | 高维向量 |
| 查询方式 | 精确匹配 | 相似性搜索 |
| 应用场景 | 业务数据 | AI 语义检索 |
| 召回率 | 100% | 可调节(召回 vs 速度) |
1.2 核心应用场景
flowchart TB
subgraph ImageSearch[" 图像检索"]
direction LR
I1["用户上传图片"] --> I2["CNN 提取特征"]
I2 --> I3["特征向量"]
I3 --> I4["向量检索"]
I4 --> I5["相似图片"]
end
subgraph VoiceSearch[" 语音搜索"]
direction LR
V1["语音输入"] --> V2["ASR 转文本"]
V2 --> V3["Embedding"]
V3 --> V4["向量检索"]
V4 --> V5["搜索结果"]
end
subgraph RAGSearch[" RAG 知识库"]
direction LR
R1["用户问题"] --> R2["问题向量化"]
R2 --> R3["知识库检索"]
R3 --> R4["相关文档"]
R4 --> R5["LLM 生成答案"]
end
style ImageSearch fill:#e3f2fd
style VoiceSearch fill:#fff8e1
style RAGSearch fill:#e8f5e9
graph LR
A["用户上传图片"] --> B["提取特征向量"]
B --> C["向量数据库检索"]
C --> D["返回相似图片"]
E["语音输入"] --> F["ASR 转文本"]
F --> G["Embedding 向量化"]
G --> H["向量检索"]
H --> I["语音搜索结果"]
二、主流向量数据库对比
2.0 架构对比概览
flowchart TB
subgraph MilvusArch[" Milvus 架构"]
direction TB
M1["SDK/API"] --> M2["Proxy"]
M2 --> M3["Coordinator<br/>协调器集群"]
M3 --> M4["Worker Nodes<br/>查询/索引/数据节点"]
M4 --> M5["Object Storage<br/>MinIO/S3"]
style MilvusArch fill:#e3f2fd
end
subgraph QdrantArch[" Qdrant 架构"]
direction TB
Q1["REST/gRPC API"] --> Q2["Collection Manager"]
Q2 --> Q3["HNSW Index<br/>Rust 实现"]
Q3 --> Q4["Storage<br/>RocksDB/内存"]
style QdrantArch fill:#fff8e1
end
subgraph PineconeArch[" Pinecone 架构"]
direction TB
P1["Client SDK"] --> P2["Pinecone Cloud"]
P2 --> P3["Managed Index<br/>全托管"]
P3 --> P4["Auto Scaling<br/>自动扩缩"]
style PineconeArch fill:#e8f5e9
end
subgraph ChromaArch[" Chroma 架构"]
direction TB
C1["Python SDK"] --> C2["DuckDB<br/>嵌入式存储"]
C2 --> C3["HNSW Index<br/>hnswlib"]
style ChromaArch fill:#fce4ec
end
2.1 功能对比
| 特性 | Milvus | Qdrant | Pinecone | Chroma | Weaviate |
|---|---|---|---|---|---|
| 部署方式 | 自托管 | 自托管 | 云服务 | 嵌入式 | 自托管 |
| 索引算法 | HNSW/IVF | HNSW | HNSW | HNSW | HNSW |
| 混合搜索 | |||||
| 全文搜索 | |||||
| 分布式 | |||||
| 元数据过滤 | |||||
| Python SDK | |||||
| Rust 核心 |
2.2 性能对比
# 向量数据库性能基准测试框架class VectorDBBenchmark: def __init__(self, db_type: str): self.db_type = db_type
def benchmark(self, dataset_size: int = 1000000): """QPS 与召回率基准测试""" results = { "milvus": {"qps": 5000, "recall": 0.95, "p99_latency": "15ms"}, "qdrant": {"qps": 8000, "recall": 0.97, "p99_latency": "8ms"}, "weaviate": {"qps": 3000, "recall": 0.93, "p99_latency": "20ms"}, } return results.get(self.db_type, {})三、索引算法详解
3.1 HNSW 算法原理
flowchart TB
subgraph L2[" Layer 2 - 快速跳转"]
direction LR
A2["A"] --- B2["B"]
B2 --- C2["C"]
end
subgraph L1[" Layer 1 - 中间过渡"]
direction LR
A1["A"] --- B1["D"]
B1 --- C1["E"]
D1["D"] --- E1["F"]
end
subgraph L0[" Layer 0 - 精确搜索"]
direction LR
A0["A"] --- B0["G"]
B0 --- C0["H"]
C0 --- D0["I"]
D0 --- E0["J"]
E0 --- F0["K"]
F0 --- G0["L"]
end
L2 -.->|"下沉"| L1
L1 -.->|"下沉"| L0
Search[" 搜索过程:<br/>顶层入口 → 贪心搜索 → 逐层下沉"]
style L2 fill:#e3f2fd,stroke:#1976d2
style L1 fill:#fff8e1,stroke:#f57c00
style L0 fill:#e8f5e9,stroke:#388e3c
style Search fill:#f3e5f5
graph TB
subgraph "Layer 2"
A2["Node A"]
B2["Node B"]
C2["Node C"]
end
subgraph "Layer 1"
A1["Node A"] --> B1["Node D"]
B1 --> C1["Node E"]
D1 --> E1["Node F"]
end
subgraph "Layer 0"
A0["Node A"] --> B0["Node G"]
B0 --> C0["Node H"]
C0 --> D0["Node I"]
D0 --> E0["Node J"]
end
# HNSW 搜索算法伪代码class HNSWIndex: def __init__(self, m: int = 16, ef_construction: int = 200): self.m = m # 每一层最多连接数 self.ef_construction = ef_construction # 构建时动态列表大小
def search(self, query_vector: list, ef: int = 100): """ 搜索过程: 1. 从顶层开始,找到最近邻 2. 逐层向下,更新候选集 3. 最终在底层返回精确结果 """ candidates = self._search_layer_0(query_vector, ef)
# 层间跳转 for layer in range(self.max_layer, 0, -1): candidates = self._expand_neighbors( candidates, query_vector, ef=ef_construction )
return candidates[:ef]3.2 IVF 倒排索引
# IVF 索引原理class IVFIndex: def __init__(self, nlist: int = 1024): self.nlist = nlist # 聚类中心数量
def build(self, vectors: list): """1. k-means 聚类建立倒排表""" self.centers, assignments = kmeans(vectors, self.nlist)
# 2. 建立倒排表 self.inverted_index = {} for i, cluster_id in enumerate(assignments): if cluster_id not in self.inverted_index: self.inverted_index[cluster_id] = [] self.inverted_index[cluster_id].append(i)
def search(self, query: list, nprobe: int = 10): """搜索时只扫描 nprobe 个聚类中心""" # 1. 找到最近的 nprobe 个聚类中心 nearest_centers = self._find_nearest_centers( query, nprobe )
# 2. 在这些聚类中暴力搜索 candidates = [] for center_id in nearest_centers: candidates.extend(self.inverted_index[center_id])
return self._brute_force_search(query, candidates)3.3 PQ 量化压缩
# Product Quantization 原理class PQIndex: def __init__(self, m: int = 8, ks: int = 256): """ m: 分段数(通常 8-16) ks: 每个子空间码本大小(通常 256) """ self.m = m self.ks = ks self.codebooks = []
def train(self, vectors: list): """训练码书""" dim = len(vectors[0]) sub_dim = dim // self.m
for i in range(self.m): # 对第 i 个子空间进行 k-means sub_vectors = vectors[:, i*sub_dim:(i+1)*sub_dim] codebook = kmeans(sub_vectors, self.ks) self.codebooks.append(codebook)
def encode(self, vector: list): """编码:每个子空间找最近码字""" codes = [] for i, codebook in enumerate(self.codebooks): sub_vec = vector[i*self.sub_dim:(i+1)*self.sub_dim] code = np.argmin(np.linalg.norm(codebook - sub_vec, axis=1)) codes.append(code) return codes
def search(self, query: list, candidates: list): """距离计算使用查表而非暴力计算""" # 预计算查询向量各子空间到各码字距离 distance_table = self._build_distance_table(query)
# 查表累加获取最终距离 for vector_id in candidates: total_dist = sum( distance_table[i][self.codes[vector_id][i]] for i in range(self.m) )四、Milvus 深度解析
4.0 Milvus 架构详解
flowchart TB
subgraph Client[" 客户端"]
SDK["SDK<br/>Python/Go/Java/Node"]
end
subgraph Access[" 接入层"]
direction LR
P1["Proxy 1"]
P2["Proxy 2"]
P3["Proxy N"]
P1 --- P2 --- P3
end
subgraph Coordinator[" 协调层"]
direction TB
RC["Root Coordinator<br/>元数据管理"]
QC["Query Coordinator<br/>查询调度"]
DC["Data Coordinator<br/>数据管理"]
IC["Index Coordinator<br/>索引管理"]
end
subgraph Worker[" 工作节点"]
direction TB
QN["Query Node<br/>查询执行"]
DN["Data Node<br/>数据写入"]
IN["Index Node<br/>索引构建"]
end
subgraph Storage[" 存储层"]
direction TB
MS["Message Storage<br/>Kafka/Pulsar"]
OS["Object Storage<br/>MinIO/S3"]
MD["Meta Storage<br/>etcd"]
end
SDK --> Access
Access --> Coordinator
Coordinator --> Worker
Worker --> Storage
style Client fill:#e8eaf6
style Access fill:#e3f2fd
style Coordinator fill:#fff8e1
style Worker fill:#f3e5f5
style Storage fill:#e8f5e9
4.1 架构设计
graph TB
subgraph "接入层"
A["SDK"] --> B["Proxy"]
B --> C["RBAC"]
end
subgraph "协调层"
C --> D["Root Coordinator"]
C --> E["Query Coordinator"]
C --> F["Index Coordinator"]
end
subgraph "执行层"
D --> G["Query Node"]
E --> H["Index Node"]
F --> I["Data Node"]
end
subgraph "存储层"
G --> J["Object Storage"]
H --> J
I --> J
J --> K["MinIO/S3"]
end
4.2 Milvus 使用示例
from pymilvus import connections, Collection, FieldSchema, CollectionSchema, DataType
# 1. 连接 Milvusconnections.connect(host='localhost', port='19530')
# 2. 定义 Schemafields = [ FieldSchema(name="id", dtype=DataType.INT64, is_primary=True), FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=768), FieldSchema(name="category", dtype=DataType.VARCHAR, max_length=100),]schema = CollectionSchema(fields=fields, description="向量检索集合")
# 3. 创建 Collectioncollection = Collection(name="documents", schema=schema)
# 4. 创建索引index_params = { "index_type": "HNSW", "params": {"M": 16, "efConstruction": 200}, "metric_type": "L2"}collection.create_index(field_name="embedding", index_params=index_params)
# 5. 插入数据entities = [ [1, 2, 3], # id [[0.1]*768, [0.2]*768], # embeddings ["科技", "娱乐"] # category]collection.insert(entities)
# 6. 搜索search_params = {"metric_type": "L2", "params": {"ef": 100}}results = collection.search( data=[[0.1]*768], anns_field="embedding", param=search_params, limit=10, expr="category == '科技'")五、Qdrant 深度解析
5.0 Qdrant 架构详解
flowchart TB
subgraph Client[" 客户端"]
direction LR
C1["Python SDK"]
C2["Rust SDK"]
C3["REST API"]
end
subgraph API[" API 层"]
direction TB
REST["REST API<br/>HTTP/gRPC"]
end
subgraph Core[" 核心引擎 - Rust"]
direction TB
CM["Collection Manager<br/>集合管理"]
SEG["Segment<br/>数据分片"]
HNSW["HNSW Index<br/>高性能图索引"]
QC["Quantization<br/>向量量化"]
end
subgraph Storage[" 存储层"]
direction TB
MEM["Memory<br/>热数据"]
ROCK["RocksDB<br/>持久化存储"]
SNAP["Snapshot<br/>备份恢复"]
end
Client --> API
API --> Core
Core --> Storage
style Client fill:#e8eaf6
style API fill:#e3f2fd
style Core fill:#fff8e1
style Storage fill:#e8f5e9
flowchart LR
subgraph QdrantFeatures[" Qdrant 特色"]
direction TB
F1[" Rust 实现<br/>内存安全+高性能"]
F2[" 单二进制部署<br/>运维简单"]
F3[" 原生过滤<br/>元数据+向量联合"]
F4[" 动态负载<br/>自动均衡"]
end
style QdrantFeatures fill:#f3e5f5
5.1 核心特性
# Qdrant 配置文件storage: # 存储路径 storage_path: /qdrant/storage
# HNSW 参数 hnsw_index: m: 16 # 连接数 ef_construct: 100 # 构建时搜索深度 full_scan_threshold: 10000 # 小于此规模用暴力搜索
# 量化配置 quantization: binary: false product: compression: 8 # 压缩比5.2 Qdrant 使用示例
from qdrant_client import QdrantClientfrom qdrant_client.models import Distance, VectorParams, Filter
client = QdrantClient(host="localhost", port=6333)
# 1. 创建 Collectionclient.create_collection( collection_name="articles", vectors_config=VectorParams(size=768, distance=Distance.COSINE))
# 2. 插入向量client.upsert( collection_name="articles", points=[ { "id": 1, "vector": [0.1]*768, "payload": {"title": "Python 教程", "category": "编程"} }, ])
# 3. 搜索results = client.search( collection_name="articles", query_vector=[0.1]*768, query_filter=Filter( must=[ {"key": "category", "match": {"value": "编程"}} ] ), limit=5)
# 4. 范围搜索(按分数过滤)results = client.search( collection_name="articles", query_vector=[0.1]*768, score_threshold=0.8, # 只返回相似度 > 0.8 的结果 limit=10)六、选型指南
6.0 四大数据库对比
flowchart TB
subgraph Milvus[" Milvus"]
direction TB
M_Pros["分布式架构<br/>超大规模支持<br/>功能最全面"]
M_Cons["部署复杂<br/>运维成本高"]
M_Use[" 适用: 大型企业<br/>亿级向量"]
end
subgraph Qdrant[" Qdrant"]
direction TB
Q_Pros["性能优异<br/>部署简单<br/>原生过滤"]
Q_Cons["社区较小<br/>云服务起步"]
Q_Use[" 适用: 高性能需求<br/>百万-千万级"]
end
subgraph Pinecone[" Pinecone"]
direction TB
P_Pros["全托管<br/>零运维<br/>快速上手"]
P_Cons["成本较高<br/>数据主权问题"]
P_Use[" 适用: 快速迭代<br/>SaaS 产品"]
end
subgraph Chroma[" Chroma"]
direction TB
C_Pros["嵌入式<br/>一行代码启动<br/>开源免费"]
C_Cons["不支持分布式<br/>性能有限"]
C_Use[" 适用: 原型开发<br/>小规模场景"]
end
style Milvus fill:#e3f2fd
style Qdrant fill:#fff8e1
style Pinecone fill:#e8f5e9
style Chroma fill:#fce4ec
6.1 场景化选型
| 场景 | 推荐方案 | 原因 |
|---|---|---|
| 快速原型 | Chroma | 嵌入式,一行代码启动 |
| 生产环境自托管 | Qdrant/Milvus | 性能好,功能完整 |
| 云原生 SaaS | Pinecone | 全托管,免运维 |
| 需要混合检索 | Qdrant/Weaviate | 支持向量+全文联合检索 |
| 超大规模(>1亿) | Milvus | 分布式架构成熟 |
| 低延迟实时系统 | Qdrant | Rust 实现,性能优异 |
6.2 性能优化建议
# 向量数据库性能优化清单optimization_checklist = { "索引参数": { "HNSW_M": "16-64,越大越精确但越慢", "HNSW_ef": "100-500,搜索时动态调整", "HNSW_ef_construction": "200-400,构建时精度" }, "量化策略": { "binary": "内存减半,速度加倍,精度略降", "product": "内存压缩 4-16 倍,精度可调", "scalar": "不影响精度,略微提升速度" }, "硬件配置": { "内存": "能装下全部向量 + 索引 > 80% 命中率", "CPU": "影响索引构建速度,HNSW 构建 CPU 密集", "SSD": "向量量大时必须,内存不足时代替" }}七、总结
mindmap
root((向量数据库))
Milvus
分布式架构
云原生设计
功能最全
适用大规模
Qdrant
Rust 高性能
单机部署简单
原生过滤强大
适用高并发
Pinecone
全托管 SaaS
零运维
快速上线
适用初创
Chroma
嵌入式轻量
开发便捷
原型首选
适用小规模
选型因素
数据规模
性能需求
运维能力
成本预算
| 数据库 | 优势 | 适用场景 |
|---|---|---|
| Milvus | 功能全面,分布式成熟 | 超大规模生产环境 |
| Qdrant | 性能优异,Rust 实现 | 高并发低延迟需求 |
| Pinecone | 全托管,运维简单 | 云原生,快速上线 |
| Chroma | 轻量级,原型快速 | 小规模,本地开发 |
| Weaviate | 混合搜索,原生 GraphQL | 知识图谱+向量融合 |
flowchart TB
Start[" 开始选型"] --> Q1{"数据规模?"}
Q1 -->|"≤ 100 万"| Q2{"是否需要<br/>全文搜索?"}
Q1 -->|"100 万 - 1 亿"| Q3{"性能优先<br/>还是功能优先?"}
Q1 -->|"≥ 1 亿"| Milvus[" Milvus<br/>分布式架构"]
Q2 -->|"是"| Weaviate[" Weaviate"]
Q2 -->|"否"| Q4{"开发阶段?"}
Q4 -->|"原型/开发"| Chroma[" Chroma"]
Q4 -->|"生产环境"| Qdrant[" Qdrant"]
Q3 -->|"性能优先"| Qdrant
Q3 -->|"功能优先"| Milvus
Q5{"运维能力?"} -->|"强"| Qdrant
Q5 -->|"弱"| Pinecone[" Pinecone"]
style Start fill:#e8eaf6
style Milvus fill:#e3f2fd
style Qdrant fill:#fff8e1
style Pinecone fill:#e8f5e9
style Chroma fill:#fce4ec
```
支持与分享
如果这篇文章对你有帮助,欢迎支持作者或分享给更多人
部分信息可能已经过时
相关文章 智能推荐
1
RAG 优化策略深度解析
AI 深入解析 RAG 检索增强生成的优化策略——Query 改写、混合检索、重排序、Context 压缩与引用追踪。
2
Agent 记忆系统:短期、长期与向量数据库
AI AI Agent 记忆机制详解——短期记忆、长期记忆、情景记忆的设计与实现,以及记忆的检索、压缩与遗忘策略。
3
Embedding 与向量搜索原理
AI 深入解析文本 Embedding 模型与向量检索——模型原理、索引结构、相似度计算与工程实践。
4
让AI拥有知识:RAG检索增强生成详解
AI 让AI拥有知识——RAG检索增强生成详解
5
AI 工程化实践
AI AI 工程化全景导览——从提示词工程到多模态系统,梳理大模型落地的核心工程能力与知识体系






