HarmonyOS Next数据底座向量数据库介绍

背景

今年HDC在展厅遇见了HarmonyOS 数据底座的架构师,介绍了基于数据底座实现端侧能力的智能小助手,听着很吸引人,HarmonyOS将端侧AI做到了系统层,给开发者创造了无限可能。回来后赶紧看了下更新的文档,HarmonyOS提供了ArkTS与C++两种语言接口。本文将深入探讨向量数据库的技术特性、核心概念、操作接口以及高级功能,帮助开发者全面掌握这一新兴技术。

向量数据库概述

向量数据库是一种支持存储、管理和检索向量数据的数据库系统,同时兼容传统的关系型数据处理能力。其核心数据类型floatvector用于存储向量化结果,使得系统能够高效实现相似性搜索和快速检索功能。

从API version 18开始,向量数据库正式支持通过标准化接口实现数据持久化,为开发者提供了可靠的数据存储解决方案。

基本概念与架构

结果集机制

查询操作返回的结果集合称为结果集(ResultSet)​,它提供了灵活的数据访问方式,使开发者能够方便地获取所需数据。结果集采用惰性加载策略,只有在实际访问数据时才会从存储层加载,有效降低了内存消耗。

向量数据表示

floatvector是向量数据库的核心数据类型,用于表示高维向量数据。例如[1.0, 3.0, 2.4, 5.1, 6.2, 11.7]这样的数值数组就是典型的向量表示形式,广泛应用于图像识别、自然语言处理等领域。

系统约束与限制

向量数据库在设计上考虑了性能与资源平衡,设置了以下关键约束:

  • 日志模式​:默认采用WAL(Write Ahead Log)模式,确保数据写入的原子性和持久性
  • 落盘策略​:FULL模式保证数据完整写入存储介质
  • 连接管理​:系统默认维护4个读连接和1个写连接,采用连接池技术优化资源使用
  • 写入并发​:同一时间只支持一个写操作,并发写请求会自动串行化处理
  • 数据大小限制​:建议单条数据不超过2MB,超出可能导致读取失败

数据清理机制

当应用被卸载时,设备上的相关数据库文件及临时文件会被自动清除,这种设计简化了应用生命周期管理,避免了残留文件问题。

数据类型与约束

支持的数据类型

向量数据库支持丰富的字段类型,满足多样化的数据存储需求:

类型 描述 是否支持
NULL 空值
INTEGER 整形
DOUBLE 浮点类型
TEXT 字符串类型
BLOB 二进制类型
FLOATVECTOR 向量数据类型

3.2 字段约束机制

为保证数据完整性,系统提供多种字段约束:

  • NOT NULL​:确保字段不为空
  • DEFAULT​:设置字段默认值
  • UNIQUE​:保证字段值唯一性
  • PRIMARY KEY​:定义主键索引

注意:系统目前不支持外键约束(FOREIGN)和CHECK约束。

查询语言特性

查询子句支持

向量数据库支持丰富的SQL查询子句:

  • WHERE​:条件过滤
  • LIMIT​:结果数量限制
  • ORDER BY​:多列排序,特别支持向量距离排序
  • GROUP BY​:数据分组
  • HAVING​:聚合结果过滤
  • INDEXED BY​:强制使用特定索引
  • DISTINCT​:去重(暂不支持)

特别值得注意的是向量距离排序功能,支持两种距离度量:

  • <->:L2欧式距离
  • <=>:余弦相似度

集合操作

支持标准的集合操作:

  • UNION​:合并结果并去重
  • UNION ALL​:合并结果保留重复项

运算符体系

系统提供全面的运算符支持:

  • 算术运算​:+、-、*、/、%
  • 比较运算​:==、=、!=、>、>=、<、<=
  • 逻辑运算​:AND、BETWEEN、EXISTS等12种
  • 字符串拼接​:||
  • 位运算​:&、|、~、<<、>>
  • 向量距离运算​:<->、<=>(支持在聚合函数中使用)

时间与日期函数

内置多种时间处理函数:

函数 描述 格式
DATE 日期 "YYYY-MM-DD"
TIME 时间 "HH:MM:SS"
DATETIME 日期时间 "YYYY-MM-DD HH:MM:SS"
JULIANDAY 儒略日 天数
STRFTIME 格式化日期 自定义格式

聚合与分析函数

系统提供丰富的分析函数:

  • COUNT​:行数统计
  • MAX/MIN​:极值计算
  • AVG​:平均值
  • SUM​:总和
  • RANDOM​:随机数生成
  • ABS​:绝对值
  • UPPER/LOWER​:字符串大小写转换
  • LENGTH​:字符串长度

这些函数可与向量操作结合,实现复杂的数据分析需求。

开发接口与实践

环境检测与初始化

开发第一步是检测系统是否支持向量数据库:

import { relationalStore } from '@kit.ArkData';
import { UIAbility } from '@kit.AbilityKit';

class EntryAbility extends UIAbility {
  async onWindowStageCreate(windowStage: window.WindowStage) {
    let ret = relationalStore.isVectorSupported();
    if (!ret) {
      console.error(`vectorDB is not supported.`);
      return;
    }
    // 初始化数据库
  }
}

