type
status
date
slug
summary
tags
category
icon
password
概述
数据存储,即应用数据持久化,是指应用将内存中的数据通过文件或数据库的形式保存到设备上。内存中的数据形态通常是任意的数据结构或数据对象,存储介质上的数据形态可能是文本、数据库、二进制文件等。HarmonyOS标准系统支持典型的存储数据形态,包括用户首选项、键值型数据库、关系型数据库。
- 用户首选项(Preferences):通常用于保存应用的配置信息。数据通过文本的形式保存在设备中,应用使用过程中会将文本中的数据全量加载到内存中,所以访问速度快、效率高,但不适合需要存储大量数据的场景。
- 键值型数据库(KV-Store):一种非关系型数据库,其数据以“键值”对的形式进行组织、索引和存储,其中“键”作为唯一标识符。适合很少数据关系和业务关系的业务数据存储,同时因其在分布式场景中降低了解决数据库版本兼容问题的复杂度,和数据同步过程中冲突解决的复杂度而被广泛使用。相比于关系型数据库,更容易做到跨设备跨版本兼容。
- 关系型数据库(RelationalStore):一种关系型数据库,以行和列的形式存储数据,广泛用于应用中的关系型数据的处理,包括一系列的增、删、改、查等接口,开发者也可以运行自己定义的SQL语句来满足复杂业务场景的需要。
一、用户首选项
用户首选项Preferences,类似于Android中的SharedPreferences,为应用提供Key-Value键值型的数据存储能力,常用于轻量级的数据存储,如应用配置。进程中每个文件对应一个Preferences实例,应用获取到实例后,可以从中读取数据,或者将数据存入实例中。通过调用flush方法可以将实例中的数据回写到文件里。
1.1 首选项与非关系数据库的对比
分类 | 关系型数据库 | 用户首选项 |
数据库类型 | 关系型 | 非关系型,不保证遵循ACID(Atomicity, Consistency, Isolation and Durability)特性,数据之间无关系 |
使用场景 | 提供复杂场景下的本地数据库管理机制 | 对Key-Value结构的数据进行存取和持久化操作 |
存储方式 | SQLite数据库 | 文件 |
约束与限制 | 1.连接池最大4个
2.同一时间只支持一个写操作 | 1.建议数据不超一万条
2.Key为string型 |
1.2 接口说明
以下是用户首选项持久化功能的相关接口,大部分为异步接口。异步接口均有callback和Promise两种返回形式,下表均以callback形式为例,更多接口及使用方式请见用户首选项。
接口名称 | 描述 |
getPreferences(context: Context, name: string, callback: AsyncCallback<Preferences>): void | 获取Preferences实例。 |
put(key: string, value: ValueType, callback: AsyncCallback<void>): void | 将数据写入Preferences实例,可通过flush将Preferences实例持久化。 |
has(key: string, callback: AsyncCallback<boolean>): void | 检查Preferences实例是否包含名为给定Key的存储键值对。给定的Key值不能为空。 |
get(key: string, defValue: ValueType, callback: AsyncCallback<ValueType>): void | 获取键对应的值,如果值为null或者非默认值类型,返回默认数据defValue。 |
delete(key: string, callback: AsyncCallback<void>): void | 从Preferences实例中删除名为给定Key的存储键值对。 |
flush(callback: AsyncCallback<void>): void | 将当前Preferences实例的数据异步存储到用户首选项持久化文件中。 |
on(type: 'change', callback: Callback<{ key : string }>): void | 订阅数据变更,订阅的Key的值发生变更后,在执行flush方法后,触发callback回调。 |
off(type: 'change', callback?: Callback<{ key : string }>): void | 取消订阅数据变更。 |
deletePreferences(context: Context, name: string, callback: AsyncCallback<void>): void | 从内存中移除指定的Preferences实例。若Preferences实例有对应的持久化文件,则同时删除其持久化文件。 |
1.3 示例
二、键值型数据库
2.1 场景介绍
键值型数据库存储键值对形式的数据,当需要存储的数据没有复杂的关系模型,比如存储商品名称及对应价格、员工工号及今日是否已出勤等,由于数据复杂度低,更容易兼容不同数据库版本和设备类型,因此推荐使用键值型数据库持久化此类数据。
2.2 约束限制
- 设备协同数据库,针对每条记录,Key的长度≤896 Byte,Value的长度<4 MB。
- 单版本数据库,针对每条记录,Key的长度≤1 KB,Value的长度<4 MB。
- 每个应用程序最多支持同时打开16个键值型分布式数据库。
- 键值型数据库事件回调方法中不允许进行阻塞操作,例如修改UI组件。
2.3 接口说明
以下是键值型数据库持久化功能的相关接口,大部分为异步接口。异步接口均有callback和Promise两种返回形式,下表均以callback形式为例,更多接口及使用方式请见分布式键值数据库。
接口名称 | 描述 |
createKVManager(config: KVManagerConfig): KVManager | 创建一个KVManager对象实例,用于管理数据库对象。 |
getKVStore<T>(storeId: string, options: Options, callback: AsyncCallback<T>): void | 指定Options和storeId,创建并得到指定类型的KVStore数据库。 |
put(key: string, value: Uint8Array|string|number|boolean, callback: AsyncCallback<void>): void | 添加指定类型的键值对到数据库。 |
get(key: string, callback: AsyncCallback<Uint8Array|string|boolean|number>): void | 获取指定键的值。 |
delete(key: string, callback: AsyncCallback<void>): void | 从数据库中删除指定键值的数据。 |
2.3 示例
三、关系型数据库
3.1 场景介绍
关系型数据库基于SQLite组件,适用于存储包含复杂关系数据的场景,比如一个班级的学生信息,需要包括姓名、学号、各科成绩等,又或者公司的雇员信息,需要包括姓名、工号、职位等,由于数据之间有较强的对应关系,复杂程度比键值型数据更高,此时需要使用关系型数据库来持久化保存数据。
3.2 基本概念
- 谓词:数据库中用来代表数据实体的性质、特征或者数据实体之间关系的词项,主要用来定义数据库的操作条件。
- 结果集:指用户查询之后的结果集合,可以对数据进行访问。结果集提供了灵活的数据访问方式,可以更方便地拿到用户想要的数据。
3.3 运作机制
关系型数据库对应用提供通用的操作接口,底层使用SQLite作为持久化存储引擎,支持SQLite具有的数据库特性,包括但不限于事务、索引、视图、触发器、外键、参数化查询和预编译SQL语句。
3.4 约束限制
- 系统默认日志方式是WAL(Write Ahead Log)模式,系统默认落盘方式是FULL模式。
- 数据库中连接池的最大数量是4个,用以管理用户的读操作。
- 为保证数据的准确性,数据库同一时间只能支持一个写操作。
- 当应用被卸载完成后,设备上的相关数据库文件及临时文件会被自动清除。
3.5 接口说明
以下是关系型数据库持久化功能的相关接口,大部分为异步接口。异步接口均有callback和Promise两种返回形式,下表均以callback形式为例,更多接口及使用方式请见关系型数据库。
接口名称 | 描述 |
getRdbStore(context: Context, config: StoreConfig, callback: AsyncCallback<RdbStore>): void | 获得一个相关的RdbStore,操作关系型数据库,用户可以根据自己的需求配置RdbStore的参数,然后通过RdbStore调用相关接口可以执行相关的数据操作。 |
executeSql(sql: string, bindArgs: Array<ValueType>, callback: AsyncCallback<void>):void | 执行包含指定参数但不返回值的SQL语句。 |
insert(table: string, values: ValuesBucket, callback: AsyncCallback<number>):void | 向目标表中插入一行数据。 |
update(values: ValuesBucket, predicates: RdbPredicates, callback: AsyncCallback<number>):void | 根据RdbPredicates的指定实例对象更新数据库中的数据。 |
delete(predicates: RdbPredicates, callback: AsyncCallback<number>):void | 根据RdbPredicates的指定实例对象从数据库中删除数据。 |
query(predicates: RdbPredicates, columns: Array<string>, callback: AsyncCallback<ResultSet>):void | 根据指定条件查询数据库中的数据。 |
deleteRdbStore(context: Context, name: string, callback: AsyncCallback<void>): void | 删除数据库。 |