一、什么是向量数据库

        一种专门用于存储和检索高维向量数据的数据库。它将数据(如文本、图像、音频等)通过嵌入模型转换为向量形式,并通过高效的索引和搜索算法实现快速检索。

二、向量数据库的作用

        向量数据库的核心作用是实现相似性搜索,即通过计算向量之间的距离(如欧几里得距离、余弦相似度等)来找到与目标向量最相似的其他向量。它特别适合处理非结构化数据,支持语义搜索、内容推荐等场景。

(1)主要功能作用

1、相似性搜索

  • 最近邻搜索:快速找到与查询向量最相似的向量

  • 范围搜索:查找在特定距离范围内的所有向量

  • 多模态检索:支持文本、图像、音频等多种数据的联合检索

2、大规模向量管理

  • 高效存储:优化高维向量的存储结构

  • 索引优化:支持多种索引算法提升检索速度

  • 分布式扩展:支持水平扩展处理亿级向量

3、实时数据处理

  • 流式处理:实时处理新增向量数据

  • 动态更新:支持向量的增删改操作

  • 一致性保证:在分布式环境下保证数据一致性

4、生产级特性

  • 高可用性:故障自动转移和数据备份

  • 安全性:访问控制和数据加密

  • 监控运维:完善的监控指标和运维工具

(2)向量数据库如何存储和检索嵌入向量

存储:向量数据库将嵌入向量存储为高维空间中的点,并为每个向量分配唯一标识符(ID),同时支持存储元数据。

检索:通过近似最近邻(ANN)算法(如PQ等)对向量进行索引和快速搜索。比如,FAISS和Milvus等数据库通过高效的索引结构加速检索。

(3)典型应用场景

示例代码:

# 向量数据库在RAG中的应用
def rag_with_vector_db(question, knowledge_base):
    # 1. 问题向量化
    query_vector = embedding_model.encode(question)
    
    # 2. 向量数据库相似搜索
    relevant_chunks = vector_db.similarity_search(
        query_vector, 
        top_k=5
    )
    
    # 3. 增强生成
    augmented_prompt = build_prompt(question, relevant_chunks)
    answer = llm.generate(augmented_prompt)
    
    return answer

三、向量数据库与传统数据库的对比

1. 数据类型

传统数据库:存储结构化数据(如表格、行、列)。

向量数据库:存储高维向量数据,适合非结构化数据。

2. 查询方式

传统数据库:依赖精确匹配(如=、<、>)。

向量数据库:基于相似度或距离度量(如欧几里得距离、余弦相似度)。

3. 应用场景

传统数据库:适合事务记录和结构化信息管理。

向量数据库:适合语义搜索、内容推荐等需要相似性计算的场景。

四、向量数据库类型

1. 专用向量数据库

专门为向量操作设计的数据库系统。

特点:

  • 原生支持向量操作

  • 优化的向量索引算法

  • 高效的相似性搜索

代表:

  • Milvus / Zilliz Cloud

  • Qdrant

  • Weaviate

  • Pinecone

2. 扩展型向量数据库

在现有数据库基础上添加向量功能。

特点:

  • 兼容现有生态

  • 支持混合查询(向量+标量)

  • 学习成本较低

代表:

  • Redis + RedisSearch

  • Elasticsearch + 向量插件

  • PostgreSQL + pgvector

3. 云服务向量数据库

云厂商提供的托管式向量数据库服务。

特点:

  • 开箱即用

  • 自动扩缩容

  • 企业级支持

代表:

  • AWS OpenSearch(向量搜索)

  • Google Vertex AI 匹配引擎

  • Azure Cognitive Search

4. 轻量级向量库

适合小规模应用和原型开发。

特点:

  • 部署简单

  • 资源消耗少

  • 功能相对简单

代表:

  • Chroma

  • FAISS(严格来说是库而非数据库)

  • Annoy

三、主流向量数据库与功能对比

功能对比总表

特性MilvusQdrantWeaviateChromaPGVector
开源协议Apache 2.0Apache 2.0BSD-3-ClauseApache 2.0PostgreSQL
部署方式独立服务独立服务独立服务嵌入/服务PostgreSQL扩展
向量维度支持高维支持高维支持高维支持高维最高2000维
索引类型HNSW, IVFHNSW, IVFHNSWHNSWIVF, HNSW
标量过滤
多向量
分布式
混合查询
元数据
语言支持多语言多语言多语言Python/JSSQL
云托管Zilliz CloudQdrant CloudWeaviate CloudChroma Cloud各大云厂

详细特性分析

1. Milvus / Zilliz Cloud

优势:

  • 功能最全面,企业级特性丰富

  • 社区活跃,生态完善

  • 支持多种向量索引算法

  • 分布式架构,扩展性强

适用场景:

  • 大规模企业级应用

  • 需要高可用和强一致性的场景

  • 复杂的多模态检索需求

2. Qdrant

优势:

  • Rust开发,性能优异

  • API设计简洁易用

  • 丰富的过滤条件

  • 内存优化好

