Tablestore入门手册-UpdateRow接口详解

本文涉及的产品
表格存储 Tablestore,50G 2个月
简介: 表格存储Tablestore入门手册系列主要介绍表格存储的各个功能接口和适用场景,帮助客户了解和使用表格存储Tablestore。本文对表格存储Tablestore的UpdateRow接口进行介绍,包括其参数、功能示例、使用场景等。 ## 接口概述 UpdateRow接口是表格存储Tablestore提供的基础读写接口之一,用于对某一行进行更新操作,若指定行不存在,UpdateRo

表格存储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
表格存储(Tablestore)入门指南
表格存储(Tablestore)入门指南内容简介了表格存储(Tablestore)是阿里云自研的 NoSQL 多模型数据库,提供海量结构化数据存储以及快速的查询和分析服务。
18494 2
|
1月前
|
存储 NoSQL 开发工具
开发者如何使用表格存储 Tablestore
【10月更文挑战第11天】开发者如何使用表格存储 Tablestore
93 0
|
5月前
|
SQL 分布式计算 DataWorks
DataWorks产品使用合集之对于Hologres的Python查询,该如何操作
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
51 0
|
SQL Kubernetes 关系型数据库
实践教程之如何使用PolarDB-X进行数据导入导出
PolarDB-X 为了方便用户体验,提供了免费的实验环境,您可以在实验环境里体验 PolarDB-X 的安装部署和各种内核特性。除了免费的实验,PolarDB-X 也提供免费的视频课程,手把手教你玩转 PolarDB-X 分布式数据库。本期实验将指导您如何使用PolarDB-X进行数据导入导出。
《阿里云产品手册2022-2023 版》——表格存储
《阿里云产品手册2022-2023 版》——表格存储
145 0
|
存储 SQL 分布式计算
《阿里云存储手册》——表格存储Tablestore
《阿里云存储手册》——表格存储Tablestore
296 0
|
存储 SQL 分布式计算
表格存储使用场景介绍| 学习笔记
快速学习表格存储使用场景介绍。
表格存储使用场景介绍| 学习笔记
|
NoSQL 开发者
《玩转 Tablestore 入门与实战》电子版地址
阿里云基础产品事业部Tablestore团队联合阿里云开发者社区《玩转 Tablestore 入门与实战》重磅来袭!466页技术干货,分享阿里内部基于 Tablestore 的优秀架构设计经验和典型应用场景,带你揭开Tablestore 的神秘面纱!
146 0
《玩转 Tablestore 入门与实战》电子版地址
|
SQL 存储 分布式计算
MaxCompute Tunnel 技术原理及开发实战|学习笔记
快速学习 MaxCompute Tunnel 技术原理及开发实战
423 0
MaxCompute Tunnel 技术原理及开发实战|学习笔记
|
SQL 分布式计算 DataWorks
【MaxCompute 常见问题】 快速入门
如何使用 Tunnel 命令导入数据? 可以使用 tunnel upload 命令上传数据至 MaxCompute 表,每一次上传只支持数据上传到一张表或表的一个分区。
【MaxCompute 常见问题】 快速入门
下一篇
无影云桌面