Tablestore入门手册-UpdateRow接口详解

本文涉及的产品
对象存储 OSS,20GB 3个月
阿里云盘企业版 CDE,企业版用户数5人 500GB空间
云备份 Cloud Backup,100GB 3个月
简介:

表格存储Tablestore入门手册系列主要介绍表格存储的各个功能接口和适用场景,帮助客户了解和使用表格存储Tablestore。本文对表格存储Tablestore的UpdateRow接口进行介绍,包括其参数、功能示例、使用场景等。

接口概述

UpdateRow接口是表格存储Tablestore提供的基础读写接口之一,用于对某一行进行更新操作,若指定行不存在,UpdateRow也可以用于新增一行。这里的更新包括新增、修改或删除某一列,如果使用了多版本功能,也可以对某列中指定的版本进行新增、修改或删除。此外,在接口参数中也可以指定条件,仅当满足条件时进行更新。下面详细介绍该接口的参数和功能。

接口参数说明

API定义和参数说明

首先是UpdateRow接口的API定义:

message UpdateRowRequest {
    required string table_name = 1;
    required bytes row_change = 2;
    required Condition condition = 3;
    optional ReturnContent return_content = 4; 
}

message UpdateRowResponse {
    required ConsumedCapacity consumed = 1;
    optional bytes row = 2;
}

API定义中的具体参数说明,见官网API文档:https://help.aliyun.com/document_detail/27307.html

SDK接口和参数说明

在项目代码中对表格存储Tablestore进行读写操作,是通过表格存储Tablestore发布的各语言SDK进行的,SDK对API进行了封装,内部自动处理了请求的编码和响应的解析等。因此对于表格存储Tablestore的使用者来说,只需要熟悉SDK的接口即可。

下面以Java SDK为例,介绍SDK中的UpdateRow接口和参数。

接口定义

同步接口(SyncClient):

    /**
     * 更新表中的一行数据。
     * <p>若要更新的行不存在,则新写入一行数据。</p>
     * <p>更新操作可以包括新写入一个属性列或者删除一个属性列的一个或多个版本。</p>
     *
     * @param updateRowRequest 执行UpdateRow操作所需的参数。
     * @return TableStore服务返回的结果
     * @throws TableStoreException    TableStore服务返回的异常
     * @throws ClientException 请求的返回结果无效、或遇到网络异常
     */
    public UpdateRowResponse updateRow(UpdateRowRequest updateRowRequest)
            throws TableStoreException, ClientException;

异步接口(AsyncClient):

    /**
     * 更新表中的一行数据。
     * <p>若要更新的行不存在,则新写入一行数据。</p>
     * <p>更新操作可以包括新写入一个属性列或者删除一个属性列的一个或多个版本。</p>
     *
     * @param updateRowRequest 执行UpdateRow操作所需的参数。
     * @param callback 请求完成后调用的回调函数,可以为null,则代表不需要执行回调函数
     * @return 获取结果的Future
     * @throws TableStoreException TableStore服务返回的异常
     * @throws ClientException 请求的返回结果无效、或遇到网络异常
     */
    public Future<UpdateRowResponse> updateRow(
            UpdateRowRequest updateRowRequest, TableStoreCallback<UpdateRowRequest, UpdateRowResponse> callback);

具体参数说明:

变量类型 说明 备注
UpdateRowRequest UpdateRow接口的请求类型,具体内容见后续说明。
UpdateRowResponse UpdateRow接口的返回结果,具体内容见后续说明。
TableStoreCallback callback UpdateRow接口的异步回调函数。 仅适用于异步接口。
Future 异步接口的UpdateRow接口返回结果。 仅适用于异步接口。
异步接口调用后不等待请求结束,立即返回future,通过future.get()可以获取实际接口响应的结果。

UpdateRowRequest参数说明

1.png

具体参数说明:

变量类型 说明 备注
TxnRequest(基类) 抽象类,包含TransactionId成员变量,继承该类的请求类型可用于局部事务中。 TransactionId的使用可参考局部事务的文档。
UpdateRowRequest UpdateRow接口的请求类型,包含一个成员变量:RowUpdateChange。
继承自TxnRequest,表示该请求可用于局部事务中。
RowUpdateChange 本次更新的具体请求参数。

