向量存储检索
操作场景
在企业级应用中,随着业务数据量的快速增长,高效向量检索的需求日益迫切。然而,传统的“关系数据库 + 独立向量数据库”分离式架构存在数据同步复杂、维护成本高、系统一致性差等问题。为满足企业级场景对向量检索能力的需求,数据库支持向量索引已成为重要的发展方向。
向量(Vector)是将文本、图像等非结构化数据通过嵌入模型映射到高维数值空间后得到的浮点数序列。在向量空间中,语义相近的数据点彼此距离更近,因此可通过计算向量间的距离来衡量数据的语义相似性。该技术广泛应用于语义搜索、推荐系统等场景。然而随着数据规模增长,对海量高维向量进行精确最近邻搜索面临维度灾难,计算复杂度难以满足实时性要求,向量索引由此应运而生。RDS采用HNSW(Hierarchical Navigable Small World)算法构建向量索引,通过多层级导航小世界图实现对数级时间复杂度的近似最近邻搜索,并支持欧氏距离(Euclidean Distance)和余弦距离(Cosine Distance)两种距离度量方式。
RDS借助支持向量索引,为企业级应用提供高效、一致且易于维护的向量检索方案。相比传统的分离式架构,RDS在统一的数据存储与事务体系下,实现结构化数据与向量数据的一体化管理及联合查询,从而降低多系统间的数据同步与维护成本,显著提升系统一致性、查询效率以及整体运维稳定性。
版本约束
RDS实例内核版本大于等于8.0.43.260600,支持原生向量。
原理介绍
向量(Vector)是将文本、图片等非结构化数据通过嵌入模型(Embedding Model)转换得到的一组高维数值。语义相近的数据通常会映射到向量空间中相近的位置,因此可以通过计算向量之间的距离来衡量数据的相似度。RDS当前支持欧氏距离(L2)和余弦距离(Cosine)两种距离度量方式。
传统B+Tree索引适用于精确匹配和范围查询,但无法高效支持高维向量的相似度检索。为此,RDS引入HNSW(Hierarchical Navigable Small World)向量索引,通过构建多层近邻图来组织向量数据。查询时,从高层入口节点开始逐层搜索,快速定位与目标向量最接近的候选节点,最终返回Top-K相似结果。
在存储层面,每个向量索引对应一张隐藏的辅助表,用于持久化保存HNSW图节点及邻接关系。这样可以直接复用InnoDB的事务、恢复和锁机制,无需额外设计专用存储引擎,在保证数据一致性的同时提供高效的向量检索能力。
约束与限制
| 类别 | 约束和限制 |
|---|---|
| 存储与引擎 | 仅支持InnoDB存储引擎,事务上只支持READ-COMMITTED隔离级别,与辅助表持久化机制关联。 |
| 向量属性 |
|
| 向量索引 |
|
| 表类型与DDL操作 |
|
| 功能限制 |
|
向量参数说明
| 参数名 | 参数类型 | 取值范围 | 默认值 | 说明 |
|---|---|---|---|---|
| transaction_isolation | String | READ-UNCOMMITTED/READ-COMMITTED/REPEATABLE-READ/SERIALIZABLE | READ-COMMITTED | 事务隔离级别。向量操作仅支持READ-COMMITTED隔离级别,其余隔离级别不支持。 |
| rds_vidx_disabled | GLOBAL_BOOL | ON/OFF | ON | 向量功能开关。
|
| rds_vidx_default_distance | SESSION_ENUM | EUCLIDEAN/COSINE | EUCLIDEAN | 默认距离类型。
|
| rds_vidx_hnsw_default_m | SESSION_UINT | 3~200 | 6 | HNSW参数M,图节点的邻居数量。 |
| rds_vidx_hnsw_ef_search | SESSION_UINT | 1~10000 | 20 | 搜索时的队列大小。 |
| rds_vidx_hnsw_cache_size | GLOBAL_ULONGLONG | 1MB~1GB | 16MB | HNSW缓存大小限制。 |
向量函数
- VEC_FROMTEXT(str)
- 描述
将JSON数组格式的文本字符串转换为二进制VECTOR值。例如将 '[1.0, 2.0, 3.0]' 转为内部浮点数序列的二进制表示。最大支持16383维。
- 别名:
TO_VECTOR、STRING_TO_VECTOR,功能与VEC_FROMTEXT完全相同。
- 参数说明:
str:VARCHAR类型,JSON数组格式的字符串,如 '[1.0, 2.0, 3.0]'。不支持JSON类型或Geometry类型参数。
- 描述
- VEC_TOTEXT(vector)
- 描述:
将二进制VECTOR值转换为JSON数组格式的文本字符串,返回如 '[1.0, 2.0, 3.0]' 的可读文本,字符集为utf8mb4_0900_bin。
- 别名:
FROM_VECTOR、VECTOR_TO_STRING,功能与VEC_TOTEXT完全相同。
- 参数说明:
vector:VECTOR类型(二进制字符串),即内部存储的向量值。
- 描述:
- VEC_DISTANCE(v1, v2)
- 描述:
计算两个向量之间的距离。自动根据列上定义的VECTOR INDEX的距离度量类型来选择计算方式:
若索引为EUCLIDEAN则计算L2距离,若为COSINE则计算余弦距离。
如果找不到适用的向量索引,则报错。当任一输入为NULL、维度不匹配、或计算结果非有限值时返回NULL。
- 参数说明:
- v1:VECTOR类型,第一个向量,必须是向量索引列(用于索引查找优化)。
- v2:VECTOR类型,第二个向量,常量,两个向量的维度必须一致。
- 描述:
- VEC_DISTANCE_EUCLIDEAN(v1, v2)
- 描述:
计算两个向量之间的欧几里得距离(L2 距离),公式为sqrt(sum((v1[i] - v2[i])²))。当任一输入为NULL、维度不匹配、或计算结果非有限值时返回NULL。
- 参数说明:
v1、v2:VECTOR 类型,两个向量都是任意向量表达式(常量、有索引向量列、无索引向量列),且维度必须一致。
- 描述:
- VEC_DISTANCE_COSINE(v1, v2)
- 描述:
计算两个向量之间的余弦距离,公式为 1 - dot(v1, v2) / (|v1| × |v2|)。当任一输入为NULL、维度不匹配、或计算结果非有限值时返回NULL。
- 参数说明:
v1、v2:VECTOR 类型,两个向量都是任意向量表达式(常量、有索引向量列、无索引向量列),且维度必须一致。
- 描述:
- VECTOR_DIM(vector)
- 描述:
返回向量的维度数(即浮点元素的个数)。计算方式为二进制长度除以 sizeof(float)(4 字节)。
- 参数说明:
vector:VECTOR类型(二进制字符串),即内部存储的向量值。返回BIGINT类型。
- 描述:
创建向量列
在CREATE TABLE或ALTER TABLE语句中使用VECTOR(N)类型定义N维向量列。
其中N表示维度,N∈[1,16383]。
- 创建包含向量列的新表。
CREATE TABLE items ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), embedding VECTOR(128) ); - 将向量列添加到现有表中。
ALTER TABLE products ADD COLUMN description_vec VECTOR(64);
使用向量索引
- 创建HNSW向量索引。
CREATE VECTOR INDEX idx ON t(v)
示例:
在表items的向量列embedding上创建名为 vidx 的向量索引,使用默认参数。
CREATE VECTOR INDEX vidx ON items(embedding);
- 指定索引参数,指定邻居数M和距离类型。
CREATE VECTOR INDEX idx ON t(v) M=N DISTANCE=metric
示例:
在表items的向量列embedding上创建索引vidx,指定每个节点最大连接数M为16,距离类型为余弦距离。
CREATE VECTOR INDEX vidx ON items(embedding) M=16 DISTANCE=COSINE;
- 建表时创建向量索引。
CREATE TABLE t(..., VECTOR INDEX(v))
示例:
创建表items,包含自增主键id、128维向量列embedding,并同时创建名为vidx的向量索引,指定M=16,距离类型为欧式距离。
CREATE TABLE items ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, embedding VECTOR(128), VECTOR INDEX vidx(embedding) M=16 DISTANCE=EUCLIDEAN ); - 删除向量索引。
ALTER TABLE t DROP VECTOR INDEX idx
示例:
删除表items上的向量索引vidx。
ALTER TABLE items DROP INDEX vidx;
向量查询
- 向量排序查询,返回Top-N相似向量。
SELECT * FROM t ORDER BY VEC_DISTANCE(v, query_vec) LIMIT N
示例:
查询表items中与向量 [1.0, 0.5, 0.8, ...] 最相似的前10条记录,embedding为向量列,VEC_FROMTEXT('[1.0,0.5,0.8,0.2,0.3]') 将文本转为查询向量。
SELECT * FROM items ORDER BY VEC_DISTANCE(embedding, VEC_FROMTEXT('[1.0,0.5,0.8,0.2,0.3]')) LIMIT 10; - 混合条件查询,先过滤后排序,结合标量条件。
SELECT * FROM t WHERE category='A' ORDER BY VEC_DISTANCE(v, query_vec) LIMIT N
示例:
查询表items中category为 'electronics' 且与查询向量最相似的前5条记录,先按category过滤再按向量距离排序。
SELECT * FROM items WHERE category = 'electronics' ORDER BY VEC_DISTANCE(embedding, VEC_FROMTEXT('[1.0,0.5,0.8,0.2,0.3]')) LIMIT 5; - 显示计算的距离值。
SELECT id, VEC_DISTANCE(v, query_vec) AS dist FROM t ORDER BY dist LIMIT N
示例:
查询表items中与查询向量最相似的前10条记录,并显示每条记录的id和距离值dist。
SELECT id, VEC_DISTANCE(embedding, VEC_FROMTEXT('[1.0,0.5,0.8,0.2,0.3]')) AS dist FROM items ORDER BY dist LIMIT 10; - 强制使用向量索引。
SELECT * FROM t FORCE INDEX(vidx) ORDER BY VEC_DISTANCE(v, query_vec)
示例:
强制使用向量索引vidx查询表items中与查询向量最相似的前10条记录。
SELECT * FROM items FORCE INDEX(vidx) ORDER BY VEC_DISTANCE(embedding, VEC_FROMTEXT('[1.0,0.5,0.8,0.2,0.3]')) LIMIT 10;
使用示例
- 提交工单开启向量功能。
- 设置隔离级别。
SET transaction_isolation = 'READ-COMMITTED';
- 创建表和向量索引。
CREATE TABLE product_embeddings ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, product_name VARCHAR(255), embedding VECTOR(5) NOT NULL, -- 创建向量索引,并指定M值和距离计算方式 VECTOR INDEX idx_embedding(embedding) M=16 DISTANCE=COSINE );
- 插入数据。
INSERT INTO product_embeddings (product_name, embedding) VALUES ('product_A', VEC_FROMTEXT('[0.1, 0.2, 0.3, 0.4, 0.5]')), ('product_B', VEC_FROMTEXT('[0.6, 0.7, 0.8, 0.9, 1.0]')), ('product_C', VEC_FROMTEXT('[0.11, 0.22, 0.33, 0.44, 0.55]')); - 进行向量相似度查询。
-- 查找与给定向量 '[0.1, 0.2, 0.3, 0.4, 0.51]' 最相似的2个商品 SELECT id, product_name, VEC_DISTANCE(embedding, VEC_FROMTEXT('[0.1, 0.2, 0.3, 0.4, 0.51]')) AS similarity_score FROM product_embeddings ORDER BY similarity_score ASC -- COSINE距离越小越相似 LIMIT 2;