一、什么是向量数据库?

向量数据库(Vector Database)是一种专门为存储和检索高维向量(如 128、256、768 甚至数千维)而优化的数据库。
每个向量可以理解为一个有序的数值数组,通常由深度学习模型、特征工程、嵌入算法(如 word2vec、BERT、CLIP、ResNet 等)生成。

典型应用:

  • 文本、图片、音频、视频的语义检索
  • 推荐系统、相似内容查找
  • AI Agent、RAG(检索增强生成)、知识库

二、向量数据库与传统数据库的区别

对比项 关系型/NoSQL数据库 向量数据库
数据结构 表、文档、键值 向量(数组)+元数据
检索方式 精确查找/条件过滤 相似度查找(ANN)
查询目标 结构化信息 语义相似、最近邻
性能优化 索引、分区 向量索引、分片、ANN
适用场景 传统业务 AI、推荐、语义搜索

三、核心技术原理

1. 高维向量存储

  • 每条记录包含向量字段(如 [0.12, -0.98, ..., 0.56])和元数据(如ID、标签、原始内容等)。

2. 相似度检索(ANN)

  • ANN(Approximate Nearest Neighbor)算法,如 HNSW、IVF、PQ、LSH 等。
  • 通过向量之间的距离(如欧氏距离、余弦相似度)查找最相似的 K 个向量。

3. 向量索引

  • 支持高效插入、删除、批量检索。
  • 支持分片、分布式扩展,适合亿级向量规模。

4. 混合检索

  • 支持向量检索与结构化过滤(如标签、时间范围)结合。

四、主流向量数据库产品

1. Milvus

  • 开源、分布式、极高性能
  • 支持多种 ANN 算法
  • 提供 Python/Java/Go/REST 等接口

2. Faiss

  • Facebook 开源库,专注于向量检索
  • C++/Python接口,常嵌入自定义服务

3. Weaviate

  • 开源,支持向量+结构化混合检索
  • 内置多种模型、RESTful API

4. Pinecone

  • 云原生、托管服务,易用性高
  • 支持大规模部署

5. Qdrant

  • 开源,专注于高效 ANN 检索
  • 多语言API支持

6. Elasticsearch/OpenSearch 向量检索

  • 传统搜索引擎扩展,适合与全文检索结合

五、典型应用场景

  1. AI 语义检索:文本、图片、视频的语义相似搜索
  2. 推荐系统:用户/物品特征向量检索,做个性化推荐
  3. RAG/知识库:LLM 检索增强生成,知识问答
  4. 异常检测/聚类分析:高维特征的聚类、异常点发现
  5. 多模态检索:跨文本、图像、音频的统一检索

六、基本操作与查询示例(以 Milvus 为例)

1. 插入向量

from pymilvus import Collection

# 创建集合
collection = Collection("demo")  # 已定义 schema

# 插入向量
entities = [[0.12, -0.98, ..., 0.56], [0.23, -0.87, ..., 0.45]]
collection.insert(entities)

2. 相似度检索

# 查询与目标向量最相近的前5条
results = collection.search([[0.10, -0.90, ..., 0.50]], "embedding", params={"metric_type": "L2"}, limit=5)
for hit in results[0]:
    print(hit.id, hit.distance)

3. 混合过滤检索

results = collection.search(
    [[0.10, -0.90, ..., 0.50]],
    "embedding",
    limit=5,
    expr="label == 'cat' and ts > 1680000000"
)

七、架构与性能优化

  • 分布式扩展:支持多节点、分片、负载均衡
  • 索引类型选择:根据数据规模、精度需求选 HNSW、IVF、PQ 等
  • 批量写入/检索:提升吞吐量
  • 混合检索:结合元数据和向量,提高业务相关性
  • 缓存与预热:热点向量预加载,降低响应延迟

八、选型建议

  • 亿级规模、高性能:Milvus、Pinecone、Qdrant
  • 嵌入自定义服务:Faiss
  • 结构化+向量混合:Weaviate、Elasticsearch/OpenSearch
  • 云原生易用:Pinecone
  • 开源本地部署:Milvus、Qdrant、Weaviate

九、向量数据库与 AI 的结合

向量数据库已成为 AI Agent、知识库、RAG 等新一代智能应用的核心基础设施。
它能让大模型“记住”海量知识、实现语义理解和推理,极大提升智能化水平。

十、Milvus 安装方式

1. Docker 一键安装(推荐)

适合个人开发、测试和小型生产环境。

# 下载官方 docker-compose 文件
wget https://github.com/milvus-io/milvus/releases/download/v2.3.12/milvus-standalone-docker-compose.yml -O docker-compose.yml

# 启动 Milvus
docker-compose up -d

# 查看服务状态
docker-compose ps
  • 默认包含 Milvus Standalone(服务端)、MinIO(对象存储)、Etcd(元数据)、支持 REST/gRPC/Python/Java 等多种客户端。
  • 默认端口:19530(gRPC),9091(HTTP REST)

