Tablestore入门手册-UpdateRow接口详解
表格存儲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參數說明
具體參數說明:
| TxnRequest(基類) | 抽象類,包含TransactionId成員變量,繼承該類的請求類型可用于局部事務中。 | TransactionId的使用可參考局部事務的文檔。 |
| UpdateRowRequest | UpdateRow接口的請求類型,包含一個成員變量:RowUpdateChange。 繼承自TxnRequest,表示該請求可用于局部事務中。 | ? |
| RowUpdateChange | 本次更新的具體請求參數。 | ? |
RowUpdateChange參數說明
具體參數說明:
| 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參數說明
具體參數說明:
| 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操作,對某一行寫入兩列,指定版本號寫入,同時刪除某列的某個版本,也需要指定要刪除的版本號。
注意:在指定版本號時,需要保證該版本號在表上設置的最大版本偏差內,若超出該偏差范圍,可以調整表上的最大版本偏差設置。
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());}
原文鏈接
本文為阿里云原創內容,未經允許不得轉載。
總結
以上是生活随笔為你收集整理的Tablestore入门手册-UpdateRow接口详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里每天究竟要抵御多少攻击
- 下一篇: 120万人同时在线考试,这么大的流量如何