全部產品
Search
文件中心

Tablestore:讀取資料

更新時間:Oct 11, 2024

Tablestore提供了GetRow介面用於讀取單行資料以及BatchGetRow、GetRange等介面用於讀取多行資料。

說明

組成表的基本單位為行,行由主鍵和屬性列組成。其中主鍵是必須的,且每一行的主鍵列的名稱和類型相同;屬性不是必須的,且每一行的屬性可以不同。更多資訊,請參見寬表模型介紹

注意事項

當要讀取帶有自增主鍵列的表資料時,請確保已擷取到包含自增主鍵列值在內的完整主鍵。更多資訊,請參見主鍵列自增

重要

如果未記錄自增主鍵列的值,您可以使用範圍讀取資料按照第一個主鍵列確定範圍讀取資料。

讀取單行資料

調用GetRow介面讀取一行資料。適用於能確定完整主鍵且要讀取行數較少的情境。

讀取單行資料時,您可以配置如下條件過濾所需資料。

  • 系統預設返回所有列,您可以配置只返回指定列的資料。

  • 使用過濾器擷取符合過濾條件的行資料。更多資訊,請參見過濾器

  • 如果為資料表配置了資料多版本,則您可以配置最多讀取幾個版本資料、讀取指定時間範圍或者指定版本號碼的資料。關於資料多版本的更多資訊,請參見資料版本和生命週期

讀取結果可能有如下兩種情況:

  • 如果該行存在,則返回該行的各主鍵列以及屬性列。

  • 如果該行不存在,則返回結果中不包含行,並且不會報錯。

批量讀取資料

調用BatchGetRow介面一次請求讀取多行資料或者一次對多張表進行讀取。適用於能確定完整主鍵,且要讀取行數較多或者要讀取多個表中資料的情境。

BatchGetRow操作由多個GetRow子操作組成,構造子操作的過程與使用GetRow介面時相同。

批量讀取資料時,您可以配置如下條件過濾所需資料。

  • 一次請求中讀取多張表中的資料。

    單次請求中支援讀取的最大行數為100行。

  • 系統預設返回所有列,您可以配置只返回指定列的資料。

    批量讀取的所有行採用相同的參數條件,例如ColumnsToGet=[colA],表示要讀取的所有行都唯讀取colA列。

  • 使用過濾器擷取符合過濾條件的行資料。更多資訊,請參見過濾器

  • 如果為資料表配置了資料多版本,則您可以配置最多讀取幾個版本資料、讀取指定時間範圍或者指定版本號碼的資料。關於資料版本的更多資訊,請參見資料版本和生命週期

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

範圍讀取資料

調用GetRange介面讀取一個範圍內的資料。適用於能確定完整主鍵範圍或者主鍵首碼的情境。

說明

Tablestore表中的行都是按照主鍵排序的,而主鍵是由全部主鍵列按照順序組成的,所以不能理解為Tablestore會按照某列主鍵排序,這是常見的誤區。

GetRange操作遵循最左匹配原則,讀取資料時,依次比較第一主鍵列到第四主鍵列。例如表的主鍵包括PK1、PK2、PK3三個主鍵列,讀取資料時,優先比較PK1是否在開始主鍵與結束主鍵的範圍內,如果PK1在設定的主鍵範圍內,則不會再比較其他的主鍵,返回在PK1主鍵範圍內的資料;如果PK1在設定的主鍵邊界上,則繼續比較PK2是否在開始主鍵與結束主鍵的範圍內,以此類推。

