向量数据库对比
摘要
向量数据库是现代AI应用的核心基础设施,负责存储和检索高维向量数据。本文档对Pinecone、Milvus、Chroma、Weaviate、Qdrant和pgvector六大主流向量数据库进行深度对比,从架构设计、索引算法、性能表现、扩展性、成本等多维度分析,为技术选型提供系统性的决策依据。
关键词速查表
| 关键词 | 说明 |
|---|---|
| ANN | Approximate Nearest Neighbor,近似最近邻搜索 |
| HNSW | Hierarchical Navigable Small World,分层可导航小世界图 |
| IVF | Inverted File Index,倒排文件索引 |
| PQ | Product Quantization,乘积量化 |
| 距离度量 | 余弦、欧氏、内积等向量距离计算方式 |
| 混合搜索 | 结合向量检索和关键词检索 |
| 元数据过滤 | 支持在向量检索基础上进行属性过滤 |
| 分片 | 数据在多个节点间的分布策略 |
| 副本 | 数据的多份拷贝用于容错和高可用 |
| 近似精度 | 召回率与性能的权衡指标 |
一、向量数据库核心概念
1.1 向量数据库的定位
向量数据库专为高维向量数据的存储和检索设计,是RAG、知识图谱、语义搜索、推荐系统等AI应用的关键基础设施。与传统关系型数据库不同,向量数据库的核心能力不是精确匹配,而是近似最近邻(ANN)搜索——在可接受的召回率损失下,快速找到与查询向量最相似的Top-K个向量。
这种能力源于深度学习模型将非结构化数据(文本、图像、音频)转化为高维向量表示。一个典型的768维向量代表一段文本的语义内容,向量间的距离反映了语义相似度。向量数据库通过优化的索引结构和距离算法,实现了毫秒级的语义检索能力。
1.2 核心索引算法
向量索引算法决定了检索的速度和精度权衡。主流算法各有特点:
HNSW(Hierarchical Navigable Small World) 是当前最流行的向量索引算法,采用分层图结构。顶层是稀疏的快速导航层,底层是密集的精确搜索层。搜索时从顶层入口点开始,逐层向下逼近,最终在底层找到最近邻。HNSW的优势在于查询速度快、精度高,但内存占用较大。
IVF(Inverted File Index) 将向量空间划分为多个聚类,搜索时只在相关聚类中进行。这种方法适合处理超大规模数据,但精度略逊于HNSW。
PQ(Product Quantization) 将高维向量压缩为低维码本表示,大幅降低存储成本,适合对内存敏感的场景。
"""
索引算法对比示意
实际使用时,各向量数据库已内置这些算法的实现
"""
index_algorithms = {
"HNSW": {
"query_speed": "极快",
"build_speed": "中等",
"memory_usage": "高",
"recall": "高 (95%+)",
"best_for": "追求低延迟场景"
},
"IVF": {
"query_speed": "快",
"build_speed": "快",
"memory_usage": "中等",
"recall": "中等 (85-95%)",
"best_for": "超大规模数据"
},
"PQ": {
"query_speed": "中等",
"build_speed": "中等",
"memory_usage": "低",
"recall": "中等偏低",
"best_for": "内存受限场景"
},
"HNSW + PQ": {
"query_speed": "快",
"build_speed": "慢",
"memory_usage": "可调",
"recall": "高",
"best_for": "大规模高精度"
}
}1.3 距离度量
向量数据库支持多种距离度量,选择取决于向量生成模型和业务需求:
| 距离类型 | 计算公式 | 适用场景 |
|---|---|---|
| 余弦相似度 | cos(θ) = A·B/(|A||B|) | 文本Embedding、文本相似度 |
| L2欧氏距离 | √(Σ(Ai-Bi)²) | 图像向量、通用场景 |
| 点积/内积 | A·B | 归一化向量、需要注意力权重 |
| 曼哈顿距离 | Σ|Ai-Bi| | 特定领域 |
二、Pinecone详解
2.1 产品定位
Pinecone是云原生的向量数据库服务,以”零运维、全托管”为核心理念。作为serverless架构的代表性产品,Pinecone让用户专注于应用开发,无需关心基础设施的运维工作。其定价基于实际使用量,按索引存储和向量查询计费。
2.2 核心架构
Pinecone采用分布式云原生架构,数据自动分片和复制,确保高可用和低延迟。服务端自动处理索引构建、查询优化和资源扩缩容。
"""
Pinecone Python SDK使用示例
安装: pip install pinecone-client
"""
from pinecone import Pinecone, ServerlessSpec
import time
# 初始化
pc = Pinecone(api_key="YOUR_API_KEY")
# 创建索引
index_name = "production-knowledge-base"
# 检查是否已存在
if index_name not in [idx.name for idx in pc.list_indexes()]:
pc.create_index(
name=index_name,
dimension=1536, # OpenAI ada-002 dimension
metric="cosine", # 余弦相似度
spec=ServerlessSpec(
cloud="aws",
region="us-east-1"
)
)
# 等待索引就绪
while not pc.describe_index(index_name).status.ready:
time.sleep(1)
# 连接索引
index = pc.Index(index_name)
# 插入向量
vectors = [
{"id": "doc-001", "values": [0.1] * 1536, "metadata": {"text": "文档内容", "category": "技术"}},
{"id": "doc-002", "values": [0.2] * 1536, "metadata": {"text": "另一文档", "category": "产品"}},
]
index.upsert(vectors)
# 查询
query_vector = [0.15] * 1536
results = index.query(
vector=query_vector,
top_k=10,
include_metadata=True,
filter={"category": {"$eq": "技术"}} # 元数据过滤
)
for match in results.matches:
print(f"ID: {match.id}, Score: {match.score}, Text: {match.metadata['text']}")
# 批量操作
batch_results = index.query(
vector=[query_vector] * 5,
top_k=5
)2.3 核心特性
Serverless架构:用户无需预配置资源,按实际使用量付费。在流量波动场景下,这显著降低了成本。
Metadata Filtering:支持在向量检索基础上进行结构化过滤。结合向量相似度和属性条件,精确定位目标数据。
Pod类型选择:标准Pod适合通用场景;s1Pod优化存储密集型应用;p2Pod优化性能密集型工作负载。
"""
高级特性示例
"""
# 命名空间隔离(多租户场景)
index = pc.Index("multi-tenant-index", namespace="tenant-a")
index.upsert([...])
# 稀疏向量支持(混合搜索)
index.upsert([{
"id": "doc-001",
"values": dense_vector, # 密集向量
"sparse_values": {"indices": [0, 10, 20], "values": [0.1, 0.2, 0.3]} # 稀疏
}])
# 索引描述和统计
stats = index.describe_index_stats()
print(f"Total vectors: {stats.total_vector_count}")
print(f"Dimension: {stats.dimension}")2.4 优缺点分析
优势:托管服务省去运维负担、自动扩缩容稳定可靠、全球化部署低延迟、生态集成完善(OpenAI、LangChain等)。
劣势:成本随数据量线性增长、专有API锁定、自托管选项有限。
三、Milvus详解
3.1 产品定位
Milvus是Apache基金会旗下的开源向量数据库,以”高性能、大规模、强扩展”为核心定位。它支持多种部署模式,从单机到分布式集群,适合各种规模的应用场景。作为最成熟的开源向量数据库,Milvus在工业界拥有广泛的应用。
3.2 核心架构
Milvus采用分层架构设计:接入层处理客户端请求,协调节点管理集群状态,工作节点执行实际的向量操作,存储层管理数据持久化。这种架构支持水平扩展,适应业务增长。
"""
Milvus Python SDK (pymilvus) 使用示例
安装: pip install pymilvus
"""
from pymilvus import connections, Collection, FieldSchema, CollectionSchema, CollectionName, DataType, utility
import numpy as np
# 连接服务器
connections.connect(
alias="default",
host="localhost",
port="19530"
)
# 定义Collection Schema
fields = [
FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True),
FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=768),
FieldSchema(name="text", dtype=DataType.VARCHAR, max_length=65535),
FieldSchema(name="category", dtype=DataType.VARCHAR, max_length=100)
]
schema = CollectionSchema(
fields=fields,
description="知识库向量集合"
)
# 创建Collection
collection_name = "knowledge_base"
collection = Collection(name=collection_name, schema=schema)
# 创建索引(提高检索效率的关键步骤)
index_params = {
"index_type": "HNSW",
"metric_type": "COSINE",
"params": {"M": 16, "efConstruction": 200}
}
collection.create_index(
field_name="embedding",
index_params=index_params
)
# 加载到内存(查询前必须)
collection.load()
# 插入数据
data = [
[i for i in range(1000)], # 主键(自增)
np.random.rand(1000, 768).tolist(), # 向量
[f"文档{i}内容" for i in range(1000)], # 文本
[f"category-{i%5}" for i in range(1000)] # 类别
]
insert_result = collection.insert(data)
print(f"Inserted {insert_result.insert_count} entities")
# 查询
search_params = {"metric_type": "COSINE", "params": {"ef": 128}}
query_vector = np.random.rand(768).tolist()
results = collection.search(
data=[query_vector],
anns_field="embedding",
param=search_params,
limit=10,
expr='category == "category-0"', # 表达式过滤
output_fields=["text", "category"]
)
for hits in results:
for hit in hits:
print(f"ID: {hit.id}, Distance: {hit.distance}, Text: {hit.entity.get('text')}")
# 删除索引(修改Schema前需要)
collection.release()
collection.drop_index()3.3 分布式部署
# docker-compose.yml for Milvus Cluster
version: '3.8'
services:
etcd:
image: quay.io/coreos/etcd:v3.5.5
environment:
- ETCD_AUTO_COMPACTION_MODE=revision
- ETCD_AUTO_COMPACTION_RETENTION=1000
- ETCD_QUOTA_BACKEND_BYTES=4294967296
volumes:
- etcd_data:/etcd
command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd
minio:
image: minio/minio:RELEASE.2023-03-20T20-16-18Z
environment:
MINIO_ACCESS_KEY: minioadmin
MINIO_SECRET_KEY: minioadmin
volumes:
- minio_data:/minio
command: minio server /minio --console-address ":9001"
milvus:
image: milvusdb/milvus:v2.3.3
command: ["milvus", "run", "standalone"]
environment:
ETCD_ENDPOINTS: etcd:2379
MINIO_ADDRESS: minio:9000
volumes:
- milvus_data:/var/lib/milvus
ports:
- "19530:19530"
- "9091:9091"
volumes:
etcd_data:
minio_data:
milvus_data:3.4 优缺点分析
优势:完全开源可自托管、水平扩展能力强、社区活跃度高、支持多种索引类型、性价比高。
劣势:运维复杂度较高(相对Pinecone)、单机性能略逊于专用优化版本、学习曲线较陡。
四、Chroma详解
4.1 产品定位
Chroma是专为AI应用设计的开源向量数据库,以”开发者友好、嵌入应用内置”为核心理念。它可以嵌入Python应用进程运行,无需独立部署,适合原型开发和小型应用。Chroma的设计哲学是 simplicity first,为LangChain等AI框架提供无缝集成。
4.2 核心架构
Chroma的核心是轻量级的本地向量存储,支持文件持久化和客户端-服务器两种模式。这种设计使其成为AI应用开发的理想选择。
"""
Chroma Python SDK使用示例
安装: pip install chromadb
"""
import chromadb
from chromadb.config import Settings
import numpy as np
# 方式1: 内存模式(临时数据)
client = chromadb.Client()
# 方式2: 持久化模式
client = chromadb.PersistentClient(path="./chroma_data")
# 方式3: 客户端-服务器模式
client = chromadb.HttpClient(host="localhost", port=8000)
# 创建Collection
collection = client.create_collection(
name="knowledge_base",
metadata={"description": "知识库向量集合"}, # 集合级别的元数据
get_or_create=True
)
# 添加向量
collection.add(
ids=["doc-001", "doc-002", "doc-003"],
embeddings=np.random.rand(3, 384).tolist(), # BGE-small dimension
documents=[
"机器学习是人工智能的核心技术",
"深度学习是机器学习的子领域",
"自然语言处理处理文本数据"
],
metadatas=[
{"source": "技术文档", "category": "AI"},
{"source": "技术文档", "category": "深度学习"},
{"source": "技术文档", "category": "NLP"}
]
)
# 查询
query_embedding = np.random.rand(384).tolist()
results = collection.query(
query_embeddings=[query_embedding],
n_results=2,
where={"category": "AI"}, # 元数据过滤
include=["documents", "metadatas", "distances"]
)
print(f"IDs: {results['ids']}")
print(f"Distances: {results['distances']}")
print(f"Documents: {results['documents']}")
# 更新和删除
collection.update(
ids=["doc-001"],
embeddings=[np.random.rand(384).tolist()],
documents=["更新后的文档内容"]
)
collection.delete(ids=["doc-003"], where={"category": "NLP"})
# Collection管理
collection_list = client.list_collections()
print(f"Collections: {[c.name for c in collection_list]}")
collection_info = collection.get()
print(f"Count: {collection_info.count()}")4.3 与LangChain集成
"""
Chroma与LangChain集成示例
安装: pip install langchain-chroma
"""
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import TextLoader
# 初始化Embedding模型
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
# 创建Chroma向量存储
vectorstore = Chroma(
client=chromadb.PersistentClient(path="./chroma_data"),
collection_name="langchain_docs",
embedding_function=embeddings
)
# 加载文档
loader = TextLoader("./knowledge_base.txt")
documents = loader.load()
# 文本分割
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200
)
chunks = text_splitter.split_documents(documents)
# 向量化存储
vectorstore.add_documents(chunks)
# 相似性检索
results = vectorstore.similarity_search(
"什么是机器学习",
k=5,
filter={"source": "技术文档"}
)
for doc in results:
print(f"Content: {doc.page_content[:100]}...")
print(f"Metadata: {doc.metadata}")4.4 优缺点分析
优势:零配置使用、学习曲线极低、与AI框架无缝集成、轻量级适合原型开发、完全开源。
劣势:单机模式不适合大规模生产环境、客户端-服务器模式功能受限、不支持分布式部署、持久化性能一般。
五、Weaviate详解
5.1 产品定位
Weaviate是以”知识图谱+向量搜索”融合为特色的向量数据库。它原生支持混合搜索,结合向量相似度和结构化属性过滤,适合构建知识图谱增强的智能应用。Weaviate提供云服务和企业版,同时保持完全开源。
5.2 核心架构
Weaviate采用模块化架构设计,核心引擎支持多种向量化模块(如OpenAI、 Cohere、本地模型)。它原生存储JSON格式的对象,与GraphQL风格的查询接口。
"""
Weaviate Python SDK使用示例
安装: pip install weaviate-client
"""
import weaviate
from weaviate.classes.init import Auth
import numpy as np
# 初始化客户端
client = weaviate.Client(
url="http://localhost:8080",
# auth_client_secret=Auth.api_key("YOUR-WEAVIATE-API-KEY") # 云服务认证
)
# 创建Collection(Schema定义)
if not client.collections.exists("Article"):
article_collection = client.collections.create(
name="Article",
properties=[
weaviate.classes.config.Property(name="title", data_type=weaviate.classes.config.DataType.TEXT),
weaviate.classes.config.Property(name="content", data_type=weaviate.classes.config.DataType.TEXT),
weaviate.classes.config.Property(name="author", data_type=weaviate.classes.config.DataType.TEXT),
weaviate.classes.config.Property(name="publish_year", data_type=weaviate.classes.config.DataType.INT),
weaviate.classes.config.Property(name="tags", data_type=weaviate.classes.config.DataType.TEXT_ARRAY)
],
vectorizer_config=[
weaviate.classes.config.Configure.NamedVectorizer.text2vec_transformers(
vectorize_collection_name=False
)
],
vector_index_config=weaviate.classes.config.Configure.VectorIndex.HNSW(
distance_metric=weaviate.classes.config.VectorDistances.COSINE
)
)
# 插入数据
article_collection = client.collections.get("Article")
data_objects = [
{
"title": "深度学习导论",
"content": "深度学习是机器学习的一个分支...",
"author": "张三",
"publish_year": 2023,
"tags": ["AI", "深度学习", "机器学习"]
},
{
"title": "自然语言处理基础",
"content": "NLP处理文本和语音数据...",
"author": "李四",
"publish_year": 2024,
"tags": ["NLP", "AI", "语言"]
}
]
# 使用内置向量化器自动生成向量
article_collection.data.insert_many(data_objects)
# 手动指定向量
article_collection.data.insert(
properties={
"title": "计算机视觉进展",
"content": "CV领域的重要突破...",
"author": "王五"
},
vector=np.random.rand(768).tolist()
)
# 混合搜索(向量+关键词)
articles = article_collection.query.hybrid(
query="机器学习",
vector=np.random.rand(768).tolist(), # 可选:结合向量搜索
alpha=0.7, # 0=纯关键词, 1=纯向量
limit=10,
filters=weaviate.classes.query.Filter.by_property("publish_year").greater_than(2022),
return_properties=["title", "content", "author"],
return_metadata=weaviate.classes.query.MetadataQuery.full()
)
for obj in articles.objects:
print(f"Title: {obj.properties['title']}")
print(f"Score: {obj.metadata.score}")
# 纯向量搜索
articles = article_collection.query.near_vector(
near_vector=np.random.rand(768).tolist(),
limit=10,
filters=weaviate.classes.query.Filter.by_property("tags").contains_any(["AI"])
)5.3 GraphQL查询
"""
Weaviate GraphQL查询示例
"""
# GraphQL方式查询
query = """
{
Get {
Article(
nearText: {
concepts: ["人工智能"]
moveTo: {
concepts: ["机器学习"],
force: 0.5
}
moveAwayFrom: {
concepts: ["硬件"],
force: 0.3
}
}
limit: 10
) {
title
content
_additional {
certainty
distance
}
}
}
}
"""
result = client.query.raw(query)
print(result)5.4 优缺点分析
优势:知识图谱原生支持、混合搜索能力强、多向量化模块集成、GraphQL接口灵活、GraphQL订阅支持实时更新。
劣势:学习曲线较陡(GraphQL API)、资源占用较高、分布式功能需要企业版。
六、Qdrant详解
6.1 产品定位
Qdrant是高性能的开源向量搜索引擎,以”速度优先、灵活筛选”为设计理念。它提供精确的控制能力和优秀的性能表现,特别适合需要细粒度检索控制的场景。Qdrant支持本地部署和云服务,社区活跃度高。
6.2 核心架构
Qdrant采用Rust语言实现,在性能和内存效率上有显著优势。它支持多种距离度量、丰富的过滤表达式和稀疏-密集混合向量。
"""
Qdrant Python SDK使用示例
安装: pip install qdrant-client
"""
from qdrant_client import QdrantClient, models
from qdrant_client.models import Distance, VectorParams, PointStruct, Filter
import numpy as np
# 连接Qdrant服务
client = QdrantClient(host="localhost", port=6333)
# 创建Collection
collection_name = "knowledge_base"
# 删除已存在的Collection(可选)
if client.collection_exists(collection_name):
client.delete_collection(collection_name)
# 创建Collection,指定向量参数
client.create_collection(
collection_name=collection_name,
vectors_config=VectorParams(
size=768, # 向量维度
distance=Distance.COSINE # 距离度量
),
# 稀疏向量配置(可选)
sparse_vectors_config=models.SparseVectorParams(
index=models.SparseIndexParams(
on_disk=False
)
)
)
# 配置HNSW索引参数
client.update_collection(
collection_name=collection_name,
hnsw_config=models.HnswConfigDiff(
m=16, # 节点连接数
ef_construct=200, # 构建时探索因子
full_scan_threshold=10000 # 小于此规模用全扫描
)
)
# 插入向量
points = [
PointStruct(
id="doc-001",
vector=np.random.rand(768).tolist(),
payload={
"text": "机器学习是人工智能的核心技术",
"category": "AI",
"created_at": "2024-01-01",
"score_range": 85
}
),
PointStruct(
id="doc-002",
vector=np.random.rand(768).tolist(),
payload={
"text": "深度学习使用神经网络",
"category": "深度学习",
"created_at": "2024-01-15",
"score_range": 90
}
)
]
client.upsert(
collection_name=collection_name,
points=points
)
# 高级查询
search_results = client.search(
collection_name=collection_name,
query_vector=np.random.rand(768).tolist(),
query_filter=Filter(
must=[
models.FieldCondition(
key="category",
match=models.MatchValue(value="AI")
),
models.FieldCondition(
key="score_range",
range=models.Range(gte=80)
)
],
should=[
models.FieldCondition(
key="created_at",
match=models.MatchText(text="2024")
)
]
),
limit=10,
score_threshold=0.7, # 最低分数阈值
with_payload=True,
with_vectors=False
)
for result in search_results:
print(f"ID: {result.id}")
print(f"Score: {result.score}")
print(f"Payload: {result.payload}")
# 批量搜索
query_vectors = [np.random.rand(768).tolist() for _ in range(3)]
batch_results = client.search_batch(
collection_name=collection_name,
requests=[
models.SearchRequest(
vector=qv,
limit=5,
filter=Filter(must=[models.FieldCondition(key="category", match=models.MatchValue(value="AI"))])
)
for qv in query_vectors
]
)6.3 重组与更新
"""
Qdrant重组(Re-ranking)和条件更新
"""
# 重组查询 - 在初步向量搜索后进行精确排序
result = client.search(
collection_name=collection_name,
query_vector=query_vector,
limit=20, # 初步返回更多结果
search_params=models.SearchParams(hnsw_ef=128)
)
# 使用不同策略重组
reranked = sorted(
result,
key=lambda x: (x.score * 0.7 + x.payload.get('score_range', 0) / 100 * 0.3),
reverse=True
)
# 条件更新
client.update_collection(
collection_name=collection_name,
optimizer_config=models.OptimizersConfigDiff(
indexing_threshold=20000, # 触发索引建立的向量数
memmap_threshold_kb=1024
)
)
# 删除向量
client.delete(
collection_name=collection_name,
points_selector=models.PointIdsList(
points=["doc-001", "doc-002"]
)
)
# 条件删除
client.delete(
collection_name=collection_name,
points_selector=models.FilterSelector(
filter=Filter(
must=[
models.FieldCondition(
key="category",
match=models.MatchValue(value="deprecated")
)
]
)
)
)6.4 优缺点分析
优势:Rust实现性能卓越、过滤表达式丰富灵活、稀疏-密集混合支持、成熟度高的开源项目、详尽的文档和API。
劣势:生态系统相对年轻、托管服务相对新、没有内置知识图谱功能。
七、pgvector详解
7.1 产品定位
pgvector是PostgreSQL的向量搜索扩展,将向量存储能力融入成熟的关系型数据库。对于已有PostgreSQL基础设施的团队,pgvector提供了零新增基础设施的向量搜索方案。它支持向量存储、相似度搜索和精确的KNN(最近邻)操作。
7.2 核心功能
-- 安装扩展
CREATE EXTENSION IF NOT EXISTS vector;
-- 创建带向量列的表
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
title VARCHAR(500),
content TEXT,
embedding vector(768), -- 768维向量(可调)
category VARCHAR(100),
created_at TIMESTAMP DEFAULT NOW()
);
-- 创建HNSW索引(推荐用于生产环境)
CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops);
-- 或创建IVFFlat索引(适合超大数据集)
CREATE INDEX ON documents USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);
-- 插入数据
INSERT INTO documents (title, content, embedding, category)
VALUES
('深度学习入门', '深度学习是机器学习的分支...',
'[0.1, 0.2, ...]::vector', 'AI'),
('Python教程', 'Python是一门编程语言...',
'[0.3, 0.4, ...]::vector', '编程');
-- 基础相似度查询
SELECT title, content,
1 - (embedding <=> '[0.1, 0.2, ...]::vector') AS similarity
FROM documents
ORDER BY embedding <=> '[0.1, 0.2, ...]::vector'
LIMIT 5;
-- 精确KNN查询
SELECT * FROM documents
ORDER BY embedding <-> '[0.1, 0.2, ...]::vector'
LIMIT 10;
-- 距离操作符说明
-- <=> 余弦距离 (1 - cosine_similarity)
-- <+> L2欧氏距离
-- <#> 负内积7.3 Python集成
"""
pgvector与Python生态集成
安装: pip install psycopg2-binary pgvector
"""
import psycopg2
import numpy as np
# 连接数据库
conn = psycopg2.connect(
host="localhost",
database="vector_db",
user="postgres",
password="password"
)
cursor = conn.cursor()
# 执行向量搜索
def search_similar(query_embedding, top_k=10, category=None):
query_vec = "[" + ",".join(map(str, query_embedding)) + "]"
sql = """
SELECT id, title, content,
1 - (embedding <=> %s::vector) AS similarity
FROM documents
WHERE 1=1
"""
params = [query_vec]
if category:
sql += " AND category = %s"
params.append(category)
sql += f"""
ORDER BY embedding <=> %s::vector
LIMIT {top_k}
"""
cursor.execute(sql, params)
return cursor.fetchall()
# 批量插入
def batch_insert(documents):
"""批量插入文档和向量"""
values = []
params = []
for doc in documents:
vec_str = "[" + ",".join(map(str, doc["embedding"])) + "]"
values.append("(%s, %s, %s, %s::vector)")
params.extend([doc["title"], doc["content"], doc["category"], vec_str])
sql = """
INSERT INTO documents (title, content, category, embedding)
VALUES """ + ",".join(values)
cursor.execute(sql, params)
conn.commit()
# 搜索示例
query_emb = np.random.rand(768)
results = search_similar(query_emb, top_k=5, category="AI")
for row in results:
print(f"ID: {row[0]}, Title: {row[1]}, Similarity: {row[3]:.4f}")7.4 与SQLAlchemy集成
"""
使用SQLAlchemy操作pgvector
安装: pip install sqlalchemy[postgresql] sqlalchemy-utils
"""
from sqlalchemy import create_engine, Column, Integer, String, Text, Float
from sqlalchemy.dialects.postgresql import ARRAY
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
import numpy as np
Base = declarative_base()
class Document(Base):
__tablename__ = "documents"
id = Column(Integer, primary_key=True)
title = Column(String(500))
content = Column(Text)
category = Column(String(100))
# pgvector列使用String存储,向量操作时CAST
embedding = Column(String) # 存储为字符串 "[0.1, 0.2, ...]"
def get_embedding_array(self):
return np.array(eval(self.embedding))
def set_embedding_array(self, arr):
self.embedding = str(arr.tolist())
engine = create_engine("postgresql://postgres:password@localhost/vector_db")
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
# 添加文档
doc = Document(
title="机器学习基础",
content="机器学习是人工智能的重要分支...",
category="AI"
)
doc.set_embedding_array(np.random.rand(768))
session.add(doc)
session.commit()
# 相似性搜索
def search_documents(query_embedding, limit=10):
vec_str = str(query_embedding.tolist())
results = session.execute(
f"""
SELECT id, title, content, category,
1 - (embedding::vector <=> '{vec_str}'::vector) AS similarity
FROM documents
ORDER BY embedding::vector <=> '{vec_str}'::vector
LIMIT {limit}
"""
)
return [(row[0], row[1], row[4]) for row in results]7.5 优缺点分析
优势:零新增基础设施、与现有Postgres生态完美集成、事务支持强(ACID)、支持复杂SQL联接、免费开源。
劣势:向量索引性能不如专用向量数据库、大规模向量(百万级)性能下降、水平扩展需要PostgreSQL原生分片。
八、综合对比矩阵
8.1 功能特性对比
| 特性 | Pinecone | Milvus | Chroma | Weaviate | Qdrant | pgvector |
|---|---|---|---|---|---|---|
| 部署模式 | 全托管 | 自托管/云 | 嵌入/服务器 | 自托管/云 | 自托管/云 | 自托管 |
| 开源 | 否 | 是 | 是 | 是 | 是 | 是 |
| HNSW | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| IVF | ❌ | ✅ | ❌ | ✅ | ✅ | ✅ |
| 混合搜索 | ✅ | ✅ | ❌ | ✅ | ✅ | ✅ |
| 元数据过滤 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| 稀疏向量 | ✅ | ✅ | ❌ | ✅ | ✅ | ❌ |
| 知识图谱 | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ |
| 分布式 | 自动 | 支持 | ❌ | 企业版 | 支持 | 受限 |
| 多租户 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
8.2 性能对比
基于10M 768维向量的基准测试(来源:ANN-Benchmark等公开数据):
| 数据库 | QPS | P99延迟 | 召回率 | 内存占用 |
|---|---|---|---|---|
| Qdrant | 1500+ | 50ms | 98% | 高 |
| Milvus | 1200+ | 80ms | 97% | 高 |
| Weaviate | 800+ | 100ms | 96% | 中 |
| Pinecone | 1000+ | 60ms | 97% | 托管 |
| Chroma | 500+ | 150ms | 95% | 中 |
| pgvector | 300+ | 200ms | 99% | 低 |
测试说明
测试条件:10M向量,HNSW索引(M=16, efConstruction=200),V100 GPU环境。实际性能因数据分布、查询复杂度而异。
8.3 成本对比
| 数据库 | 免费额度 | 1M向量/月 | 扩展成本 |
|---|---|---|---|
| Pinecone | ❌ | ~$70-200 | 按使用量 |
| Milvus | ✅ | ~$50-100* | 基础设施 |
| Chroma | ✅ | ~$0-20* | 基础设施 |
| Weaviate | ✅ | ~$60-150* | 基础设施+云服务 |
| Qdrant | ✅ | ~$40-80* | 基础设施+云服务 |
| pgvector | ✅ | ~$30-60* | 基础设施 |
*估算,基于典型云服务器成本
8.4 选型决策树
开始
│
├─ 是否已有PostgreSQL基础设施?
│ │
│ ├─ 是 → pgvector(零成本扩展)
│ └─ 否
│ │
│ ├─ 是否需要知识图谱能力?
│ │ │
│ │ ├─ 是 → Weaviate
│ │ └─ 否
│ │ │
│ │ ├─ 团队规模 < 5人,原型开发?
│ │ │ │
│ │ │ ├─ 是 → Chroma
│ │ │ └─ 否
│ │ │ │
│ │ │ ├─ 是否需要托管服务?
│ │ │ │ │
│ │ │ │ ├─ 是 → Pinecone
│ │ │ │ └─ 否 → Qdrant / Milvus
│ │ │ │
│ │ └─ 规模 > 100M向量?
│ │ │
│ │ ├─ 是 → Milvus(分布式支持)
│ │ └─ 否 → Qdrant(性能优先)
│ │
│ └─ 是否追求极致性能?
│ │
│ ├─ 是 → Qdrant
│ └─ 否 → 根据其他因素选择
│
结束
九、相关主题链接
- 向量数据库部署 - 各数据库的详细部署指南
- Embedding模型选择 - 向量生成模型选型
- 重排技术深度指南 - 检索后重排优化
- 混合检索技术 - 向量+关键词混合搜索
- GraphRAG深度指南 - GraphRAG中的向量存储
- 知识库评估体系 - 检索质量评估
更新日志
- 2026-04-18: 初始版本完成
- 涵盖6大主流向量数据库的全面对比
- 提供详尽的代码示例和选型决策指南