功能说明
条件更新功能只有在满足条件时才对表中的数据进行更改, 当不满足条件时更新失败.
比如有如下场景, 初始化数据, 当数据字段 A 为 - 1 时, 将 A 的值更新为指定的内容. 比如更新为 12; 如果不是 - 1 则更新失败.
条件更新支持两个维度. 分别是行的存在性检查和列值的条件判断.
第一个维度是行的条件检查, 包括如下三种条件:
IGNORE: 忽略, 不做存在性检查; 比如我们 PutRow 一行数据, PK 为 ABC, 设置 IGNORE 之后, 不管表中是否已经存在了 ABC 这一行数据, PutRow 都可以写入成功. 写入成功之后新写入的行将覆盖老的行.
EXPECT_EXIST: 期望行存在; 示例如上, 同样是写入一行数据 ABC, 此次写入是期望表中已经存在 ABC 这一行数据, 如果存在, 写入成功, 新的行覆盖老的行; 如果不存在, 此次写入也将失败.
EXPECT_NOT_EXIST: 期望行不存在; 也是写入一行数据 ABC, 此时希望表中不存在 ABC 这一行; 如果表中存在这一行数据, 写入失败; 如果这行数据不存在, 那么写入 ABC.
第二个维度是列条件更新检查, 目前支持单条件 (SingleColumnValueCondition) 和多条件 (CompositeColumnValueCondition) 列值判断; 列条件判断还支持算术运算(=,!=,>,>=,<,<=) 和逻辑运算(NOT,AND,OR).
比如, 我们要更新人员信息, 更新国家为中国的数据, 伪代码如下
SQL 样例: where 国家 ='中国'
- # 伪代码
- SingleColumnValueCondition(国家 = 中国)
- # 因为只有一个条件, 所以使用 SingleColumnValueCondition
- # 列名为 "中国", 算数运算符为'=', 只为'中国'
在限定必须小于 20 岁, 变成了多条件检查,
SQL 样例: where 国家 ='中国' and age<20
- # 伪代码如下
- cond = CompositeColumnValueCondition(AND)
- cond.addCondtition(SingleColumnValueCondition(国家 = 中国))
- cond.addCondtition(SingleColumnValueCondition(age<20))
- # 两个条件, 所以使用 CompositeColumnValueCondition
- # 同时两个条件色'且'的语义, 使用 AND
- # 第一个条件同上, 第二个使用了'<'运算符
嵌套的方式, 比如条件如下, 比如中国为 20 岁一下, 美国 18 岁一下
SQL 样例: where (国家 ='中国' and age<20) or (国家 ='美国' and age<18)
- # 伪代码如下
- cond = CompositeColumnValueCondition(OR)
- subCond1 = CompositeColumnValueCondition(AND)
- subCond1.addCondtition(SingleColumnValueCondition(国家 = 中国))
- subCond1.addCondtition(SingleColumnValueCondition(age<20))
- subCond2 = CompositeColumnValueCondition(AND)
- subCond2.addCondtition(SingleColumnValueCondition(国家 = 美国))
- subCond2.addCondtition(SingleColumnValueCondition(age<18))
- cond.addCondtition(subCond1)
- cond.addCondtition(subCond2)
- # 因为是嵌套条件, 所以最外层使用 CompositeColumnValueCondition,
- # 由于只要满足一个条件即可, 所以外围的 CompositeColumnValueCondition 为'或'的语义, 所以使用 OR
- # 子条件可以参考之前的描述方式
- # 最后将子条件添加到最外层的条件检查中
限制条件
列条件最多 10 个条件的组合.
行和列的条件有效范围, 都只能针对当前正在操作的这一行, 不支持跨行条件检查.
支持的 API
- PutRow
- UpdateRow
- DeleteRow
- BatchWriteRow
费用计算
如果写入数据或者更新数据删除数据, CU 的计算规则和平时调用 API 的计费规则一致. 如果是条件检查失败, 会分别消耗 1 单位的读 CU 和 1 单位的写 CU.
功能与示例
背景: 小明是公司 HR, 每月会对薪酬表 (remuneration) 进行定期的调整, 薪酬表中记录了相关人员的薪资信息; 我们定义了各种不同的更新方式, 全方位的展示条件更新的使用方式.
部门(主键) | 人员数目 | 人员 HC 数目 | 奖金池 | 薪资池 |
技术部门 | 10 | 30 | 32 | 12034 |
财务部门 | 2 | 2 | 0 | 0 |
行政部门 | 3 | 5 | 3 | 12 |
销售部门 | 0 | 30 | 30 | 35 |
以下代码使用 Java 代码演示
场景一: 新增一个部门 "运营部门", 未来进行招聘, 当前录入部门薪酬信息
- # 由于是新增部门, 我们期望表中不会存在该部门的信息, 所以使用 行存在性 的检查, 期望这一行
- # 不存在(EXPECT_NOT_EXIST), 当原有表中不存在这行数据时, 写入成功, 否则写入失败.
- # PutRow 的实现方式
- {
- RowPutChange rowChange = new RowPutChange(TABLE_NAME);
- rowChange.setPrimaryKey(PrimaryKeyBuilder.createPrimaryKeyBuilder()
- .addPrimaryKeyColumn(PK, PrimaryKeyValue.fromString("运营部门"))
- .build());
- rowChange.addColumn("人员数目", ColumnValue.fromLong(0));
- rowChange.addColumn("人员 HC 数目", ColumnValue.fromLong(30));
- rowChange.addColumn("奖金池", ColumnValue.fromLong(30));
- rowChange.addColumn("薪资池", ColumnValue.fromLong(35));
- // 因为 "运营部门" 是新增, 所以期望表中是不存在行的, 因此采用行存在性检查: EXPECT_NOT_EXIST
- rowChange.setCondition(new Condition(RowExistenceExpectation.EXPECT_NOT_EXIST));
- }
场景二: 更新行政部门的人员数目, 从 3 更新为 5 人
- # 这里会使用两个条件更新的检查:
- # 第一个是行存在性的检查, 期望这一行存在;
- # 第二个是列的条件检查, 期望'人员数目'是 3, 则更新, 如果不是 3 则更新失败
- # UpdateRow 的实现方式
- {
- RowUpdateChange rowChange = new RowUpdateChange(TABLE_NAME);
- rowChange.setPrimaryKey(PrimaryKeyBuilder.createPrimaryKeyBuilder()
- .addPrimaryKeyColumn(PK, PrimaryKeyValue.fromString("行政部门"))
- .build());
- rowChange.put("人员数目", ColumnValue.fromLong(5));
- // 行存在性检查, 期望存在
- Condition condition = new Condition(RowExistenceExpectation.EXPECT_EXIST);
- // 列条件检查, 期望 '人员数目' 为 3
- SingleColumnValueCondition singleColumnValueCondition = new SingleColumnValueCondition(
- "人员数目",
- SingleColumnValueCondition.CompareOperator.EQUAL,
- ColumnValue.fromLong(3)
- );
- condition.setColumnCondition(singleColumnValueCondition);
- rowChange.setCondition(condition);
- }
场景三: 由于销售部门已经外包给第三方公司, 因此决定删除 "销售部门" 的记录信息
- # 这里只需要使用行存在性检查即可, 期望 "销售部门" 的信息存在(EXPECT_EXIST)
- # DeleteRow 的实现方式
- {
- RowDeleteChange rowChange = new RowDeleteChange(TABLE_NAME);
- rowChange.setPrimaryKey(PrimaryKeyBuilder.createPrimaryKeyBuilder()
- .addPrimaryKeyColumn(PK, PrimaryKeyValue.fromString("销售部门"))
- .build());
- // 行存在性检查, 期望存在
- Condition condition = new Condition(RowExistenceExpectation.EXPECT_EXIST);
- rowChange.setCondition(condition);
- }
场景四: 增加小团队的 HC, 小团队人员和 HC 小于等于 5 的, 每个部门新增 2 个人头的招聘资源, 比如财务部门就满足这个条件, 所以在更新财务部门的 HC, 更新的过程中使用条件更新检查;
- # UpdateRow 的实现方式
- {
- RowUpdateChange rowChange = new RowUpdateChange(TABLE_NAME);
- rowChange.setPrimaryKey(PrimaryKeyBuilder.createPrimaryKeyBuilder()
- .addPrimaryKeyColumn(PK, PrimaryKeyValue.fromString("财务部门"))
- .build());
- rowChange.increment(new Column("人员 HC 数目", ColumnValue.fromLong(2)));
- // 行存在性检查
- Condition condition = new Condition(RowExistenceExpectation.IGNORE);
- CompositeColumnValueCondition conditions = new CompositeColumnValueCondition(CompositeColumnValueCondition.LogicOperator.OR);
- {
- // 列条件检查, 期望 '人员数目' 小于等于 5
- SingleColumnValueCondition singleColumnValueCondition = new SingleColumnValueCondition(
- "人员数目",
- SingleColumnValueCondition.CompareOperator.LESS_EQUAL,
- ColumnValue.fromLong(5)
- );
- conditions.addCondition(singleColumnValueCondition);
- }
- {
- // 列条件检查, 期望 '人员 HC 数目' 小于等于 5
- SingleColumnValueCondition singleColumnValueCondition = new SingleColumnValueCondition(
- "人员 HC 数目",
- SingleColumnValueCondition.CompareOperator.LESS_EQUAL,
- ColumnValue.fromLong(5)
- );
- conditions.addCondition(singleColumnValueCondition);
- }
- condition.setColumnCondition(conditions);
- rowChange.setCondition(condition);
- }
表格存储使用手册
本文结合 Java SDK 的接口调用代码, 介绍了 Tablestore 在数据管理方面的基本功能与使用方式. 代码已开源在 Tablestore-Examples 项目中, 用户可以直接运行使用. 基于样例代码与文章, 新用户能更简单, 更快速地上手 Tablestore, 欢迎新, 老用户使用与建议.
通过对基础使用功能的持续输出, 我们将整理出一套完整的使用手册(含可执行样例), 敬请期待.
专家服务
来源: https://yq.aliyun.com/articles/742973