存储能力
目前支持的存储能力有:实体存储。
要求
ONES | @ones-op/sdk | @ones/cli |
---|---|---|
v6.31.0 | v1.0.8 | v1.40.10 |
实体存储
实体是用户定义的用于存储应用数据的数据结构。
ONES 的实体存储 SDK 允许你使用各种查询条件查询存储在这些结构中的数据,或者对数据进行创建、更新、删除等数据管理操作。
实体数据类型
实体具有多个类型化的属性,你可以使用以下数据类型定义属性:
- boolean
- integer
- float
- string
- text
实体数据的使用规范
数据类型 | 是否支持索引 | 是否需要定义长度 | 写入的数据的规范 |
---|---|---|---|
boolean | 支持 | 否 | true | false |
integer | 支持 | 否 | (-9223372036854775808, 9223372036854775807] |
float | 支持 | 否 | (-1.7976931348623157e308, -2.2250738585072014e−308) 0 (2.2250738585072014e−308, 1.7976931348623157e308) 支持最大 15 位精度 |
string | 支持 | 是 定义的范围是 [1, 2048] | 全部 string 类型属性的长度由用户定义 全部 string 类型属性的累加总长度不超过 2048 字节 |
text | 不支持 | 否 | 每个属性最大可写入 32768 字节 |
数据类型 string 和 text
string:如果你的业务数据需要索引,请使用 string,并且声明你的属性长度。
text:如果你的业务数据以存储为准,请使用 text。
实体定义
实体定义,需要在 config/plugin.yaml
文件中声明。
基本实体定义说明
基本实体定义,声明的结构如下:
- name,必填,自定义实体名。
- attributes,必填,自定义属性声明。
- indexes,选填,自定义索引声明。
config/plugin.yaml
storage:
entities:
- name: <entity1> # 自定义实体名
attributes: # 自定义属性声明,必填
<attribute1>: # 自定义属性名
type: <type>
required: true
<attribute2>:
type: <type>
default: <value>
# ... more attributes
<attributeN>:
type: <type>
default: <value>
indexes: # 自定义索引声明,选填
- name: <index1> # 自定义索引名
range_attribute: <attribute name>
# ... more indexes
- name: <indexN>
range_attribute: <attribute name>
partition:
- <attribute name>
# ... more attributes
- <attribute name>
- name: <entity2>
# ... more entity
- name: <entityN>
自定义属性说明
自定义属性,支持以下两种声明的结构:
- 必填属性
- type,必填,自定义属性的类型,需要声明支持的数据类型。
- 如果定义属性的类型的 string,则需要额外定义长度,必填,定义的范围是 [1, 2048]。
- 创建或者更新实体数据时,需要必填属性值,且符合当前字段的数据类型。
- 声明必填的属性,不能声明默认值。
- type,必填,自定义属性的类型,需要声明支持的数据类型。
- 声明默认值的属性
- type,必填,自定义属性的类型,需要声明支持的数据类型。
- 如果定义属性的类型的 string,则需要额外定义长度,必填,定义的范围是 [1, 2048]。
- 创建实体数据时,如果缺失,则会使用默认值创建该条实体数据。
- 更新实体数据时,如果缺失,则保留原来的属性值不变。
- 默认值的声明,需符合当前字段的数据类型。
- 声明默认值的属性,不能声明必填。
- type,必填,自定义属性的类型,需要声明支持的数据类型。
config/plugin.yaml
# case1: 必填属性
<attribute1>:
type: <type>
required: true
# case2: 声明默认值的属性
<attribute2>:
type: <type>
default: <value>
# case3: 必填的 string 属性
<attribute1>:
type: string
length: 32
required: true
# case4: 声明默认值的 string 属性
<attribute2>:
type: string
length: 32
default: <value>
自定义索引说明
自定义索引,基本声明的结构如下 :
- 自定义索引
- name,必填,自定义索引名。
- range_attribute,必填,使用条件查询时,被查询的属性。
- 需要填写在 attributes 中声明过的属性名,且类型为:boolean,integer,float,string 其中之一。
- partition,选填,使用索引查询时,按分区属性值查询。并且按当前属性排序。
- 需要填写在 attributes 中声明过的属性名,且类型为:boolean,integer,float,string 其中之一。
- unique,选填,数据的唯一性标记。在创建或者更新数据时,数据需要唯一。
- 根据 range_attribute 和 partition 填写的属性名的组合,需要唯一。
- 具体例子,请参考:设置实体查询条件。
config/plugin.yaml
# case1: 自定义索引
- name: <index1>
range_attribute: <attribute name>
# case2: 有分区属性值的自定义索引
- name: <index2>
range_attribute: <attribute name>
partition:
- <attribute name>
- <attribute name>
# case3: 自定义索引且有唯一性标记
- name: <index1>
range_attribute: <attribute name>
unique: true
# case4: 有分区属性值的自定义索引且有唯一性标记
- name: <index2>
range_attribute: <attribute name>
unique: true
partition:
- <attribute name>
- <attribute name>
完整实体定义的例子
config/plugin.yaml
storage:
entities:
- name: employee # 员工实体
attributes:
name: # 员工名
type: string
length: 32
required: true
age: # 员工年龄
type: integer
required: true
deleted: # 是否删除标记
type: boolean
required: true
indexes:
- name: find_by_name # 以员工名作为范围查询的索引
range_attribute: name
- name: find_by_age_in_deleted_partition # 在删除标记的属性分区中,以员工年龄作为范围查询的索引
range_attribute: age
partition:
- deleted
实体定义的声明规范
类别 | 规范要求 |
---|---|
实体 | 实体声明数量最多 64 个 实体名称最长 32 个字节 且满足该正则表达式 /^[_a-z0-9]{1,32}$/ |
实体属性 | 实体属性声明数量最多 32 个 实体属性名最长 64 个字节 且满足该正则表达式 /^[_a-z0-9]{1,64}$/ |
自定义索引 | 自定义索引声明数量最多 64 个 自定义索引名最长 64 个字节 且满足该正则表达式 /^[_a-z0-9]{1,64}$/ |
实体管理
实体管理,包括创建实体和更新实体。
实体管理动作,将会在插件的生 命周期中执行。
并且根据 实体定义的声明规范 进行校验。
生命周期 | 实体管理 |
---|---|
插件首次安装 | 根据实体定义,创建实体。 |
插件升级 | 对比实体定义差异部分,增加属性和索引。 已存在的属性和索引不允许修改和删除。 |
插件卸载 | 实体数据保留,支持数据导出。 |
插件卸载后再重新安装 | 创建新的实体。 |
插件升级注意事项
插件可以在不同版本之间进行差量升级,因此,在插件的迭代过程中,实体定义只能增加属性和索引。
在查询数据时,如果实体数据是历史数据,它的新增的属性默认返回 null
。即:
backend/src/index.ts
import { storage } from '@ones-op/sdk/backend'
const { entity } = storage
entity('employee')
.query()
.getOne()
.then((data) => {
// 假设 department 为新增属性,则返回 null
console.log(data?.value.department)
})
一般情况下,推荐插件进行 数据迁移 或者 新增业务逻辑。即:
backend/src/index.ts
import { storage } from '@ones-op/sdk/backend'
const { entity } = storage
// 数据迁移(分页需要自行实现)
entity('employee')
.query()
.getMany()
.then((data) => {
entity('employee').batchSet(
data.data.map((item) => {
// 假设 department 为新增属性
item.value.department = item.value.department || '研发部'
return item
}),
)
})
// 新增业务逻辑
const getDepartment = (key: string) => {
return entity('employee')
.get(key)
.then((data) => {
return data?.department || '研发部'
})
}
实体数据管理
在每个实体中,默认包含 Key,且 Key 唯一。
在进行 实体数据管理 时,需要使用 Key,对数据进行创建、更新、删除等数据管理操作。
请参考:实体存储 SDK。
实体的 Key 的使用规范
类别 | 规范要求 |
---|---|
Key | 最长 64 个字节 且满足该正则表达式 /^[_a-z0-9]{1,64}$/ |