全部產品
Search
文件中心

Tablestore:寫入資料

更新時間:Dec 20, 2024

Tablestore提供了單行和批量的方式寫入資料到資料表,您可以結合實際情境選擇適合的資料寫入方式。本文為您介紹如何通過Java SDK寫入Table Store資料。

前提條件

  • 初始化OTSClient。具體操作,請參見初始化OTSClient

  • 在Table Store的執行個體中建立資料表。

寫入方式

Tablestore提供單行寫入、單行更新和批量寫入資料功能。不同寫入方式的區別和適用情境請參見下表。

寫入方式

說明

適用情境

寫入單行資料

調用 PutRow 介面新寫入一行資料。

適用於寫入少量資料的情境。

更新單行資料

調用 UpdateRow 介面更新一行資料。

適用於更新少量資料的情境。

批量寫入資料

調用 BatchWriteRow 介面在一次請求中進行批量寫入操作或者一次對多張表進行寫入。

適用於增刪改大量資料或者同時需要進行資料增刪改操作的情境。

參數說明

資料寫入的相關參數說明如下表所示。

參數

說明

tableName

資料表的名稱。

primaryKey

資料表的主鍵資訊。包括主鍵列名、主鍵類型和主索引值。

重要
  • 設定的主鍵個數和類型必須與資料表的主鍵個數和類型保持一致。

  • 主鍵為自增列時,只需將自增列的值設定為預留位置。具體方式,請參見主鍵列自增

column

屬性列資訊。包括屬性列名稱、屬性列的值、屬性列資料類型(可選)和時間戳記(可選)。

  • 屬性列名稱。由英文字元(a~z)或(A~Z)、數字(0~9)和底線(_)組成,首字母不能為數字,大小寫敏感,長度在1~255個字元之間。

  • 屬性列資料類型。支援字串、整型、二進位、浮點數和布爾值。

  • 時間戳記即資料的版本號碼。預設由系統自動產生,也可以自行指定。更多關於版本號碼的資訊,請參見資料版本和生命週期

說明
  • 刪除屬性列時,只需要設定屬性列名稱。

  • 刪除屬性列特定版本的資料時,需要設定屬性列名稱和時間戳記。

  • 刪除一行資料的全部屬性列不等於刪除該行。如果需要刪除該行,請使用DeleteRow介面操作,具體操作請參見刪除資料

condition

寫入條件。包括行存在性條件和列判斷條件,更多資訊,請參見條件更新

寫入單行資料

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

說明

本文樣本中的pkValue均表示主鍵列值,使用時請根據實際填寫具體資料。寫入資料時,您需要指定完整的主鍵以及需要寫入的屬性列資訊。您也可以根據需要配置資料寫入條件,例如設定只有在行不存在時才寫入資料。

以下範例程式碼為您展示如何使用系統自動產生的資料版本號碼、自訂資料版本號碼以及如何使用寫入條件。

寫入資料時系統自動產生資料版本號碼

以下範例程式碼新增了一行資料,寫入10個屬性列,每列寫入1個版本,由系統自動產生資料的版本號碼(時間戳記)。

private static void putRow(SyncClient client, String pkValue) {
    //構造主鍵。
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("your_primaryKey", PrimaryKeyValue.fromString(pkValue));
    PrimaryKey primaryKey = primaryKeyBuilder.build();
    //設定資料表名稱。
    RowPutChange rowPutChange = new RowPutChange("your_tableName", primaryKey);

    //加入一些屬性列。
    for (int i = 0; i < 10; i++) {
        rowPutChange.addColumn(new Column("Col" + i, ColumnValue.fromLong(i)));
    }

    client.putRow(new PutRowRequest(rowPutChange));
}

插入資料時自訂資料版本號碼

以下範例程式碼新增了一行資料,寫入10個屬性列,每列寫入3個版本,並且自訂資料的版本號碼。

private static void putRow(SyncClient client, String pkValue) {
    //構造主鍵。
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("your_primaryKey", PrimaryKeyValue.fromString(pkValue));
    PrimaryKey primaryKey = primaryKeyBuilder.build();
    //設定資料表名稱。
    RowPutChange rowPutChange = new RowPutChange("your_tableName", 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));
}

插入資料時使用行條件

以下範例程式碼在原行不存在時新增一條資料,寫入10個屬性列,每列寫入3個版本,並且自訂資料的版本號碼(時間戳記)。

private static void putRow(SyncClient client, String pkValue) {
    //構造主鍵。
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("your_primaryKey", PrimaryKeyValue.fromString(pkValue));
    PrimaryKey primaryKey = primaryKeyBuilder.build();
    //設定資料表名稱。
    RowPutChange rowPutChange = new RowPutChange("your_tableName", 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));
}

插入資料時同時使用列和行條件

以下範例程式碼在原行存在且Col0列的值大於100時寫入資料,寫入10個屬性列,每列寫入3個版本,並且自訂資料的版本號碼(時間戳記)。

private static void putRow(SyncClient client, String pkValue) {
    //構造主鍵。
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("your_primaryKey", PrimaryKeyValue.fromString(pkValue));
    PrimaryKey primaryKey = primaryKeyBuilder.build();
    //設定資料表名稱。
    RowPutChange rowPutChange = new RowPutChange("your_tableName", 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));
}

更新單行資料

調用UpdateRow介面更新一行資料。可以更新屬性列的值、增加和刪除屬性列、刪除屬性列指定版本的資料。如果更新的行不存在,則新增一行資料。