範圍讀取資料時,您可以配置如下條件過濾所需資料。

  • 指定主鍵首碼後其他主鍵列使用虛擬點INF_MIN(無窮小)和INF_MAX(無窮大)讀取資料,或者指定完整主鍵範圍讀取資料。

    重要

    如果不能確定主鍵首碼,您也可以通過設定完整主鍵範圍均為虛擬點INF_MIN和INF_MAX進行全表資料掃描,但是執行此操作會消耗較多計算資源,請謹慎使用。

    如果範圍較大,已掃描的行數或者資料量超過一定限制,會停止掃描,並返回已擷取的行和下一個主鍵資訊。您可以根據返回的下一個主鍵資訊,繼續發起請求,擷取範圍內剩餘的行。

    GetRange操作可能在如下情況停止執行並返回資料。

    • 掃描的行資料大小之和達到4 MB。

    • 掃描的行數等於5000。

    • 返回的行數等於最大返回行數。

    • 當前剩餘的預留讀輸送量已全部使用,餘量不足以讀取下一條資料。

  • 按照正序或者逆序讀取最多指定個數的行資料,例如按照正序讀取最多5行資料。

  • 系統預設返回所有列,您可以配置只返回指定列的資料。

  • 使用過濾器擷取符合過濾條件的行資料。更多資訊,請參見過濾器

    範圍讀取的所有行採用相同的參數條件,例如ColumnsToGet=[colA],表示要讀取的所有行都唯讀取colA列。

  • 如果為資料表配置了資料多版本,則您可以配置最多讀取幾個版本資料、讀取指定時間範圍或者指定版本號碼的資料。關於資料版本的更多資訊,請參見資料版本和生命週期

當使用GetRange掃描的資料量較大時,Tablestore每次請求僅會掃描一次(行數大於5000或者大小大於4 MB停止掃描),超過限制的資料不會繼續返回,需要通過翻頁繼續擷取後面的資料。

使用方式

使用控制台

您可以使用控制台進行單行查詢資料或範圍查詢資料。

  1. 登入Table Store控制台

  2. 概覽頁面,單擊執行個體操作列的執行個體管理

  3. 執行個體詳情頁簽的資料表列表地區,單擊資料表操作列的查詢/搜尋

  4. 資料管理頁簽,單擊查詢資料,根據實際選擇單行讀取資料或者範圍讀取資料。

    讀取單行資料

    1. 查詢資料對話方塊,選擇查詢範圍單行查詢,並選擇要查詢的表。

    2. 系統預設返回所有列。如需顯示指定屬性列,請關閉擷取所有列並輸入需要返回的屬性列。

      多個屬性列之間用半形逗號(,)隔開。

    3. 輸入目標行的主索引值

      主索引值的完整性和準確性均會影響查詢。

    4. 輸入最大版本數,指定需要返回的版本數。

    5. 單擊確定

    範圍讀取資料

    1. 查詢資料對話方塊,選擇查詢範圍範圍查詢,並選擇要查詢的表。

    2. 系統預設返回所有列。如需顯示指定屬性列,請關閉擷取所有列並輸入需要返回的屬性列。

      多個屬性列之間用半形逗號(,)隔開。

    3. 輸入起始主鍵列和結束主鍵列。

    4. 重要
      • 範圍查詢優先使用第一個主索引值進行查詢,當設定的第一個主索引值一致時,系統會使用第二個主索引值進行查詢,其他主鍵的查詢規則同上。

      • 讀取範圍是前開後閉的區間。

    5. 輸入最大版本數,指定需要返回的版本數。

    6. 設定查詢結果的排序方向,可選正序查詢逆序查詢

    7. 單擊確定

使用命令列工具CLI

您可以使用命令列工具執行如下命令讀取資料。

  • 執行get命令讀取單行資料。更多資訊,請參見讀取資料

    以下樣本用於讀取第一主鍵列值為“86”,第二主鍵列值為6771的行資料。

    get --pk '["86",6771]'
  • 執行scan命令範圍讀取資料。更多資訊,請參見匯出資料

    以下樣本用於逆序讀取["86",7000]["86",6770]主鍵範圍之間的行資料,且只返回pid列。

    scan --begin '["86",7000]' --end '["86",6770]' --backward --columns pid

使用SDK

您可以使用Java SDKGo SDKPython SDKNode.js SDK.NET SDKPHP SDK讀取資料。此處以Java SDK為例介紹讀取資料的使用。

讀取單行資料