适用场景:

  • 对性能要求高的应用

  • 需要复杂过滤条件的场景

  • 中等规模的数据量

3. Weaviate

优势:

  • 内置模块化设计

  • 支持多模态向量化

  • GraphQL接口

  • 语义搜索能力强

适用场景:

  • 知识图谱应用

  • 多模态搜索

  • 需要GraphQL接口的项目

4. Chroma

优势:

  • 部署简单,学习成本低

  • Python原生支持好

  • 适合快速原型开发

  • 内存模式适合开发测试

适用场景:

  • 原型开发和实验

  • 小到中等规模应用

  • Python技术栈项目

5. PGVector(PostgreSQL扩展)

优势:

  • 利用成熟的PostgreSQL生态

  • ACID事务支持

  • 向量和关系数据统一管理

  • SQL标准接口

适用场景:

  • 已使用PostgreSQL的项目

  • 需要强事务保证的应用

  • 向量和关系数据混合查询

五、向量数据库服务搭建实战

1. Chroma - 快速入门部署

本地部署:

import chromadb
from chromadb.config import Settings

# 创建客户端
client = chromadb.Client(Settings(
    chroma_db_impl="duckdb+parquet",
    persist_directory="./chroma_db"
))

# 创建集合(类似表)
collection = client.create_collection(name="my_documents")

# 添加文档
documents = [
    "人工智能是未来的发展方向",
    "机器学习是AI的重要分支", 
    "深度学习基于神经网络",
    "自然语言处理让计算机理解人类语言"
]
metadatas = [{"category": "ai"}, {"category": "ml"}, 
             {"category": "dl"}, {"category": "nlp"}]
ids = ["doc1", "doc2", "doc3", "doc4"]

collection.add(
    documents=documents,
    metadatas=metadatas,
    ids=ids
)

# 相似性搜索
results = collection.query(
    query_texts=["什么是AI技术?"],
    n_results=2
)

print("搜索结果:", results)

Docker部署:

# docker-compose.yml
version: '3.8'
services:
  chroma:
    image: chromadb/chroma
    ports:
      - "8000:8000"
    environment:
      - IS_PERSISTENT=TRUE
    volumes:
      - chroma_data:/chroma/chroma
volumes:
  chroma_data:

2. Qdrant - 生产级部署

Docker部署:

# docker-compose.yml
version: '3.8'
services:
  qdrant:
    image: qdrant/qdrant
    ports:
      - "6333:6333"
      - "6334:6334"
    volumes:
      - qdrant_data:/qdrant/storage
    environment:
      - QDRANT__SERVICE__HTTP_PORT=6333
      - QDRANT__SERVICE__GRPC_PORT=6334

volumes:
  qdrant_data:

Python客户端使用:

from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct
import numpy as np

# 连接客户端
client = QdrantClient(host="localhost", port=6333)

# 创建集合
client.create_collection(
    collection_name="tech_articles",
    vectors_config=VectorParams(size=384, distance=Distance.COSINE)
)

# 准备数据
vectors = np.random.rand(100, 384).tolist()  # 100个384维向量
payloads = [
    {"text": f"文章内容{i}", "category": "AI", "year": 2023}
    for i in range(100)
]
points = [
    PointStruct(
        id=idx,
        vector=vector,
        payload=payload
    )
    for idx, (vector, payload) in enumerate(zip(vectors, payloads))
]

# 上传数据
client.upsert(
    collection_name="tech_articles",
    wait=True,
    points=points
)

# 带过滤的搜索
search_result = client.search(
    collection_name="tech_articles",
    query_vector=np.random.rand(384).tolist(),
    query_filter={
        "must": [
            {"key": "category", "match": {"value": "AI"}},
            {"key": "year", "range": {"gte": 2020}}
        ]
    },
    limit=5
)

for result in search_result:
    print(f"ID: {result.id}, 得分: {result.score}, 内容: {result.payload}")

3. Milvus - 分布式部署

单机Docker部署:

# 启动Milvus单机版
docker run -d --name milvus \
  -p 19530:19530 \
  -p 9091:9091 \
  -v milvus_data:/var/lib/milvus \
  milvusdb/milvus:v2.3.4

集群部署(生产环境):

# docker-compose.cluster.yml
version: '3.5'
services:
  etcd:
    container_name: milvus-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
      - ETCD_SNAPSHOT_COUNT=50000
    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:
    container_name: milvus-minio
    image: minio/minio:RELEASE.2023-03-20T20-16-18Z
    environment:
      MINIO_ACCESS_KEY: minioadmin
      MINIO_SECRET_KEY: minioadmin
    volumes:
      - minio_data:/minio_data
    command: minio server /minio_data
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      timeout: 20s
      retries: 3

  milvus:
    container_name: milvus-standalone
    image: milvusdb/milvus:v2.3.4
    command: ["milvus", "run", "standalone"]
    environment:
      ETCD_ENDPOINTS: etcd:2379
      MINIO_ADDRESS: minio:9000
    volumes:
      - milvus_data:/var/lib/milvus
    ports:
      - "19530:19530"
      - "9091:9091"
    depends_on:
      - "etcd"
      - "minio"

