Tablestore提供了PutRow和UpdateRow介面用於寫入單行資料以及BatchWriteRow介面用於批量寫入資料。

前提條件

  • 已初始化Client,詳情請參見初始化
  • 已建立資料表並寫入資料。

插入單行資料

調用PutRow介面新寫入一行資料。如果該行已存在,則先刪除原行資料(原行的所有列以及所有版本的資料),再寫入新行資料。

介面

/// <summary>
/// 指定資料表名稱、主鍵和屬性,寫入一行資料。返回本次操作消耗的CapacityUnit。
/// </summary>
/// <param name="request">插入資料的請求</param>
/// <returns>本次操作消耗的CapacityUnit</returns>
public PutRowResponse PutRow(PutRowRequest request);

/// <summary>
/// PutRow的非同步形式。
/// </summary>
public Task<PutRowResponse> PutRowAsync(PutRowRequest request);                    

參數

參數 說明
tableName 資料表名稱。
primaryKey 行的主鍵。
说明
  • 設定的主鍵個數和類型必須和資料表的主鍵個數和類型一致。
  • 當主鍵為自增列時,只需將自增列的值設定為預留位置。更多資訊,請參見主鍵列自增
attribute 行的屬性列。
  • 每一項的順序是屬性名稱、屬性類型(可選)、屬性值、時間戳記(可選)。
  • 時間戳記即資料的版本號碼。更多資訊,請參見資料版本和生命週期

    資料的版本號碼可以由系統自動產生或者自訂,如果不設定此參數,則預設由系統自動產生。

    • 當由系統自動產生資料的版本號碼時,系統預設將目前時間的毫秒單位時間戳記(從1970-01-01 00:00:00 UTC計算起的毫秒數)作為資料的版本號碼。
    • 當自訂資料的版本號碼時,版本號碼需要為64位的毫秒單位時間戳記且在有效版本範圍內。
condition 支援使用條件更新,可以設定原行的存在性條件或者原行中某列的列值條件。更多資訊,請參見條件更新
说明
  • 從.NET SDK 2.2.0版本開始,Condition不僅支援行條件,也支援列條件。
  • Condition.IGNORE、Condition.EXPECT_EXIST和Condition.EXPECT_NOT_EXIST從.NET SDK 3.0.0版本開始被廢棄,請替換為new Condition (RowExistenceExpectation.IGNORE)、new Condition (RowExistenceExpectation.EXPECT_EXIST)和new Condition (RowExistenceExpectation.EXPECT_NOT_EXIST)。
  • RowExistenceExpectation.IGNORE表示無論此行是否存在均會插入新資料,如果之前行已存在,則寫入資料時會覆蓋原有資料。
  • RowExistenceExpectation.EXPECT_EXIST表示只有此行存在時才會插入新資料,寫入資料時會覆蓋原有資料。
  • RowExistenceExpectation.EXPECT_NOT_EXIST表示只有此行不存在時才會插入資料。