讀取資料時,您可以指定要讀取的資料版本、要讀取的列、過濾器、正則過濾等。

  • 讀取最新版本資料和指定列

    以下樣本用於讀取資料表中的一行資料,設定讀取最新版本的資料和讀取指定的列。

    private static void getRow(SyncClient client, String pkValue) {
        //構造主鍵。
        PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryKeyBuilder.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString(pkValue));
        PrimaryKey primaryKey = primaryKeyBuilder.build();
    
        //讀取一行資料,設定資料表名稱。
        SingleRowQueryCriteria criteria = new SingleRowQueryCriteria("<TABLE_NAME>", primaryKey);
        //設定讀取最新版本。
        criteria.setMaxVersions(1);
        GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria));
        Row row = getRowResponse.getRow();
    
        System.out.println("讀取完畢,結果為: ");
        System.out.println(row);
    
        //設定讀取某些列。
        criteria.addColumnsToGet("Col0");
        getRowResponse = client.getRow(new GetRowRequest(criteria));
        row = getRowResponse.getRow();
    
        System.out.println("讀取完畢,結果為:");
        System.out.println(row);
    } 
  • 讀取資料時使用過濾器

    以下樣本用於讀取資料表中的一行資料,設定讀取最新版本的資料以及根據Col0列的值過濾資料。

    private static void getRow(SyncClient client, String pkValue) {
        //構造主鍵。
        PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryKeyBuilder.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString(pkValue));
        PrimaryKey primaryKey = primaryKeyBuilder.build();
    
        //讀取一行資料,設定資料表名稱。
        SingleRowQueryCriteria criteria = new SingleRowQueryCriteria("<TABLE_NAME>", primaryKey);
        //設定讀取最新版本。
        criteria.setMaxVersions(1);
    
        //設定過濾器,當Col0列的值為0時,返回該行。
        SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter("Col0",
                SingleColumnValueFilter.CompareOperator.EQUAL, ColumnValue.fromLong(0));
        //如果Col0列不存在,則不返回該行。
        singleColumnValueFilter.setPassIfMissing(false);
        criteria.setFilter(singleColumnValueFilter);
    
        GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria));
        Row row = getRowResponse.getRow();
    
        System.out.println("讀取完畢,結果為: ");
        System.out.println(row);
    }
  • 讀取資料時使用正則過濾

    以下樣本用於讀取資料表一行中Col1列的資料,並對該列的資料執行正則過濾。

    private static void getRow(SyncClient client, String pkValue) {
        //設定資料表名稱。
        SingleRowQueryCriteria criteria = new SingleRowQueryCriteria("<TABLE_NAME>");
     
        //構造主鍵。
        PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
            .addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString(pkValue))
            .build();
        criteria.setPrimaryKey(primaryKey);
     
        // 設定讀取最新版本。
        criteria.setMaxVersions(1);
     
        // 設定過濾器,當cast<int>(regex(Col1)) > 100時,返回該行。
        RegexRule regexRule = new RegexRule("t1:([0-9]+),", RegexRule.CastType.VT_INTEGER);
        SingleColumnValueRegexFilter filter =  new SingleColumnValueRegexFilter("Col1",
            regexRule,SingleColumnValueRegexFilter.CompareOperator.GREATER_THAN, ColumnValue.fromLong(100));
        criteria.setFilter(filter);
     
        GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria));
        Row row = getRowResponse.getRow();
    
        System.out.println("讀取完畢,結果為: ");
        System.out.println(row);
    }

批量讀取資料

以下樣本用於讀取10行,設定版本條件、要讀取的列、過濾器等。