RowUpdateChange参数说明

2.png

具体参数说明:

变量类型 类说明 成员变量或接口 说明
RowChange(基类) RowUpdateChange的基类,提供了设置表名、主键、更新条件、返回类型等通用参数。 tableName 指定本次更新要操作的表名。
primaryKey 指定本次要更新的行的主键。
condition 指定本次更新操作的条件,可选。
returnType 枚举类型,默认为RT_NONE,表示不返回行的内容,此外还有两种值:
(1)RT_PK: 返回主键,适用于使用主键自增列功能的场景,用于返回系统生成的自增主键值。
(2)RT_AFTER_MODIFY: 返回修改的列的数据,适用于使用了原子加功能的场景,用于返回原子加之后,某一列的值。此时需要设置returnColumnNames。
returnColumnNames 当returnType为RT_AFTER_MODIFY时,指定要返回的被修改的列的列名(适用于原子加的场景)。
RowUpdateChange UpdateRow的具体请求参数,继承自RowChange类。 put(String columnName, ColumnValue value) 新增或修改某一列的值。
(系统内部会为该列生成一个新的版本号,单版本模式下无须关心该版本号)
put(String columnName, ColumnValue value, long version) 新增或修改某一列的某一个版本。
(适用于多版本模式,手动指定版本号写入)
put(Column column) 功能同上述put接口,只是参数使用Column类型进行了封装。
put(List column) 功能同上述put接口,只是参数为多列。
deleteColumns(String columnName) 删除某列,多版本模式下会删除该列全部版本。
deleteColumn(String columnName, long version) 删除某列的指定版本,适用于多版本模式下对特定版本进行删除。
increment(Column column) 对某列进行原子加操作,仅适用于整型类型。
Condition 本次更新的条件。可以指定行存在性条件和列条件,列条件比如“某列的值大于5”。 rowExistenceExpectation 行存在性条件,枚举类型,有以下三种值:
(1) IGNORE:不对行存在性进行判断,默认即为IGNORE。
(2) EXPECT_EXIST: 期望该行存在,若不存在,请求会报错。
(3) EXPECT_NOT_EXIST:期望该行不存在,若存在,请求会报错。
注意:
通常情况下,若没有特殊的设置条件的需求,使用IGNORE即可(保持默认,可不做设置),此时写入性能也更好。
columnCondition 列条件,可以设置单列条件(SingleColumnValueCondition),也可以设置多列组合条件(CompositeColumnValueCondition),具体见条件更新的文档。

UpdateRowResponse参数说明

3.png

具体参数说明:

变量类型 成员变量或接口 说明
Response(基类) requestId 本次请求服务端返回的requestId,用于问题调查,建议在出错时打印到业务日志中。
traceId 本次请求SDK生成的traceId,用于问题调查,建议在出错时打印到业务日志中。
UpdateRowResponse consumedCapacity 本次请求消耗的读写CU,用于计费。
row 默认情况下为null,仅当请求中returnType设置为返回PK(RT_PK)或者某列修改后的值(RT_AFTER_MODIFY)时,返回对应的内容。

功能示例

所有示例代码可以在Tablestore-Examples项目中查看。

Github地址:https://github.com/aliyun/tablestore-examples/tree/master/basic/Java/DataManage/src/main/java/com/aliyun/tablestore/basic/dataManage

基本更新操作

UpdateRow接口最常用的场景,是对某一行写入一些列,或者删除一些列。通常,业务使用单版本表比较多,此时可以忽略列上多版本的概念,按照每列只有一个值来理解。此时UpdateRow就是用于新增、修改或删除某些列。

新增:若写入的属性列之前不存在,UpdateRow执行后会新增该列。
修改:若写入的属性列之前已经有值,UpdateRow执行后会修改该列的值。
删除:UpdateRow可以用于删除某些列,若该列之前就不存在,则无影响,不会报错。

示例代码

