Vector Index
名词定义
名词 |
定义 |
|---|---|
Table |
Dingo's Table. |
IndexDefinition |
Dingo 的索引定义。 |
Index |
Dingo 的索引相当于键值存储,特别适用于向量类型的索引。对于向量索引,它会存储完整的向量、向量 UUID 和向量元数据。它利用 Faiss 等第三方库生成向量索引。 |
架构设计
添加 Dingo-Index 后的新 DingoDB 整体组件图:
在DingoDB的整体语义中,新增了与Table同级的Index概念,Coordinator也相应地增强了Index管理和gRPC接口。
在第一次迭代中,暂时只支持 VectorIndex。随后的迭代将支持标量索引。
使用 CreateTable 创建表格时,增加了对同时创建索引的支持。
新增了对 CreateIndex 的支持,允许用户在一般向量数据库中直接使用 Index 作为集合概念,就像使用 Milvus 和 Chroma 等纯向量数据库一样。
通过这种设计,DingoDB 可以像 pgvector 和 clickhouse 一样在 Vector 上实现 SQL,同时也可以像 Milvus 一样将向量作为一等公民使用。
DW Proxy 是一个用于实现 Table+Index 双写法的组件,其独立存在性尚待确定。
新的输入/输出工作流程
表格创建过程
不带索引的 CreateTable 进程与 0.6.0 版相同。带索引的 CreateTable 进程如下:
简单地说,Coordinator 为存储和索引组件创建 Region。
具体流程如下:
由于 DingoDB 目前的设计限制,如果用户想使用带有索引的表,就必须在创建表时声明索引。
用户通过 SQL 客户端执行 SQL 语句,类似于以下语句(SQL 语句的具体格式需要稍后设计,以下语句仅供参考):
CREATE TABLE items
(id integer PRIMARY KEY,
name varchar2(256),
embedding vector(1024)),
INDEX vec_index1 (embedding) WITH (index_type=ivfflat, distance=l2, nlists=1024)),
INDEX name_index1 (name) WITH (index_type=lsm);
在上面的 SQL 语句中,用户创建了一个包含三个字段的表,其中 “embedding ”字段是一个 1024 维向量。同时,用户声明创建两个索引:一个是基于 “embedding ”字段的向量索引,使用 Ivfflat 索引类型、欧氏距离和 1024 nlists;另一个是基于 “name ”字段的标量索引,使用 LSM 索引类型。
Executor 根据用户传入的创建表语句生成 gRPC 消息,调用Coordinator 的 CreateTable 接口。由于用户要求创建一个索引,因此除了 TableDefinition 之外,还需要生成一个 IndexDefinition。在上面的示例中,需要生成两个 IndexDefinition。
接收到 CreateTable 的 gRPC 请求后,Coordinator 会解析 TableDefinition 和 IndexDefinition,并分别调用存储节点和索引节点来执行 CreateRegion 和 CreateIndexRegion 操作。
存储区遵循与 0.6.0 版相同的 CreateRegion 流程,而索引则完成 CreateIndexRegion 流程,如上图所示。
数据读写过程(向量检索 SQL)
无索引表的读写过程与 0.6.0 版完全相同。
对于有索引的表,Executor 需要处理双重写入问题。在查询数据时,Executor 会根据表的定义生成一个执行计划,以确定是否需要进行索引查询。如果需要索引查询,Executor 就会向索引组件发起查询。
数据读写过程(仅向量)
对于只涉及链的情况,则不需要 SQL 组件。因此,如果用户只需要向量的功能,可以直接使用索引。
下图说明,SDK 客户端可以利用 CreateIndex 函数直接使用索引向量存储。在读写过程中,数据操作使用特定于索引的接口(如 Get 和 Put)进行。
在这种情况下,我们可以参考主要向量数据库实现的各种 API,以满足各种向量搜索操作的要求。