private static void batchGetRow(SyncClient client) {
    //設定資料表名稱。
    MultiRowQueryCriteria multiRowQueryCriteria = new MultiRowQueryCriteria("<TABLE_NAME>");
    //加入10個要讀取的行。
    for (int i = 0; i < 10; i++) {
        PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryKeyBuilder.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString("pk" + i));
        PrimaryKey primaryKey = primaryKeyBuilder.build();
        multiRowQueryCriteria.addRow(primaryKey);
    }
    //添加條件。
    multiRowQueryCriteria.setMaxVersions(1);
    multiRowQueryCriteria.addColumnsToGet("Col0");
    multiRowQueryCriteria.addColumnsToGet("Col1");
    SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter("Col0",
            SingleColumnValueFilter.CompareOperator.EQUAL, ColumnValue.fromLong(0));
    singleColumnValueFilter.setPassIfMissing(false);
    multiRowQueryCriteria.setFilter(singleColumnValueFilter);

    BatchGetRowRequest batchGetRowRequest = new BatchGetRowRequest();
    //BatchGetRow支援讀取多個表的資料,一個multiRowQueryCriteria對應一個表的查詢條件,可以添加多個multiRowQueryCriteria。
    batchGetRowRequest.addMultiRowQueryCriteria(multiRowQueryCriteria);

    BatchGetRowResponse batchGetRowResponse = client.batchGetRow(batchGetRowRequest);

    System.out.println("是否全部成功:" + batchGetRowResponse.isAllSucceed());
    System.out.println("讀取完畢,結果為: ");
    for (BatchGetRowResponse.RowResult rowResult : batchGetRowResponse.getSucceedRows()) {
        System.out.println(rowResult.getRow());
    }
    if (!batchGetRowResponse.isAllSucceed()) {
        for (BatchGetRowResponse.RowResult rowResult : batchGetRowResponse.getFailedRows()) {
            System.out.println("失敗的行:" + batchGetRowRequest.getPrimaryKey(rowResult.getTableName(), rowResult.getIndex()));
            System.out.println("失敗原因:" + rowResult.getError());
        }

        /**
         * 可以通過createRequestForRetry方法再構造一個請求對失敗的行進行重試。此處只給出構造重試請求的部分。
         * 推薦的重試方法是使用SDK的自訂重試策略功能,支援對batch操作的部分行錯誤進行重試。設定重試策略後,調用介面處無需增加重試代碼。
         */
        BatchGetRowRequest retryRequest = batchGetRowRequest.createRequestForRetry(batchGetRowResponse.getFailedRows());
    }
}