2. 本地二进制安装

适合有特殊定制需求的场景。

  • 下载 Milvus Release
  • 解压后运行 milvus 可执行文件,需自行配置 MinIO、Etcd 等依赖。

3. 云/集群部署

  • 支持 Kubernetes 部署(Helm Chart),适合大规模生产环境。
  • 参考官方文档:Milvus Helm 部署

十一、Milvus 基本使用(Python为例)

1. 安装 Python SDK

pip install pymilvus

2. 连接 Milvus 服务

from pymilvus import connections
connections.connect("default", host="localhost", port="19530")

3. 创建 Collection(表)

定义 schema,包括主键和向量字段:

from pymilvus import FieldSchema, CollectionSchema, DataType, Collection

fields = [
    FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=False),
    FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=128)
]
schema = CollectionSchema(fields, description="向量检索测试")
collection = Collection("demo_collection", schema)

4. 插入向量数据

import numpy as np

ids = [1, 2, 3]
vectors = np.random.random((3, 128)).tolist()
collection.insert([ids, vectors])

5. 构建索引(提高检索效率)

index_params = {
    "index_type": "IVF_FLAT",    # 可选 HNSW、IVF_PQ 等
    "metric_type": "L2",         # 可选 COSINE、IP
    "params": {"nlist": 128}
}
collection.create_index(field_name="embedding", index_params=index_params)

6. 向量检索

search_vectors = np.random.random((1, 128)).tolist()
results = collection.search(
    search_vectors,
    "embedding",
    params={"metric_type": "L2", "nprobe": 10},
    limit=5
)
for hit in results[0]:
    print(f"id: {hit.id}, distance: {hit.distance}")

7. 结构化过滤/混合检索(如有其他字段)

results = collection.search(
    search_vectors,
    "embedding",
    limit=5,
    expr="id > 1"
)

8. 删除/更新数据

collection.delete("id in [2,3]")

十二、管理与运维

  • 查看所有集合from pymilvus import list_collections; print(list_collections())
  • 查看集合统计信息collection.num_entities
  • 删除集合collection.drop()
  • 备份与恢复:建议配合对象存储(MinIO)和定期快照

十三、常见问题与建议

  • 端口防火墙:确保 19530、9091 端口开放
  • 数据量大时:建议用分布式/集群部署,配置足够内存和存储
  • 索引类型选择:HNSW 适合高精度召回,IVF_FLAT/IVF_PQ 适合大规模高效检索
  • 与 AI 模型结合:推荐用 Milvus + embedding 服务,实现 RAG、语义检索等智能应用

十四、Milvus Java/Go 客户端示例

1. Java 客户端(milvus-sdk-java)

1.1 Maven 依赖

<dependency>
    <groupId>io.milvus</groupId>
    <artifactId>milvus-sdk-java</artifactId>
    <version>2.3.4</version> <!-- 请使用 Milvus 官网最新版本 -->
</dependency>

1.2 基本操作示例

import io.milvus.client.*;
import io.milvus.grpc.DataType;

import java.util.Arrays;
import java.util.List;

public class MilvusDemo {
    public static void main(String[] args) {
        MilvusServiceClient milvusClient = new MilvusServiceClient(
            ConnectParam.newBuilder()
                .withHost("localhost")
                .withPort(19530)
                .build()
        );

        // 创建集合
        FieldType idField = FieldType.newBuilder()
                .withName("id")
                .withDataType(DataType.Int64)
                .withPrimaryKey(true)
                .withAutoID(false)
                .build();
        FieldType vectorField = FieldType.newBuilder()
                .withName("embedding")
                .withDataType(DataType.FloatVector)
                .withDimension(128)
                .build();
        CreateCollectionParam createCollectionReq = CreateCollectionParam.newBuilder()
                .withCollectionName("java_demo")
                .withDescription("Java Milvus Demo")
                .withShardsNum(2)
                .addFieldType(idField)
                .addFieldType(vectorField)
                .build();
        milvusClient.createCollection(createCollectionReq);

        // 插入数据
        List<Long> ids = Arrays.asList(1L, 2L, 3L);
        List<List<Float>> vectors = Arrays.asList(
            Arrays.asList(0.1f, 0.2f, ...), // 128维向量
            Arrays.asList(0.3f, 0.4f, ...),
            Arrays.asList(0.5f, 0.6f, ...)
        );
        InsertParam insertParam = InsertParam.newBuilder()
                .withCollectionName("java_demo")
                .addField("id", ids)
                .addField("embedding", vectors)
                .build();
        milvusClient.insert(insertParam);

        // 检索
        List<List<Float>> searchVectors = Arrays.asList(Arrays.asList(0.1f, 0.2f, ...));
        SearchParam searchParam = SearchParam.newBuilder()
                .withCollectionName("java_demo")
                .withMetricType(MetricType.L2)
                .withOutFields(Arrays.asList("id"))
                .withTopK(5)
                .withVectors(searchVectors)
                .withVectorFieldName("embedding")
                .withParams("{\"nprobe\":10}")
                .build();
        SearchResults searchResults = milvusClient.search(searchParam);
        // 处理 searchResults...

        milvusClient.close();
    }
}

