1. 引言
Milvus 是一款开源的分布式向量数据库,专为海量向量数据的存储、检索与分析而设计。它支持十亿级向量的毫秒级相似度搜索,广泛应用于推荐系统、图像检索、自然语言处理、生物信息学等 AI 场景。
与关系型数据库类似,Milvus 也提供了完整的数据库操作能力,可以划分为三大类:
- DDL(Data Definition Language):数据定义语言,用于创建、修改、删除数据库、集合、索引等结构对象。
- DML(Data Manipulation Language):数据操作语言,用于向集合中插入、删除、更新数据。
- DQL(Data Query Language):数据查询语言,用于检索数据,包括标量过滤和向量相似度搜索。
本文将以 Milvus 2.x 版本(PyMilvus 客户端)为例,系统讲解这三类操作的用法与最佳实践。
2. 环境准备
在开始之前,请确保已安装并启动 Milvus 服务,同时安装 Python 客户端:
bash
pip install pymilvus
连接 Milvus 服务:
python
from pymilvus import connections
# 连接 Milvus 服务
connections.connect(host="localhost", port="19530")
3. DDL 操作:数据定义
DDL 操作主要涉及数据库、集合(Collection)、字段(Field)、索引(Index)等结构的管理。
3.1 数据库管理
Milvus 2.x 支持多数据库隔离,默认数据库名为 default。
python
from pymilvus import utility
# 创建数据库
utility.create_database("my_db")
# 列出所有数据库
databases = utility.list_databases()
print(databases)
# 删除数据库
utility.drop_database("my_db")
3.2 创建集合
集合(Collection)类似于关系型数据库中的表。创建集合时需要定义 Schema,包括字段名称、类型、主键、向量维度等。
python
from pymilvus import CollectionSchema, FieldSchema, DataType, Collection
# 定义字段
book_id = FieldSchema(name="book_id", dtype=DataType.INT64, is_primary=True, auto_id=False)
book_name = FieldSchema(name="book_name", dtype=DataType.VARCHAR, max_length=256)
book_intro = FieldSchema(name="book_intro", dtype=DataType.VARCHAR, max_length=1024)
book_vector = FieldSchema(name="book_vector", dtype=DataType.FLOAT_VECTOR, dim=128)
# 构建 Schema
schema = CollectionSchema(
fields=[book_id, book_name, book_intro, book_vector],
description="图书信息集合",
enable_dynamic_field=True
)
# 创建集合
collection = Collection(name="book", schema=schema)
3.3 查看与删除集合
python
# 查看所有集合
collections = utility.list_collections()
print(collections)
# 查看集合详情
collection = Collection("book")
print(collection.schema)
print(collection.num_entities)
# 删除集合
utility.drop_collection("book")
3.4 索引管理
索引是向量检索性能的关键。Milvus 支持多种索引类型,如 IVF_FLAT、HNSW、DISKANN 等。
python
from pymilvus import Index
# 创建向量索引
index_params = {
"index_type": "HNSW",
"metric_type": "IP", # 内积度量
"params": {"M": 16, "efConstruction": 200}
}
collection.create_index(field_name="book_vector", index_params=index_params)
# 创建标量索引
collection.create_index(field_name="book_name", index_params={"index_type": "Trie"})
# 查看索引
indexes = collection.indexes
for idx in indexes:
print(idx.field_name, idx.params)
# 删除索引
collection.drop_index(field_name="book_vector")
4. DML 操作:数据操作
DML 操作负责对集合中的数据进行增、删、改。
4.1 插入数据
python
import random
# 构造数据
data = [
[i for i in range(100)], # book_id
[f"book_{i}" for i in range(100)], # book_name
[f"intro_{i}" for i in range(100)], # book_intro
[[random.random() for _ in range(128)] for _ in range(100)] # book_vector
]
# 插入数据
collection.insert(data)
collection.flush() # 将数据落盘
4.2 删除数据
删除操作需要指定主键或过滤表达式:
python
# 按主键删除
collection.delete(expr="book_id in [0, 1, 2]")
# 按条件删除
collection.delete(expr='book_name == "book_3"')
4.3 更新数据
Milvus 目前不支持直接更新已有实体的字段值。通常的做法是「先删除、再插入」:
python
# 删除旧数据
collection.delete(expr="book_id == 5")
# 插入新数据
new_data = [
[5],
["book_5_updated"],
["updated intro"],
[[random.random() for _ in range(128)]]
]
collection.insert(new_data)
collection.flush()
5. DQL 操作:数据查询
DQL 是 Milvus 最核心的能力,包括标量查询、向量相似度搜索以及混合检索。
5.1 标量查询(Query)
按条件过滤标量字段,返回完整实体:
python
# 查询指定主键的数据
results = collection.query(expr="book_id in [10, 20, 30]", output_fields=["book_id", "book_name"])
print(results)
# 带条件过滤的查询
results = collection.query(expr='book_name like "book_1%"', output_fields=["book_id", "book_name"])
5.2 向量相似度搜索(Search)
向量搜索是 Milvus 的核心功能,通过计算向量间的距离返回最相似的 Top-K 结果:
python
# 构造查询向量
query_vector = [[random.random() for _ in range(128)]]
# 搜索参数
search_params = {
"metric_type": "IP",
"params": {"ef": 64}
}
# 执行搜索
results = collection.search(
data=query_vector,
anns_field="book_vector",
param=search_params,
limit=10, # 返回 Top-10
output_fields=["book_id", "book_name"]
)
for hits in results:
for hit in hits:
print(f"ID: {hit.id}, 距离: {hit.distance}, 名称: {hit.entity.get('book_name')}")
5.3 混合检索(带标量过滤的向量搜索)
在实际业务中,往往需要在向量搜索的同时加上标量条件过滤,以缩小搜索范围、提升精度:
python
# 在向量搜索中附加标量过滤条件
results = collection.search(
data=query_vector,
anns_field="book_vector",
param=search_params,
limit=10,
expr='book_name like "book_1%"', # 标量过滤
output_fields=["book_id", "book_name"]
)
5.4 按主键获取向量
python
# 通过主键直接获取向量数据
results = collection.query(
expr="book_id == 10",
output_fields=["book_id", "book_vector"]
)
print(results[0]["book_vector"])
6. 完整示例:图书检索系统
下面是一个完整的示例,演示从建库、建集合、插入数据到向量检索的全流程:
python
from pymilvus import connections, CollectionSchema, FieldSchema, DataType, Collection, utility
import random
# 1. 连接服务
connections.connect(host="localhost", port="19530")
# 2. 创建集合
fields = [
FieldSchema(name="book_id", dtype=DataType.INT64, is_primary=True),
FieldSchema(name="book_name", dtype=DataType.VARCHAR, max_length=256),
FieldSchema(name="book_vector", dtype=DataType.FLOAT_VECTOR, dim=128)
]
schema = CollectionSchema(fields=fields, description="图书集合")
collection = Collection(name="book_demo", schema=schema)
# 3. 创建索引
collection.create_index(
field_name="book_vector",
index_params={"index_type": "HNSW", "metric_type": "IP", "params": {"M": 16, "efConstruction": 200}}
)
# 4. 插入数据
data = [
[i for i in range(1000)],
[f"book_{i}" for i in range(1000)],
[[random.random() for _ in range(128)] for _ in range(1000)]
]
collection.insert(data)
collection.flush()
# 5. 向量检索
collection.load() # 加载到内存
query_vector = [[random.random() for _ in range(128)]]
results = collection.search(
data=query_vector,
anns_field="book_vector",
param={"metric_type": "IP", "params": {"ef": 64}},
limit=5,
output_fields=["book_id", "book_name"]
)
for hits in results:
for hit in hits:
print(f"ID: {hit.id}, 距离: {hit.distance:.4f}, 书名: {hit.entity.get('book_name')}")
# 6. 清理
collection.release()
utility.drop_collection("book_demo")
7. 总结
8. Milvus 与 MySQL 对比
很多初学者会好奇:Milvus 和 MySQL 都是数据库,它们到底有什么区别?能否互相替代?下面从多个维度进行对比。
8.1 核心定位不同
| 维度 | MySQL | Milvus |
|---|---|---|
| 定位 | 关系型数据库(RDBMS) | 分布式向量数据库 |
| 数据模型 | 结构化表格数据(行 + 列) | 集合(Collection)+ 字段(Field) |
| 核心能力 | 事务处理、精确查询、复杂关联 | 海量向量相似度检索 |
| 典型场景 | 业务系统、订单、用户、账务 | 推荐系统、图像/文本/音频检索、RAG |
| 数据规模 | 千万级以内表现良好 | 十亿级向量毫秒级检索 |
8.2 数据模型对比
MySQL 使用「表(Table)+ 行(Row)+ 列(Column)」模型,数据必须遵循严格的 Schema,支持主键、外键、唯一约束等完整性约束。
Milvus 使用「集合(Collection)+ 字段(Field)」模型,字段类型包括标量类型(INT64、VARCHAR、BOOL 等)和向量类型(FLOAT_VECTOR、BINARY_VECTOR 等)。Milvus 2.x 还支持动态字段(Dynamic Field),允许插入未在 Schema 中预定义的字段,灵活性更高。
8.3 查询能力对比
MySQL 的查询基于 SQL,支持 WHERE 条件过滤、JOIN 多表关联、GROUP BY 聚合、ORDER BY 排序、事务(ACID)等完整的关系代数能力。
Milvus 的查询分为两类:
- 标量查询(Query) :类似 MySQL 的
WHERE过滤,但能力相对有限,不支持JOIN、聚合函数等复杂操作。 - 向量搜索(Search):MySQL 无法直接实现的能力,通过计算向量间的距离(如欧氏距离、内积、余弦相似度)返回最相似的 Top-K 结果。
8.4 索引机制对比
| 维度 | MySQL | Milvus |
|---|---|---|
| 索引类型 | B+Tree、Hash、FullText 等 | IVF_FLAT、HNSW、DISKANN、SCANN 等 |
| 索引目的 | 加速等值/范围查询 | 加速近似最近邻(ANN)搜索 |
| 是否必须 | 可选,用于优化性能 | 向量字段必须建索引才能搜索 |
| 索引构建 | 写入时自动维护 | 显式调用 create_index 构建 |
8.5 更新与删除对比
MySQL 支持完整的 INSERT、UPDATE、DELETE,支持事务回滚,数据一致性由 ACID 保证。
Milvus 的更新能力较弱:
- 支持
insert和delete,但不支持直接更新已有实体的字段值,需采用「先删后插」策略。 - 删除是逻辑删除,数据不会立即物理清除,需要后续 compaction 才能真正释放空间。
- 不支持事务,数据一致性模型与 MySQL 有本质区别。
8.6 适用场景建议
选择 MySQL 的场景:
- 需要强事务保证的业务系统(订单、支付、账务)。
- 需要复杂关联查询、聚合统计、报表分析。
- 数据量在千万级以内,以精确查询为主。
选择 Milvus 的场景:
- 需要基于向量做相似度检索(语义搜索、以图搜图、推荐召回)。
- 构建 RAG(检索增强生成)应用,为 LLM 提供知识库检索。
- 数据量达到亿级甚至十亿级,需要分布式水平扩展。
8.7 两者可以互补
在实际生产系统中,Milvus 与 MySQL 并非二选一,而是经常配合使用:
- MySQL 存储业务元数据(用户信息、订单、商品详情等)。
- Milvus 存储向量数据(文本 Embedding、图像特征等)。
- 检索时先用 Milvus 做向量召回,再用 MySQL 中的主键回表查询完整业务数据。
这种「MySQL + Milvus」的混合架构,既能利用 MySQL 的事务与精确查询能力,又能发挥 Milvus 的向量检索优势,是当前 AI 应用的主流实践。
本文系统介绍了 Milvus 向量数据库的三大类操作:
| 类别 | 操作 | 说明 |
|---|---|---|
| DDL | 创建/删除数据库、集合、索引 | 管理数据结构 |
| DML | 插入、删除、更新数据 | 管理数据内容 |
| DQL | 标量查询、向量搜索、混合检索 | 检索与分析数据 |
核心要点:
- Milvus 的集合(Collection)对应关系型数据库的表,字段(Field)对应列。
- 向量搜索必须提前创建索引,否则无法执行。
- 更新操作采用「先删后插」策略。
- 混合检索(向量 + 标量过滤)是生产环境中最常用的检索模式。
掌握 DDL、DML、DQL 三类操作,是熟练使用 Milvus 构建 AI 应用的基础。希望本文能帮助你快速上手 Milvus 向量数据库。