樣本

  • 樣本1

    插入一行資料。

    //定義行的主鍵,必須與建立表時的TableMeta中定義的一致。
    var primaryKey = new PrimaryKey();
    primaryKey.Add("pk0", new ColumnValue(0));
    primaryKey.Add("pk1", new ColumnValue("abc"));
    
    //定義要寫入該行的屬性列。
    var attribute = new AttributeColumns();
    attribute.Add("col0", new ColumnValue(0));
    attribute.Add("col1", new ColumnValue("a"));
    attribute.Add("col2", new ColumnValue(true));
    
    try
    {
        //構造插入資料的請求對象,RowExistenceExpectation.IGNORE表示無論此行是否存在均會插入新資料。
        var request = new PutRowRequest("SampleTable", new Condition(RowExistenceExpectation.IGNORE),
                                primaryKey, attribute);
    
        //調用PutRow介面插入資料。
        otsClient.PutRow(request);
    
        //如果沒有拋出異常,則說明執行成功。
        Console.WriteLine("Put row succeeded.");
    }
    catch (Exception ex)
    {
        //如果拋出異常,則說明執行失敗,處理異常。
        Console.WriteLine("Put row failed, exception:{0}", ex.Message);
    }                    

    詳細代碼請參見PutRow@GitHub

  • 樣本2

    設定條件插入一行資料。如下樣本的條件為當行存在且col0大於24時才執行插入操作。

    //定義行的主鍵,必須與建立表時的TableMeta中定義的一致。
    var primaryKey = new PrimaryKey();
    primaryKey.Add("pk0", new ColumnValue(0));
    primaryKey.Add("pk1", new ColumnValue("abc"));
    
    //定義要寫入該行的屬性列。
    AttributeColumns attribute = new AttributeColumns();
    attribute.Add("col0", new ColumnValue(0));
    attribute.Add("col1", new ColumnValue("a"));
    attribute.Add("col2", new ColumnValue(true));
    
    //當col0列的值大於24時,允許再次插入行,覆蓋掉原值。
    try
    {
        var request = new PutRowRequest(tableName, new Condition(RowExistenceExpectation.EXPECT_EXIST),
                                primaryKey, attribute);
        request.Condition.ColumnCondition = new RelationalCondition("col0",
                                            RelationalCondition.CompareOperator.GREATER_THAN,
                                            new ColumnValue(24));
        otsClient.PutRow(request);
    
        Console.WriteLine("Put row succeeded.");
    }
    catch (Exception ex)
    {
        Console.WriteLine("Put row failed. error:{0}", ex.Message);
    }                   

    詳細代碼請參見ConditionPutRow@GitHub

  • 樣本3

    非同步插入一行資料。

    重要 每一個非同步呼叫都會啟動一個線程,如果連續啟動了很多非同步呼叫,且每個都耗時比較大時,可能會出現逾時。
    try
    {
        var putRowTaskList = new List<Task<PutRowResponse>>();
        for (int i = 0; i < 100; i++)
        {
            //定義行的主鍵,必須與建立表時的TableMeta中定義的一致。
            var primaryKey = new PrimaryKey();
            primaryKey.Add("pk0", new ColumnValue(i));
            primaryKey.Add("pk1", new ColumnValue("abc"));
    
            //定義要寫入該行的屬性列。
            var attribute = new AttributeColumns();
            attribute.Add("col0", new ColumnValue(i));
            attribute.Add("col1", new ColumnValue("a"));
            attribute.Add("col2", new ColumnValue(true));
    
            var request = new PutRowRequest(TableName, new Condition(RowExistenceExpectation.IGNORE),
                                            primaryKey, attribute);
    
            putRowTaskList.Add(TabeStoreClient.PutRowAsync(request));
        }
    
        //等待每個非同步呼叫返回,並列印出消耗的CU值。
        foreach (var task in putRowTaskList)
        {
            task.Wait();
            Console.WriteLine("consumed read:{0}, write:{1}", task.Result.ConsumedCapacityUnit.Read,
                                task.Result.ConsumedCapacityUnit.Write);
        }
    
        //如果沒有拋出異常,則說明執行成功。
        Console.WriteLine("Put row async succeeded.");
    }
    catch (Exception ex)
    {
        //如果拋出異常,則說明執行失敗,處理異常。
        Console.WriteLine("Put row async failed. exception:{0}", ex.Message);
    }                   

    詳細代碼請參見PutRowAsync@GitHub

更新一行資料

調用UpdateRow介面更新一行資料,可以增加和刪除一行中的屬性列,刪除屬性列指定版本的資料,或者更新已存在的屬性列的值。如果更新的行不存在,則新增一行資料。
说明 當UpdateRow請求中只包含刪除指定的列且該行不存在時,則該請求不會新增一行資料。

介面

/// <summary>
/// 更新指定行的資料,如果該行不存在,則新增一行;若該行存在,則根據請求的內容在該行中新增、修改或者刪除指定列的值。
/// </summary>
/// <param name="request">請求執行個體</param>
public UpdateRowResponse UpdateRow(UpdateRowRequest request);

/// <summary>
/// UpdateRow的非同步形式。
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public Task<UpdateRowResponse> UpdateRowAsync(UpdateRowRequest request);            

參數

參數 說明
tableName 資料表名稱。
primaryKey 行的主鍵。
说明 設定的主鍵個數和類型必須和資料表的主鍵個數和類型一致。
condition 使用條件更新,可以設定原行的存在性條件或者原行中某列的列值條件。更多資訊,請參見條件更新
attribute 更新的屬性列。
  • 增加或更新資料時,需要設定屬性名稱、屬性值、屬性類型(可選)、時間戳記(可選)。

    時間戳記即資料的版本號碼,可以由系統自動產生或者自訂,如果不設定此參數,則預設由系統自動產生。更多資訊,請參見資料版本和生命週期

    • 當由系統自動產生資料的版本號碼時,系統預設將目前時間的毫秒單位時間戳記(從1970-01-01 00:00:00 UTC計算起的毫秒數)作為資料的版本號碼。
    • 當自訂資料的版本號碼時,版本號碼需要為64位的毫秒單位時間戳記且在有效版本範圍內。
  • 刪除屬性列特定版本的資料時,只需要設定屬性名稱和時間戳記。

    時間戳記是64位整數,單位為毫秒,表示某個特定版本的資料。

  • 刪除屬性列時,只需要設定屬性名稱。
    说明 刪除一行的全部屬性列不等同於刪除該行,如果需要刪除該行,請使用DeleteRow操作。

