# 向量的存储检索
#### 操作场景
在企业级应用中，随着业务数据量的快速增长，高效向量检索的需求日益迫切。然而，传统的"关系数据库 + 独立向量数据库"的分离式架构，导致了数据同步复杂、维护成本高、系统一致性差等问题。为满足企业级场景下对向量检索能力的需求，数据库支持向量索引已逐渐成为重要的发展方向。
向量（Vector）是将文本、图像等非结构化数据通过嵌入模型映射到高维数值空间后得到的浮点数序列，向量空间中语义相近的数据点彼此距离更近，因此可通过计算向量间的距离来衡量数据的语义相似性，广泛用于语义搜索、推荐系统等场景。然而随着数据规模增长，对海量高维向量进行精确最近邻搜索面临维度灾难，计算复杂度难以满足实时性要求，向量索引由此应运而生。TaurusDB 采用 HNSW（Hierarchical Navigable Small World）算法构建向量索引，通过多层级导航小世界图实现对数级时间复杂度的近似最近邻搜索，并支持欧氏距离（Euclidean Distance）和余弦距离（Cosine Distance）两种距离度量方式。
TaurusDB通过支持向量索引，为企业级应用提供了高效、一致且易于维护的向量检索解决方案。相比传统的分离式架构，TaurusDB 能够在统一的数据存储与事务体系下，实现结构化数据与向量数据的一体化管理与联合查询，从而减少多系统间的数据同步与维护成本，显著提升系统一致性、查询效率以及整体运维稳定性。
#### 版本约束
TaurusDB实例内核版本大于等于2.0.78.260602，支持原生向量。内核版本的查询方法请参见[如何查看云数据库 TaurusDB实例的版本号](https://support.huaweicloud.com/taurusdb_faq/taurusdb_faq_0141.html)。
#### 原理介绍
向量（Vector）是将文本、图片等非结构化数据通过嵌入模型（Embedding Model）转换得到的一组高维数值。语义相近的数据通常会映射到向量空间中相近的位置，因此可以通过计算向量之间的距离来衡量数据的相似度。TaurusDB 当前支持欧氏距离（L2）和余弦距离（Cosine）两种距离度量方式。
传统 B+Tree 索引适用于精确匹配和范围查询，但无法高效支持高维向量的相似度检索。为此，TaurusDB 引入 HNSW（Hierarchical Navigable Small World）向量索引，通过构建多层近邻图来组织向量数据。查询时，从高层入口节点开始逐层搜索，快速定位与目标向量最接近的候选节点，最终返回 Top-K 相似结果。
在存储层面，每个向量索引对应一张隐藏的辅助表，用于持久化保存 HNSW 图节点及邻接关系。这样可以直接复用 InnoDB 的事务、恢复和锁机制，无需额外设计专用存储引擎，在保证数据一致性的同时提供高效的向量检索能力。
#### 约束与限制
表1约束限制 
| 类别        | 约束和限制                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
|:---|:---|
| 存储与引擎  | 仅支持 InnoDB 存储引擎，事务上只支持READ-COMMITTED隔离级别，与辅助表持久化机制关联。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| 向量属性     | - 向量维度最大为 16383，最小为 1，实际应用中通常 \>= 8。  - 向量精度为IEEE 754 单精度浮点 (32 位)。  - 向量列可以为 NULL，但不会写入索引。向量索引要求向量列有确定的值，NULL 无法参与距离计算。  - 向量列中存在 NaN 或 Inf 值时，写入失败，无法计算距离。  - 0向量和任何向量的余弦距离规定为1。                                                                                                                                                                                                                              |
| 向量索引     | - 使用 HNSW 算法，这是一种业界验证的高效近似最近邻 (ANN) 算法，支持欧式距离与余弦距离，召回率高。  - 向量索引不可设置为INVISIBLE，始终参与优化器决策。  - 单表可以创建多个向量列，但只能创建一个单列向量索引，不支持联合索引。  - 向量索引仅对带 LIMIT 的查询生效。  - 向量索引只支持ASC排序。                                                                                                                                                                                                                                               |
| 表类型与DDL操作 | - 带向量索引的表不支持分区表和临时表。  - 向量索引创建和删除需重建辅助表，用于存储 HNSW 图的节点和邻居关系。每个带向量索引的基表都会创建一个对应的辅助表，不支持在线 DDL 操作。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| 功能限制    | - 在源数据库中的存储过程、函数中使用 vector 类型，会导致迁移到不支持向量的目标数据库失败。  - 只读节点不支持向量索引。  - 不支持向量表的冷热分离和闪回功能。  - 包含向量索引的表不支持回收站功能。  - 当前不支持向量表的并行查询（PQ）功能。  - DRS暂未支持向量功能，如因开启向量功能导致全量迁移失败，请[提交工单](https://console.huaweicloud.com/ticket/?locale=zh-cn#/ticketindex/createIndex)联系客服处理。   |
   
#### 向量参数说明
除transaction_isolation外，其余参数如需修改，请[提交工单](https://console.huaweicloud.com/ticket/?locale=zh-cn#/ticketindex/createIndex)。
表2向量参数 
| **参数名称**                     | 参数类型             | **参数说明**                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
|:---|:---|:---|
| transaction_isolation       | String             | 事务隔离级别。向量操作仅支持READ-COMMITTED隔离级别，其余隔离级别不支持。                                                                                                                                                                                                                                                                                                                                                                                                                |
| rds_vidx_disabled            | GLOBAL_BOOL       | 向量功能开关，默认值为ON。 - ON：禁用向量功能。  - OFF：开启向量功能。                                                                           |
| rds_vidx_default_distance | SESSION_ENUM       | 距离类型，默认值为EUCLIDEAN。 - EUCLIDEAN：欧式距离。  - COSINE：余弦距离。   |
| rds_vidx_hnsw_default_m    | SESSION_UINT      | HNSW参数M，图节点的邻居数量，默认值为6。 取值范围：3\~200。                                                                                                                                                                                                                                                                                                                                        |
| rds_vidx_hnsw_ef_search   | SESSION_UINT     | 搜索时的队列大小，默认值为20。 取值范围：1\~10000。                                                                                                                                                                                                                                                                                                                                              |
| rds_vidx_hnsw_cache_size  | GLOBAL_ULONGLONG | HNSW缓存大小限制（单位：字节），默认值为16MB。 取值范围：1MB\~1GB。                                                                                                                                                                                                                                                                                                                                    |
   
#### 向量函数
- 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;
  ```
  
 
#### 使用示例
1. [提交工单](https://console.huaweicloud.com/ticket/?locale=zh-cn#/ticketindex/createIndex)，联系客服开启向量功能。
2. 设置隔离级别。
   ```
   SET transaction_isolation = 'READ-COMMITTED';
   ```
   
3. 创建表和向量索引。
   ```
   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
   );
   ```
   
4. 插入数据。
   ```
   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]'));
   ```
   
5. 进行向量相似度查询。
   ```
   -- 查找与给定向量 '[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;
   ```
   
 