数据库创建与配置

通过getRdbStore接口创建数据库实例:

const STORE_CONFIG: relationalStore.StoreConfig = {
  name: 'VectorTest.db',
  securityLevel: relationalStore.SecurityLevel.S1,
  vector: true // 启用向量支持
};

relationalStore.getRdbStore(this.context, STORE_CONFIG)
  .then(async (rdbStore) => {
    // 建表操作
    const SQL_CREATE_TABLE = 'CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY, repr floatvector(2));';
    await rdbStore.execute(SQL_CREATE_TABLE, 0, undefined);
  })
  .catch((err) => {
    console.error(`Get RdbStore failed: ${err.code}, ${err.message}`);
  });

数据操作实践

插入数据

支持参数绑定和非绑定两种方式:

// 参数绑定方式
const vectorValue: Float32Array = Float32Array.from([1.2, 2.3]);
await store.execute("insert into test VALUES(?, ?);", 0, [0, vectorValue]);

// 非绑定方式
await store.execute("insert into test VALUES(1, '[1.3, 2.4]');", 0, undefined);
更新与删除
// 向量更新
const vectorValue1: Float32Array = Float32Array.from([2.1, 3.2]);
await store.execute("update test set repr = ? where id = ?", 0, [vectorValue1, 0]);

// 数据删除
await store.execute("delete from test where id = ?", 0, [0]);

查询操作

基础查询
// 参数化查询
const vectorValue2: Float32Array = Float32Array.from([6.2, 7.3]);
let resultSet = await store.querySql(
  "select id, repr <-> ? as distance from test where id > ? order by repr <-> ? limit 5;",
  [vectorValue2, 0, vectorValue2]
);

while (resultSet.goToNextRow()) {
  let id = resultSet.getValue(0);
  let dis = resultSet.getValue(1);
}
resultSet.close();
子查询与聚合
// 子查询示例
let resultSet = await store.querySql(
  "select * from test where id in (select id from test1);"
);
resultSet.close();

// 聚合查询
resultSet = await store.querySql(
  "select * from test where repr <-> '[1.0, 1.0]' > 0 group by id having max(repr <=> '[1.0, 1.0]');"
);
resultSet.close();

高级特性

向量索引优化

向量索引是提升查询性能的关键技术,系统支持以下索引类型:

索引类型 描述 适用场景
gsdiskann 高维稠密向量索引 文本嵌入、图像特征等
索引创建语法

基础语法:

CREATE INDEX [IF NOT EXISTS] index_name ON table_name USING index_type (column_name dist_function);

扩展语法(带参数):

CREATE INDEX [基础语法] WITH(parameter = value [, ...]);

参数配置:

  • QUEUE_SIZE:[10,1000],默认20
  • OUT_DEGREE:[1,1200],默认60
索引管理示例
// 创建L2距离索引
await store.execute(
  "CREATE INDEX diskann_l2_idx ON test USING GSDISKANN(repr L2);"
);

// 带参数的索引创建
await store.execute(
  "CREATE INDEX diskann_l2_idx ON test USING GSDISKANN(repr L2) WITH (queue_size=20, out_degree=50);"
);

// 删除索引
await store.execute("DROP INDEX test.diskann_l2_idx;");

索引命中条件

为确保查询能利用向量索引,需满足以下条件:

  1. 查询必须是ORDER BY + LIMIT类型
  2. ORDER BY只能有一个向量距离排序条件
  3. 不能使用DESC降序
  4. 查询距离度量必须与索引创建时一致

磁盘碎片管理

从API version 20开始支持手动碎片回收:

// 手动触发碎片回收
await store.execute("PRAGMA DISKANN_ASYNC_COLLECTING;");

此功能解决了以下场景的问题:

  • 删除向量后立即关闭数据库
  • 批量删除后无后续操作

数据管理策略

数据老化配置

通过建表参数实现自动化数据清理:

参数 必填 说明
time_col 时间列名(整数类型)
interval 老化检查间隔(默认1天)
ttl 数据保留时间(默认3月)
max_num 最大数据量限制(默认1024)

示例配置:

await store.execute(
  "CREATE TABLE test2(rec_time integer not null) WITH (time_col = 'rec_time', interval = '5 minute');"
);

数据压缩功能

支持对TEXT类型列进行压缩存储:

await store.execute(
  "CREATE TABLE IF NOT EXISTS test3 (time integer not null, content text) with (time_col = 'time', interval = '5 minute', compress_col = 'content');"
);

总结与展望

向量数据库作为新兴的数据管理技术,正在重塑AI时代的数据基础设施。本文详细介绍了向量数据库的核心特性、开发接口和高级功能,为开发者提供了全面的技术指南。

随着大模型和生成式AI的普及,向量数据库的重要性将进一步提升。未来,我们可以期待看到更智能的索引算法、更高效的查询优化以及更紧密的AI框架集成,使向量数据库成为AI原生应用的核心组件。

开发者应密切关注向量数据库技术的发展,掌握其核心原理和使用技巧,从而在AI驱动的应用开发中占据先机。

你可能感兴趣的:(HarmonyOS Next数据底座向量数据库介绍)