範圍讀取資料

  • 按照確定範圍讀取資料

    以下樣本用於按照確定範圍進行正序讀取,判斷nextStartPrimaryKey是否為空白,讀取完範圍內的全部資料。

    private static void getRange(SyncClient client, String startPkValue, String endPkValue) {
        //設定資料表名稱。
        RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria("<TABLE_NAME>");
    
        //設定起始主鍵。
        PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryKeyBuilder.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString(startPkValue));
        rangeRowQueryCriteria.setInclusiveStartPrimaryKey(primaryKeyBuilder.build());
    
        //設定結束主鍵。
        primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryKeyBuilder.addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString(endPkValue));
        rangeRowQueryCriteria.setExclusiveEndPrimaryKey(primaryKeyBuilder.build());
    
        rangeRowQueryCriteria.setMaxVersions(1);
    
        System.out.println("GetRange的結果為:");
        while (true) {
            GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria));
            for (Row row : getRangeResponse.getRows()) {
                System.out.println(row);
            }
    
            //如果NextStartPrimaryKey不為null,則繼續讀取。
            if (getRangeResponse.getNextStartPrimaryKey() != null) {
                rangeRowQueryCriteria.setInclusiveStartPrimaryKey(getRangeResponse.getNextStartPrimaryKey());
            } else {
                break;
            }
        }
    }         
  • 按照第一個主鍵列確定範圍讀取資料

    以下樣本用於按照第一個主鍵列確定範圍、第二主鍵列從最小值(INF_MIN)到最大值(INF_MAX)進行正序讀取,判斷nextStartPrimaryKey是否為null,讀取完範圍內的全部資料。

    private static void getRange(SyncClient client, String startPkValue, String endPkValue) {
        //設定資料表名稱。
        RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria("<TABLE_NAME>");
        //設定起始主鍵,以兩個主鍵為例。
        PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryKeyBuilder.addPrimaryKeyColumn("pk1", PrimaryKeyValue.fromString(startPkValue));//確定值。
        primaryKeyBuilder.addPrimaryKeyColumn("pk2", PrimaryKeyValue.INF_MIN);//最小值。
        rangeRowQueryCriteria.setInclusiveStartPrimaryKey(primaryKeyBuilder.build());
    
        //設定結束主鍵。
        primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryKeyBuilder.addPrimaryKeyColumn("pk1", PrimaryKeyValue.fromString(endPkValue));//確定值。
        primaryKeyBuilder.addPrimaryKeyColumn("pk2", PrimaryKeyValue.INF_MAX);//最大值。
        rangeRowQueryCriteria.setExclusiveEndPrimaryKey(primaryKeyBuilder.build());
    
        rangeRowQueryCriteria.setMaxVersions(1);
    
        System.out.println("GetRange的結果為:");
        while (true) {
            GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria));
            for (Row row : getRangeResponse.getRows()) {
                System.out.println(row);
            }
    
            //如果nextStartPrimaryKey不為null,則繼續讀取。
            if (getRangeResponse.getNextStartPrimaryKey() != null) {
                rangeRowQueryCriteria.setInclusiveStartPrimaryKey(getRangeResponse.getNextStartPrimaryKey());
            } else {
                break;
            }
        }
    }    
  • 按照確定範圍讀取資料並對指定列使用正則過濾

    以下樣本用於讀取主鍵範圍為["pk:2020-01-01.log", "pk:2021-01-01.log")時Col1列的資料,並對該列的資料執行正則過濾。

    private static void getRange(SyncClient client) {
        //設定資料表名稱。
        RangeRowQueryCriteria criteria = new RangeRowQueryCriteria("<TABLE_NAME>");
     
        //設定主鍵範圍為["pk:2020-01-01.log", "pk:2021-01-01.log"),讀取範圍為左閉右開的區間。
        PrimaryKey pk0 = PrimaryKeyBuilder.createPrimaryKeyBuilder()
            .addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString("2020-01-01.log"))
            .build();
        PrimaryKey pk1 = PrimaryKeyBuilder.createPrimaryKeyBuilder()
            .addPrimaryKeyColumn("pk", PrimaryKeyValue.fromString("2021-01-01.log"))
            .build();
        criteria.setInclusiveStartPrimaryKey(pk0);
        criteria.setExclusiveEndPrimaryKey(pk1);
     
        //設定讀取最新版本。
        criteria.setMaxVersions(1);
     
        //設定過濾器,當cast<int>(regex(Col1)) > 100時,返回該行。
        RegexRule regexRule = new RegexRule("t1:([0-9]+),", RegexRule.CastType.VT_INTEGER);
        SingleColumnValueRegexFilter filter =  new SingleColumnValueRegexFilter("Col1",
            regexRule,SingleColumnValueRegexFilter.CompareOperator.GREATER_THAN,ColumnValue.fromLong(100));
        criteria.setFilter(filter);
    
        while (true) {
            GetRangeResponse resp = client.getRange(new GetRangeRequest(criteria));
            for (Row row : resp.getRows()) {
                // do something
                System.out.println(row);
            }
            if (resp.getNextStartPrimaryKey() != null) {
                criteria.setInclusiveStartPrimaryKey(resp.getNextStartPrimaryKey());
            } else {
                break;
            }
       }
    }

計費說明

根據實際計算消耗折算成CU進行計費。同時根據執行個體類型不同,計費時需要區分按量讀寫CU以及預留讀寫CU。

說明

關於執行個體類型和CU的更多資訊,請分別參見執行個體讀寫輸送量

讀取資料時不消耗寫CU,消耗的讀CU計算規則如下:

  • GetRow操作消耗的讀CU

    讀取的行主鍵的資料大小與實際讀取的屬性列資料大小之和,按4 KB向上取整。如果操作指定的行不存在,則消耗1單位讀CU。

  • BatchGetRow操作消耗的讀CU

    按照將每個RowInBatchGetRowRequest視為一個GetRow操作獨立計算讀CU。

  • GetRange操作消耗的讀CU

    從區間起始點到下一條未讀資料的起始點,所有行主鍵資料大小與實際掃描的所有屬性列資料大小之和按4 KB向上取整計算消耗的讀CU。例如掃描範圍中包含10行資料,每行主鍵資料大小與實際掃描的所有屬性列資料之和為330 Byte,則消耗的讀CU為1(資料總和3.3 KB,除以4 KB向上取整為1)。