樣本

更新一行資料。

//定義行的主鍵,必須與建立表時的TableMeta中定義的一致。
PrimaryKey primaryKey = new PrimaryKey();
primaryKey.Add("pk0", new ColumnValue(0));
primaryKey.Add("pk1", new ColumnValue("abc"));

//定義要寫入該行的屬性列。
UpdateOfAttribute attribute = new UpdateOfAttribute();
attribute.AddAttributeColumnToPut("col0", new ColumnValue(0));
attribute.AddAttributeColumnToPut("col1", new ColumnValue("b")); // 將原先的值'a'改為'b'
attribute.AddAttributeColumnToPut("col2", new ColumnValue(true));

try
{
    //構造更新行的請求對象,RowExistenceExpectation.IGNORE表示無論此行是否存在都執行更新。
    var request = new UpdateRowRequest(TableName, new Condition(RowExistenceExpectation.IGNORE),
                                primaryKey, attribute);
    //調用UpdateRow介面更新資料。
    otsClient.UpdateRow(request);

    //如果沒有拋出異常,則說明執行成功。
    Console.Writeline("Update row succeeded.");
}
catch (Exception ex)
{
    //如果拋出異常,則說明執行失敗,處理異常。
    Console.WriteLine("Update row failed, exception:{0}", ex.Message);
}           

詳細代碼請參見UpdateRow@GitHub

批量寫入資料

調用BatchWriteRow介面在一次請求中進行批量的寫入操作,也支援一次對多張表進行寫入。BatchWriteRow操作由多個PutRow、UpdateRow、DeleteRow子操作組成,構造子操作的過程與使用PutRow介面、UpdateRow介面和DeleteRow介面時相同,也支援使用條件更新。

BatchWriteRow的各個子操作獨立執行,Tablestore會分別返回各個子操作的執行結果。

注意事項

由於批量寫入可能存在部分行失敗的情況,失敗行的Index及錯誤資訊在返回的BatchWriteRowResponse中,但並不拋出異常。因此調用BatchWriteRow介面時,需要檢查傳回值,判斷每行的狀態是否成功;如果不檢查傳回值,則可能會忽略掉部分操作的失敗。

當服務端檢查到某些操作出現參數錯誤時,BatchWriteRow介面可能會拋出參數錯誤的異常,此時該請求中所有的操作都未執行。

介面

/// <summary>
/// <para>批量插入,修改或刪除一個或多個表中的若干行資料。</para>
/// <para>BatchWriteRow操作可視為多個PutRow、UpdateRow、DeleteRow操作的集合,各個操作獨立執行,獨立返回結果,獨立計算服務能力單元。</para>
/// <para>與執行大量的單行寫操作相比,使用BatchWriteRow操作可以有效減少請求的回應時間,提高資料的寫入速率。</para>
/// </summary>
/// <param name="request">請求執行個體</param>
/// <returns>響應執行個體</returns>
public BatchWriteRowResponse BatchWriteRow(BatchWriteRowRequest request);

/// <summary>
/// BatchWriteRow的非同步形式。
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public Task<BatchWriteRowResponse> BatchWriteRowAsync(BatchWriteRowRequest request);            

樣本

批量寫入100行資料。

//構造批量寫的請求對象,設定100行資料的主鍵。
var request = new BatchWriteRowRequest();
var rowChanges = new RowChanges();
for (int i = 0; i < 100; i++)
{
    PrimaryKey primaryKey = new PrimaryKey();
    primaryKey.Add("pk0", new ColumnValue(i));
    primaryKey.Add("pk1", new ColumnValue("abc"));

    //定義要寫入該行的屬性列。
    UpdateOfAttribute attribute = new UpdateOfAttribute();
    attribute.AddAttributeColumnToPut("col0", new ColumnValue(0));
    attribute.AddAttributeColumnToPut("col1", new ColumnValue("a"));
    attribute.AddAttributeColumnToPut("col2", new ColumnValue(true));

    rowChanges.AddUpdate(new Condition(RowExistenceExpectation.IGNORE), primaryKey, attribute);
}

request.Add(TableName, rowChanges);

try
{
    //調用BatchWriteRow介面寫入資料。
    var response = otsClient.BatchWriteRow(request);
    var tableRows = response.TableRespones;
    var rows = tableRows[TableName];

    //大量操作可能部分成功部分失敗,需要檢查每行的狀態是否成功,詳見範例程式碼的GitHub連結。
}
catch (Exception ex)
{
    //如果拋出異常,則說明執行失敗,處理異常。
    Console.WriteLine("Batch put row failed, exception:{0}", ex.Message);
}           

詳細代碼請參見BatchWriteRow@GitHub