下面的代码执行一次UpdateRow操作,对某一行新增两列,删除一列。

    public void updateRowNormally() {
        PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
                .addPrimaryKeyColumn(PK1, PrimaryKeyValue.fromLong(1L))
                .addPrimaryKeyColumn(PK2, PrimaryKeyValue.fromString("string"))
                .build();
        /**
         * 构造RowUpdateChange,设置表名和主键
         */
        RowUpdateChange rowChange = new RowUpdateChange(TABLE_NAME, primaryKey);

        /**
         * 写入两列
         */
        rowChange.put("col_str", ColumnValue.fromString("value1"));
        rowChange.put("col_long", ColumnValue.fromLong(1));

        /**
         * 删除某列
         */
        rowChange.deleteColumns("col_to_delete");

        /**
         * 构造UpdateRowRequest
         */
        UpdateRowRequest updateRowRequest = new UpdateRowRequest(rowChange);

        /**
         * 调用updateRow接口。若之前该行不存在,系统会新增该行。
         */
        UpdateRowResponse updateRowResponse = syncClient.updateRow(updateRowRequest);

        /**
         * 打印requestID
         */
        System.out.printf("UpdateRowSuccess, request id: %s\n", updateRowResponse.getRequestId());
    }

使用UpdateRow新增、修改或者删除某些列,是最基础的单行数据更新操作,也是很常用的场景。

但在某些场景中,若使用了表格存储Tablestore的多版本功能,可能会有新增或修改某一列的某个特定版本的需求,或者是需要删除某一列的某一个版本,此时就需要指定时间戳来更新或删除,见下面的示例。

指定版本操作

对于设置了保留多版本的表,每一列上都会保留最新的N个版本,UpdateRow可以对其中某个特定版本进行更新,也可以删除某个特定版本。

示例代码

下面的代码执行一次UpdateRow操作,对某一行写入两列,指定版本号写入,同时删除某列的某个版本,也需要指定要删除的版本号。