省略部分请用实际维度补全。更多细节见Milvus Java SDK文档


2. Go 客户端(milvus-sdk-go)

2.1 安装

go get github.com/milvus-io/milvus-sdk-go/v2@latest

2.2 基本操作示例

package main

import (
    "context"
    "fmt"
    "github.com/milvus-io/milvus-sdk-go/v2/client"
    "github.com/milvus-io/milvus-sdk-go/v2/entity"
)

func main() {
    ctx := context.Background()
    cli, err := client.NewGrpcClient(ctx, "localhost:19530")
    if err != nil {
        panic(err)
    }
    defer cli.Close()

    // 创建集合
    schema := &entity.Schema{
        CollectionName: "go_demo",
        Description:    "Milvus Go Demo",
        Fields: []*entity.Field{
            entity.NewField().
                WithName("id").
                WithDataType(entity.FieldTypeInt64).
                WithIsPrimaryKey(true).
                WithAutoID(false),
            entity.NewField().
                WithName("embedding").
                WithDataType(entity.FieldTypeFloatVector).
                WithDim(128),
        },
    }
    err = cli.CreateCollection(ctx, schema, 2)
    if err != nil {
        panic(err)
    }

    // 插入数据
    ids := entity.NewColumnInt64("id", []int64{1, 2, 3})
    vectors := entity.NewColumnFloatVector("embedding", 128, [][]float32{
        {0.1, 0.2, ...}, // 128维
        {0.3, 0.4, ...},
        {0.5, 0.6, ...},
    })
    _, err = cli.Insert(ctx, "go_demo", "", ids, vectors)
    if err != nil {
        panic(err)
    }

    // 检索
    searchVec := [][]float32{{0.1, 0.2, ...}}
    res, err := cli.Search(ctx, "go_demo", []string{}, "", []string{"embedding"}, searchVec, "embedding", entity.L2, 5, nil)
    if err != nil {
        panic(err)
    }
    fmt.Println(res)

    // 更多API见官方[Go SDK文档](https://milvus.io/docs/go_sdk.md)
}

十五、分布式部署配置(Kubernetes Helm)

1. 前提

  • 已有 Kubernetes 集群(如本地 minikube、云K8s)
  • 已安装 Helm

2. 安装 Milvus Helm Chart

helm repo add milvus https://milvus-io.github.io/milvus-helm/
helm repo update

# 查看可用版本
helm search repo milvus

# 安装分布式集群
helm install my-milvus milvus/milvus --set cluster.enabled=true

3. 主要组件

  • Milvus QueryNode/QueryCoord
  • DataNode/DataCoord
  • Proxy
  • RootCoord
  • Etcd、MinIO(元数据/对象存储)

4. 主要配置项

可通过 values.yaml 或 --set 参数自定义副本数、存储、资源等。

cluster:
  enabled: true
  queryNode:
    replicaCount: 2
  dataNode:
    replicaCount: 2
  minio:
    persistence:
      size: 100Gi
  etcd:
    replicaCount: 3

完整配置见官方 Helm 文档

5. 访问方式

  • 默认 Proxy 服务暴露 19530(gRPC)和 9091(REST)。
  • 可通过 NodePort、LoadBalancer 或 Ingress 方式暴露到外部。

十六、与 LLM/知识库集成方案(RAG 实践)

1. 典型流程

  1. 知识分段
    文档切分为段落/句子
  2. 向量生成
    用 LLM embedding API(如 OpenAI、BGE、MiniLM)将文本转为向量
  3. 入库
    向量+原文/元数据存入 Milvus
  4. 检索增强生成
    用户提问 → 生成向量 → Milvus 检索相似文本 → 拼接上下文 → LLM生成答案

2. Python 端到端示例

import openai
from pymilvus import Collection, connections

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

# 2. 用户提问
question = "什么是向量数据库?"
q_emb = openai.Embedding.create(model="text-embedding-ada-002", input=question)["data"][0]["embedding"]

# 3. 检索相关知识段
results = collection.search([q_emb], "embedding", limit=5)
context = "\n".join([hit.entity.get("content") for hit in results[0]])

# 4. 拼接上下文给大模型
prompt = f"已知知识:{context}\n请回答:{question}"
answer = openai.ChatCompletion.create(model="gpt-3.5-turbo", messages=[{"role": "user", "content": prompt}])
print(answer["choices"][0]["message"]["content"])

3. Java/Go 集成建议

  • 用 Java/Go SDK 负责与 Milvus 交互(入库、检索)。
  • 用 HTTP 调用 LLM 服务(如 OpenAI、ChatGLM、Qwen、BGE等)。
  • 构建微服务架构,支持高并发请求。

知识传递,互通有无,创作不易,点点关注!

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