表格存储提供了PutRow和UpdateRow接口用于写入单行数据以及BatchWriteRow接口用于批量写入数据。
使用
您可以使用如下语言的SDK写入数据。
插入单行数据
调用PutRow接口新写入一行数据。如果该行已存在,则先删除原行数据(原行的所有列以及所有版本的数据),再写入新行数据。
CU消耗说明
- 消耗的写CU为修改的行主键数据大小与属性列数据大小之和除以4 KB向上取整。
- 如果指定条件检查不为IGNORE,则消耗行主键数据大小除以4 KB向上取整的读CU。
- 如果操作不满足指定的行存在性检查条件,则操作失败并消耗1单位写CU和1单位读CU。
操作结果说明
- 如果操作成功,表格存储会返回操作消耗的服务能力单元(CU)。
说明 写入操作会根据指定的condition情况消耗一定的读CU。通过在单行写入请求中设置condition字段可以指定写入操作执行时,是否对行的存在性进行检查。condition有如下三种类型:
condition 说明 IGNORE 不做任何存在性检查。 EXPECT_EXIST 期望行存在。 - 如果该行存在,则操作成功。
- 如果该行不存在,则操作失败。
EXPECT_NOT_EXIST 期望行不存在。 - 如果该行不存在,则操作成功。
- 如果该行存在,则操作失败。
说明 condition为EXPECT_NOT_EXIST的DeleteRow、UpdateRow操作是无意义的,即删除一个不存在的行是无意义的。如果需要更新不存在的行可以使用PutRow操作。 - 如果操作发生错误,例如参数检查失败、单行数据量过多、行存在性检查失败等,表格存储会返回错误码。
参数
参数 | 说明 |
---|---|
tableName | 数据表名称。 |
primaryKey | 行的主键。
说明
|
condition | 使用条件更新,可以设置原行的存在性条件或者原行中某列的列值条件。更多信息,请参见条件更新。
说明
|
column | 行的属性列。
|
示例
- 示例1
写入10列属性列,每列写入1个版本,由系统自动生成数据的版本号(时间戳)。
private static void putRow(SyncClient client, String pkValue) { //构造主键。 PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString(pkValue)); PrimaryKey primaryKey = primaryKeyBuilder.build(); //设置数据表名称。 RowPutChange rowPutChange = new RowPutChange(TABLE_NAME, primaryKey); //加入一些属性列。 for (int i = 0; i < 10; i++) { rowPutChange.addColumn(new Column("Col" + i, ColumnValue.fromLong(i))); } client.putRow(new PutRowRequest(rowPutChange)); }
- 示例2
写入10列属性列,每列写入3个版本,自定义数据的版本号(时间戳)。
private static void putRow(SyncClient client, String pkValue) { //构造主键。 PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString(pkValue)); PrimaryKey primaryKey = primaryKeyBuilder.build(); //设置数据表名称。 RowPutChange rowPutChange = new RowPutChange(TABLE_NAME, primaryKey); //加入一些属性列。 long ts = System.currentTimeMillis(); for (int i = 0; i < 10; i++) { for (int j = 0; j < 3; j++) { rowPutChange.addColumn(new Column("Col" + i, ColumnValue.fromLong(j), ts + j)); } } client.putRow(new PutRowRequest(rowPutChange)); }
- 示例3
期望原行不存在时,写入10列属性列,每列写入3个版本,自定义数据的版本号(时间戳)。
private static void putRow(SyncClient client, String pkValue) { //构造主键。 PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString(pkValue)); PrimaryKey primaryKey = primaryKeyBuilder.build(); //设置数据表名称。 RowPutChange rowPutChange = new RowPutChange(TABLE_NAME, primaryKey); //设置条件更新,行条件检查为期望原行不存在。 rowPutChange.setCondition(new Condition(RowExistenceExpectation.EXPECT_NOT_EXIST)); //加入一些属性列。 long ts = System.currentTimeMillis(); for (int i = 0; i < 10; i++) { for (int j = 0; j < 3; j++) { rowPutChange.addColumn(new Column("Col" + i, ColumnValue.fromLong(j), ts + j)); } } client.putRow(new PutRowRequest(rowPutChange)); }
- 示例4
期望原行存在且Col0列的值大于100时,写入10列属性列,每列写入3个版本,自定义数据的版本号(时间戳)。
private static void putRow(SyncClient client, String pkValue) { //构造主键。 PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString(pkValue)); PrimaryKey primaryKey = primaryKeyBuilder.build(); //设置数据表名称。 RowPutChange rowPutChange = new RowPutChange(TABLE_NAME, primaryKey); //设置条件更新,期望原行存在且Col0列的值大于100时写入数据。 Condition condition = new Condition(RowExistenceExpectation.EXPECT_EXIST); condition.setColumnCondition(new SingleColumnValueCondition("Col0", SingleColumnValueCondition.CompareOperator.GREATER_THAN, ColumnValue.fromLong(100))); rowPutChange.setCondition(condition); //加入一些属性列。 long ts = System.currentTimeMillis(); for (int i = 0; i < 10; i++) { for (int j = 0; j < 3; j++) { rowPutChange.addColumn(new Column("Col" + i, ColumnValue.fromLong(j), ts + j)); } } client.putRow(new PutRowRequest(rowPutChange)); }
更新单行数据
CU消耗说明
- 消耗的写CU为修改的行主键数据大小与属性列数据大小之和除以4 KB向上取整。
操作中包含的需要删除的属性列,只有属性列的列名计入属性列数据大小。
- 如果指定条件检查不为IGNORE,则消耗行主键数据大小除以4 KB向上取整的读CU。
- 如果操作不满足指定的行存在性检查条件,则操作失败并消耗1单位写CU和1单位读CU。
参数
参数 | 说明 |
---|---|
tableName | 数据表名称。 |
primaryKey | 行的主键。
说明 设置的主键个数和类型必须和数据表的主键个数和类型一致。
|
condition | 使用条件更新,可以设置原行的存在性条件或者原行中某列的列值条件。更多信息,请参见条件更新。 |
column | 更新的属性列。
|
示例
- 示例1
更新一些列,删除某列的某一版本数据,删除某列。
private static void updateRow(SyncClient client, String pkValue) { //构造主键。 PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString(pkValue)); PrimaryKey primaryKey = primaryKeyBuilder.build(); //设置数据表名称。 RowUpdateChange rowUpdateChange = new RowUpdateChange(TABLE_NAME, primaryKey); //更新一些列。 for (int i = 0; i < 10; i++) { rowUpdateChange.put(new Column("Col" + i, ColumnValue.fromLong(i))); } //删除某列的某一版本。 rowUpdateChange.deleteColumn("Col10", 1465373223000L); //删除某一列。 rowUpdateChange.deleteColumns("Col11"); client.updateRow(new UpdateRowRequest(rowUpdateChange)); }
- 示例2
设置更新的条件。
private static void updateRow(SyncClient client, String pkValue) { //构造主键。 PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder(); primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString(pkValue)); PrimaryKey primaryKey = primaryKeyBuilder.build(); //设置数据表名称。 RowUpdateChange rowUpdateChange = new RowUpdateChange(TABLE_NAME, primaryKey); //设置条件更新,期望原行存在且Col0列的值大于100时更新数据。 Condition condition = new Condition(RowExistenceExpectation.EXPECT_EXIST); condition.setColumnCondition(new SingleColumnValueCondition("Col0", SingleColumnValueCondition.CompareOperator.GREATER_THAN, ColumnValue.fromLong(100))); rowUpdateChange.setCondition(condition); //更新一些列。 for (int i = 0; i < 10; i++) { rowUpdateChange.put(new Column("Col" + i, ColumnValue.fromLong(i))); } //删除某列的某一版本。 rowUpdateChange.deleteColumn("Col10", 1465373223000L); //删除某一列。 rowUpdateChange.deleteColumns("Col11"); client.updateRow(new UpdateRowRequest(rowUpdateChange)); }
批量写入数据
调用BatchWriteRow接口在一次请求中进行批量的写入操作,也支持一次对多张表进行写入。BatchWriteRow操作由多个PutRow、UpdateRow、DeleteRow子操作组成,构造子操作的过程与使用PutRow接口、UpdateRow接口和DeleteRow接口时相同,也支持使用条件更新。
BatchWriteRow的各个子操作独立执行,表格存储会分别返回各个子操作的执行结果。
注意事项
由于批量写入可能存在部分行失败的情况,失败行的Index及错误信息在返回的BatchWriteRowResponse中,但并不抛出异常。因此调用BatchWriteRow接口时,需要检查返回值,可通过BatchWriteRowResponse的isAllSucceed方法判断是否全部成功;如果不检查返回值,则可能会忽略掉部分操作的失败。
当服务端检查到某些操作出现参数错误时,BatchWriteRow接口可能会抛出参数错误的异常,此时该请求中所有的操作都未执行。
示例
一次BatchWriteRow请求包含2个PutRow操作、1个UpdateRow操作和1个DeleteRow操作。
private static void batchWriteRow(SyncClient client) {
BatchWriteRowRequest batchWriteRowRequest = new BatchWriteRowRequest();
//构造rowPutChange1。
PrimaryKeyBuilder pk1Builder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
pk1Builder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString("pk1"));
RowPutChange rowPutChange1 = new RowPutChange(TABLE_NAME, pk1Builder.build());
//添加一些列。
for (int i = 0; i < 10; i++) {
rowPutChange1.addColumn(new Column("Col" + i, ColumnValue.fromLong(i)));
}
//添加到batch操作中。
batchWriteRowRequest.addRowChange(rowPutChange1);
//构造rowPutChange2。
PrimaryKeyBuilder pk2Builder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
pk2Builder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString("pk2"));
RowPutChange rowPutChange2 = new RowPutChange(TABLE_NAME, pk2Builder.build());
//添加一些列。
for (int i = 0; i < 10; i++) {
rowPutChange2.addColumn(new Column("Col" + i, ColumnValue.fromLong(i)));
}
//添加到batch操作中。
batchWriteRowRequest.addRowChange(rowPutChange2);
//构造rowUpdateChange。
PrimaryKeyBuilder pk3Builder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
pk3Builder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString("pk3"));
RowUpdateChange rowUpdateChange = new RowUpdateChange(TABLE_NAME, pk3Builder.build());
//添加一些列。
for (int i = 0; i < 10; i++) {
rowUpdateChange.put(new Column("Col" + i, ColumnValue.fromLong(i)));
}
//删除一列。
rowUpdateChange.deleteColumns("Col10");
//添加到batch操作中。
batchWriteRowRequest.addRowChange(rowUpdateChange);
//构造rowDeleteChange。
PrimaryKeyBuilder pk4Builder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
pk4Builder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString("pk4"));
RowDeleteChange rowDeleteChange = new RowDeleteChange(TABLE_NAME, pk4Builder.build());
//添加到batch操作中。
batchWriteRowRequest.addRowChange(rowDeleteChange);
BatchWriteRowResponse response = client.batchWriteRow(batchWriteRowRequest);
System.out.println("是否全部成功:" + response.isAllSucceed());
if (!response.isAllSucceed()) {
for (BatchWriteRowResponse.RowResult rowResult : response.getFailedRows()) {
System.out.println("失败的行:" + batchWriteRowRequest.getRowChange(rowResult.getTableName(), rowResult.getIndex()).getPrimaryKey());
System.out.println("失败原因:" + rowResult.getError());
}
/**
* 可以通过createRequestForRetry方法再构造一个请求对失败的行进行重试。此处只给出构造重试请求的部分。
* 推荐的重试方法是使用SDK的自定义重试策略功能,支持对batch操作的部分行错误进行重试。设置重试策略后,调用接口处无需增加重试代码。
*/
BatchWriteRowRequest retryRequest = batchWriteRowRequest.createRequestForRetry(response.getFailedRows());
}
}