注意:在指定版本号时,需要保证该版本号在表上设置的最大版本偏差内,若超出该偏差范围,可以调整表上的最大版本偏差设置(见文档:https://help.aliyun.com/document_detail/89939.html)。

    public void updateRowMultiVersion() {
        PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
                .addPrimaryKeyColumn(PK1, PrimaryKeyValue.fromLong(1L))
                .addPrimaryKeyColumn(PK2, PrimaryKeyValue.fromString("string"))
                .build();
        /**
         * 构造RowUpdateChange,设置表名和主键
         */
        RowUpdateChange rowChange = new RowUpdateChange(TABLE_NAME, primaryKey);

        long version = System.currentTimeMillis();

        /**
         * 写入两列,指定版本号。
         * 若指定的版本之前不存在,则会新增一个版本;若该版本已存在,会修改该版本的值。
         */
        rowChange.put("col_str", ColumnValue.fromString("value1"), version);
        rowChange.put("col_long", ColumnValue.fromLong(1), version);

        /**
         * 删除某列的某一个版本,指定版本号。
         */
        rowChange.deleteColumn("col_to_delete", version);

        /**
         * 构造UpdateRowRequest
         */
        UpdateRowRequest updateRowRequest = new UpdateRowRequest(rowChange);

        /**
         * 调用updateRow接口。若之前该行不存在,系统会新增该行。
         */
        UpdateRowResponse updateRowResponse = syncClient.updateRow(updateRowRequest);

        /**
         * 打印requestID
         */
        System.out.printf("UpdateRowSuccess, request id: %s\n", updateRowResponse.getRequestId());
    }

条件更新

UpdateRow接口可以设置更新条件,仅当满足条件时才进行更新,条件包括行存在性条件和列条件。

行存在性条件:在更新前检查该行存在或不存在,仅当符合期望时才进行更新操作,否则抛错。

列条件:目前支持 SingleColumnValueCondition 和 CompositeColumnValueCondition,是基于某一列或者某些列的列值进行条件判断,比如“col_long的值应该大于5”等。基于列条件,可以使用表格存储Tablestore实现分布式的乐观锁机制。

条件更新的功能文档:https://help.aliyun.com/document_detail/35194.html

示例代码

设置行存在性条件和列条件:

    public void updateRowWithCondition() {
        PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
                .addPrimaryKeyColumn(PK1, PrimaryKeyValue.fromLong(1L))
                .addPrimaryKeyColumn(PK2, PrimaryKeyValue.fromString("string"))
                .build();
        /**
         * 构造RowUpdateChange,设置表名和主键
         */
        RowUpdateChange rowChange = new RowUpdateChange(TABLE_NAME, primaryKey);

        /**
         * 设置行存在条件为期望行存在
         */
        Condition condition = new Condition(RowExistenceExpectation.EXPECT_EXIST);

        /**
         * 设置列条件,若只需要检查行存在性,可以不设置列条件。
         *
         * 这里设置列条件为两列的组合条件: "(col_boolean == true) && (col_long > 0)"
         */
        CompositeColumnValueCondition colCondition = new CompositeColumnValueCondition(CompositeColumnValueCondition.LogicOperator.AND);
        SingleColumnValueCondition subColCondition1 = new SingleColumnValueCondition(
                "col_boolean",
                SingleColumnValueCondition.CompareOperator.EQUAL,
                ColumnValue.fromBoolean(true));
        subColCondition1.setPassIfMissing(true); // setPassIfMissing(true),表示若该列不存在,也视为满足条件。
        SingleColumnValueCondition subColCondition2 = new SingleColumnValueCondition(
                "col_long",
                SingleColumnValueCondition.CompareOperator.GREATER_THAN,
                ColumnValue.fromLong(0L));
        colCondition.addCondition(subColCondition1).addCondition(subColCondition2);
        subColCondition2.setPassIfMissing(false); // setPassIfMissing(false),表示若该列不存在,视为不满足条件。

        condition.setColumnCondition(colCondition);
        rowChange.setCondition(condition);

        /**
         * 满足条件时,写入两列
         */
        rowChange.put("col_str", ColumnValue.fromString("value1"));
        rowChange.put("col_long", ColumnValue.fromLong(1));

        /**
         * 构造UpdateRowRequest
         */
        UpdateRowRequest updateRowRequest = new UpdateRowRequest(rowChange);

        /**
         * 调用updateRow接口。
         * 若不满足设置的条件,比如该行不存在,或者不满足列条件,会抛OTSException,ErrorCode为"OTSConditionCheckFail".
         */
        UpdateRowResponse updateRowResponse = syncClient.updateRow(updateRowRequest);

        /**
         * 打印requestID
         */
        System.out.printf("UpdateRowSuccess, request id: %s\n", updateRowResponse.getRequestId());
    }

原子计数器

UpdateRow支持对某一整型列进行原子加操作,原子加操作可以原子的对某一整型列的数据进行增量变更操作,比如在原来的基础上加10,或者减5,等等。原子加操作可以用来构造原子计数器。

原子计数器的功能文档:https://help.aliyun.com/document_detail/90949.html

示例代码

    public void updateRowIncrement() {
        PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
                .addPrimaryKeyColumn(PK1, PrimaryKeyValue.fromLong(1L))
                .addPrimaryKeyColumn(PK2, PrimaryKeyValue.fromString("string"))
                .build();
        /**
         * 构造RowUpdateChange,设置表名和主键
         */
        RowUpdateChange rowChange = new RowUpdateChange(TABLE_NAME, primaryKey);

        String columnName = "col_long";
        /**
         * 对col_long这一列进行原子加100操作。
         * 若该列之前不存在,会从0开始累加。
         */
        rowChange.increment(new Column(columnName, ColumnValue.fromLong(100)));

        /**
         * 设置返回修改后的该列值。
         */
        rowChange.setReturnType(ReturnType.RT_AFTER_MODIFY);
        rowChange.addReturnColumn(columnName);

        /**
         * 构造UpdateRowRequest
         */
        UpdateRowRequest updateRowRequest = new UpdateRowRequest(rowChange);

        /**
         * 调用updateRow接口。若之前该行不存在,系统会新增该行。
         */
        UpdateRowResponse updateRowResponse = syncClient.updateRow(updateRowRequest);

        /**
         * 打印修改后的该列的值和RequestId
         */
        System.out.printf("UpdateRowSuccess, column [%s] was updated to %d, request id: %s\n",
                columnName,
                updateRowResponse.getRow().getLatestColumn(columnName).getValue().asLong(),
                updateRowResponse.getRequestId());
    }

专家服务

如有疑问或者需要更好的在线支持,欢迎加入钉钉群:“表格存储公开交流群”。群内提供免费的在线专家服务,欢迎扫码加入,群号:23307953

4.png

相关实践学习
消息队列+Serverless+Tablestore:实现高弹性的电商订单系统
基于消息队列以及函数计算,快速部署一个高弹性的商品订单系统,能够应对抢购场景下的高并发情况。
阿里云表格存储使用教程
表格存储(Table Store)是构建在阿里云飞天分布式系统之上的分布式NoSQL数据存储服务,根据99.99%的高可用以及11个9的数据可靠性的标准设计。表格存储通过数据分片和负载均衡技术,实现数据规模与访问并发上的无缝扩展,提供海量结构化数据的存储和实时访问。 产品详情:https://www.aliyun.com/product/ots
目录
相关文章
|
存储 自然语言处理 NoSQL
表格存储 Node.js SDK 开发入门
本文将结合电商订单场景为例,介绍表格存储 Tablestore Node.js SDK 的基本使用方法。
408 1
|
存储 SQL 运维
Tablestore 控制台入门指南
通过阅读本文您将了解和学习到如何通过表格存储Tablestore控制台快速搭建和操作一款零运维、无限容量的数据库。表格存储Tablestore提供了一定使用量的免费额度(10GB数据存储量、1000万按量读写吞吐),供大家体验测试使用。下面将开始介绍如何通过Tablestore控制台创建实例、创建数据表、读写数据、创建索引、搜索数据、删除索引和数据表。
534 0
Tablestore 控制台入门指南
|
存储 自然语言处理 NoSQL
表格存储 Python SDK 开发入门
本文将结合电商订单场景为例,介绍表格存储 Tablestore Python SDK 的基本使用方法。
578 0
|
存储 自然语言处理 NoSQL
表格存储 Go SDK 开发入门
本文将结合电商订单场景为例,介绍表格存储 Tablestore Go SDK 的基本使用方法。
308 0
|
自然语言处理 NoSQL Java
表格存储 Java SDK 开发入门
本文将结合电商订单场景为例,介绍表格存储 Tablestore Java SDK 的基本使用方法。
944 0
|
存储 NoSQL 数据管理
Tablestore入门指南-GetRange范围查询详解
查询接口 表格存储Tablestore作为大数据存储服务,提供了多种数据输出接口,主要包含: 单行读(GetRow)、 批量读(BatchGetRow)、 范围读(GetRange)、多元索引检索(Search)以及通道服务的数据订阅(Tunnel Service)。
2955 0
|
SQL 存储 NoSQL
Tablestore入门手册-条件更新
功能说明 条件更新功能只有在满足条件时才对表中的数据进行更改,当不满足条件时更新失败。 比如有如下场景,初始化数据,当数据字段A为-1时,将A的值更新为指定的内容。比如更新为12;如果不是-1则更新失败。   条件更新支持两个维度。分别是行的存在性检查和列值的条件判断。 第一个维度是行的条件检查,包括如下三种条件: IGNORE:忽略,不做存在
1199 0
|
存储 SQL 移动开发
Tablestore入门手册-UpdateRow接口详解| 1月14号云栖号夜读
今天的首篇文章,讲述了:表格存储Tablestore入门手册系列主要介绍表格存储的各个功能接口和适用场景,帮助客户了解和使用表格存储Tablestore。本文对表格存储Tablestore的UpdateRow接口进行介绍,包括其参数、功能示例、使用场景等。
2791 0
|
存储 索引
表格存储根据多元索引查询条件直接更新数据
表格存储是否可以根据多元索引查询条件直接更新数据?
111 3