volumes:
  etcd_data:
  minio_data:
  milvus_data:

Python客户端示例:

from pymilvus import connections, FieldSchema, CollectionSchema, DataType, Collection, utility
import random

# 连接Milvus
connections.connect("default", host="localhost", port="19530")

# 定义字段
fields = [
    FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=True),
    FieldSchema(name="title", dtype=DataType.VARCHAR, max_length=200),
    FieldSchema(name="content_vector", dtype=DataType.FLOAT_VECTOR, dim=384),
    FieldSchema(name="category", dtype=DataType.VARCHAR, max_length=50)
]

# 创建集合
schema = CollectionSchema(fields, description="文档集合")
collection = Collection("documents", schema)

# 创建索引
index_params = {
    "index_type": "IVF_FLAT",
    "metric_type": "L2",
    "params": {"nlist": 128}
}
collection.create_index(
    field_name="content_vector", 
    index_params=index_params
)

# 插入数据
data = [
    ["AI技术发展综述", "机器学习应用实践", "深度学习框架比较"],
    [[random.random() for _ in range(384)] for _ in range(3)],
    ["AI", "ML", "DL"]
]

collection.insert(data)
collection.load()

# 搜索
search_params = {"metric_type": "L2", "params": {"nprobe": 10}}
results = collection.search(
    data=[[random.random() for _ in range(384)]],
    anns_field="content_vector",
    param=search_params,
    limit=2,
    expr="category == 'AI'",
    output_fields=["title", "category"]
)

for hits in results:
    for hit in hits:
        print(f"命中文档: {hit.entity.get('title')}, 距离: {hit.distance}")

4. PGVector - PostgreSQL扩展部署

安装扩展:

-- 创建扩展
CREATE EXTENSION IF NOT EXISTS vector;

-- 创建带向量字段的表
CREATE TABLE documents (
    id BIGSERIAL PRIMARY KEY,
    title TEXT NOT NULL,
    content TEXT,
    content_vector vector(384),
    category VARCHAR(50),
    created_at TIMESTAMP DEFAULT NOW()
);

-- 创建向量索引
CREATE INDEX ON documents USING ivfflat (content_vector vector_cosine_ops);

Python集成:

import psycopg2
import numpy as np
from pgvector.psycopg2 import register_vector

# 连接数据库
conn = psycopg2.connect(
    dbname="vector_db",
    user="postgres",
    password="password",
    host="localhost"
)
register_vector(conn)

# 插入向量数据
def insert_document(title, content, vector, category):
    with conn.cursor() as cur:
        cur.execute(
            "INSERT INTO documents (title, content, content_vector, category) VALUES (%s, %s, %s, %s)",
            (title, content, vector, category)
        )
    conn.commit()

# 向量相似性搜索
def search_similar_documents(query_vector, category=None, limit=5):
    with conn.cursor() as cur:
        if category:
            cur.execute(
                "SELECT title, content, content_vector <=> %s as distance FROM documents WHERE category = %s ORDER BY content_vector <=> %s LIMIT %s",
                (query_vector, category, query_vector, limit)
            )
        else:
            cur.execute(
                "SELECT title, content, content_vector <=> %s as distance FROM documents ORDER BY content_vector <=> %s LIMIT %s",
                (query_vector, query_vector, limit)
            )
        return cur.fetchall()

# 使用示例
query_vec = np.random.rand(384)
results = search_similar_documents(query_vec, category="AI")
for title, content, distance in results:
    print(f"标题: {title}, 距离: {distance}")

六、选型建议与最佳实践

1. 数据库选型指南

场景推荐选择理由
快速原型Chroma部署简单,Python集成好
中等规模Qdrant性能优秀,功能全面
大规模企业Milvus分布式,企业级特性
已有PostgreSQLPGVector生态集成,事务支持
多模态搜索Weaviate内置向量化,GraphQL

2. 性能优化策略

索引选择:

# Qdrant索引配置优化
from qdrant_client.models import HnswConfigDiff

optimized_config = HnswConfigDiff(
    m=16,           # 每个节点的连接数
    ef_construct=100, # 索引时的候选数
    full_scan_threshold=10000  # 全扫描阈值
)

查询优化:

# Milvus搜索参数优化
search_params = {
    "metric_type": "IP",  # 内积相似度
    "params": {
        "nprobe": 16,     # 搜索的聚类数
        "ef": 64          # HNSW的搜索深度
    }
}

3. 生产环境部署建议

资源规划:

  • 内存:向量索引通常需要大量内存

  • 存储:SSD硬盘提升IO性能

  • 网络:低延迟网络对于分布式部署很重要

监控告警:

# 关键监控指标
metrics:
  - qps: 每秒查询数
  - latency: 查询延迟
  - memory_usage: 内存使用率
  - disk_io: 磁盘IO
  - error_rate: 错误率

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