背景
今年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],默认20OUT_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;");
索引命中条件
为确保查询能利用向量索引,需满足以下条件:
- 查询必须是
ORDER BY + LIMIT
类型 ORDER BY
只能有一个向量距离排序条件- 不能使用
DESC
降序 - 查询距离度量必须与索引创建时一致
磁盘碎片管理
从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驱动的应用开发中占据先机。