說明

當請求中只包含刪除指定的屬性列並且該行不存在時,則該請求不會新增行資料。

以下範例程式碼均更新了一些列、刪除Col1列的某一資料版本,並刪除了Col0列,區別在於是否使用了寫入條件。

更新資料時不使用條件

以下範例程式碼在更新資料時不使用寫入條件。

private static void updateRow(SyncClient client, String pkValue) {
    //構造主鍵。
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("your_primaryKey", PrimaryKeyValue.fromString(pkValue));
    PrimaryKey primaryKey = primaryKeyBuilder.build();
    //設定資料表名稱。
    RowUpdateChange rowUpdateChange = new RowUpdateChange("your_tableName", primaryKey);

    //更新一些列。
    for (int i = 0; i < 10; i++) {
        rowUpdateChange.put(new Column("Col" + i, ColumnValue.fromLong(i)));
    }

    //刪除某列的某一版本。
    rowUpdateChange.deleteColumn("Col1", 1465373223000L);

    //刪除某一列。
    rowUpdateChange.deleteColumns("Col0");

    client.updateRow(new UpdateRowRequest(rowUpdateChange));
}

更新資料時使用列和行條件

以下範例程式碼在原行存在且Col0列的值大於100時才更新資料。

private static void updateRow(SyncClient client, String pkValue) {
    //構造主鍵。
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("your_primaryKey", PrimaryKeyValue.fromString(pkValue));
    PrimaryKey primaryKey = primaryKeyBuilder.build();
    //設定資料表名稱。
    RowUpdateChange rowUpdateChange = new RowUpdateChange("your_tableName", 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("Col1", 1465373223000L);

    //刪除某一列。
    rowUpdateChange.deleteColumns("Col0");

    client.updateRow(new UpdateRowRequest(rowUpdateChange));
}

批量寫入資料

調用BatchWriteRow介面在一次請求中進行批量寫入操作或者一次對多張表進行寫入。

BatchWriteRow操作由多個PutRow、UpdateRow或DeleteRow子操作組成,構造子操作的過程與單獨使用PutRow介面、UpdateRow介面和DeleteRow介面相同。各個子操作獨立執行,Tablestore會分別返回每個子操作的執行結果。

說明
  • 服務端檢查到部分操作的參數錯誤時,BatchWriteRow介面會拋出參數錯誤異常,此時該請求中的所有操作都將不執行。

  • 批量寫入過程中可能存在部分行寫入失敗的情況,請求返回的BatchWriteRowResponse包含了失敗行的Index及錯誤資訊。建議您檢查傳回值,可以通過BatchWriteRowResponse的isAllSucceed方法判斷批量寫入是否全部成功。

以下範例程式碼的BatchWriteRow請求中包含2個PutRow操作、1個UpdateRow操作和1個DeleteRow操作。

private static void batchWriteRow(SyncClient client) {
    BatchWriteRowRequest batchWriteRowRequest = new BatchWriteRowRequest();

    //構造第1個rowPutChange。
    PrimaryKeyBuilder pk1Builder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    pk1Builder.addPrimaryKeyColumn("your_primaryKey", PrimaryKeyValue.fromString("pkValue1"));
    //設定資料表名稱。
    RowPutChange rowPutChange1 = new RowPutChange("your_tableName", pk1Builder.build());
    //添加一些列。
    for (int i = 0; i < 10; i++) {
        rowPutChange1.addColumn(new Column("Col" + i, ColumnValue.fromLong(i)));
    }
    //添加到batch操作中。
    batchWriteRowRequest.addRowChange(rowPutChange1);

    //構造第2個rowPutChange。
    PrimaryKeyBuilder pk2Builder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    pk2Builder.addPrimaryKeyColumn("your_primaryKey", PrimaryKeyValue.fromString("pkValue2"));
    //設定資料表名稱。
    RowPutChange rowPutChange2 = new RowPutChange("your_tableName", 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("your_primaryKey", PrimaryKeyValue.fromString("pkValue3"));
    //設定資料表名稱。
    RowUpdateChange rowUpdateChange = new RowUpdateChange("your_tableName", pk3Builder.build());
    //添加一些列。
    for (int i = 0; i < 10; i++) {
        rowUpdateChange.put(new Column("Col" + i, ColumnValue.fromLong(i)));
    }
    //刪除一列。
    rowUpdateChange.deleteColumns("Col0");
    //添加到batch操作中。
    batchWriteRowRequest.addRowChange(rowUpdateChange);

    //構造rowDeleteChange。
    PrimaryKeyBuilder pk4Builder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    pk4Builder.addPrimaryKeyColumn("your_primaryKey", PrimaryKeyValue.fromString("pkValue4"));
    //設定資料表名稱。
    RowDeleteChange rowDeleteChange = new RowDeleteChange("your_tableName", 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());
    }
}

常見問題

相關文檔

  • 如果您想瞭解更多Table Store資料操作的範例程式碼,請參見GitHub範例程式碼

  • BatchWriteRow介面單次只能寫入200行資料,如果您需要高並發資料寫入,請使用TableStoreWriter工具。更多資訊,請參見使用TableStoreWriter並發寫入資料

  • 如果您需要為線上應用提供即時統計功能,例如統計文章的PV(頁面瀏覽量)等,可以通過原子計數器實現。更多資訊,請參見原子計數器

  • 如果您需要進行單行寫或多行寫的原子操作,可以通過局部事務實現。更多資訊,請參見局部事務