表格存儲提供了GetRow接口用于讀取單行數據以及BatchGetRow、GetRange等接口用于讀取多行數據。
如果需要了解表格存儲各場景的應用案例,請參見快速玩轉Tablestore入門與實戰。
查詢方式
表格存儲提供的數據讀取接口包括GetRow、BatchGetRow和GetRange。讀取數據時,請根據實際查詢場景使用相應查詢方式讀取數據。
當要讀取帶有自增主鍵列的表數據時,請確保已獲取到包含自增主鍵列值在內的完整主鍵。更多信息,請參見主鍵列自增。如果未記錄自增主鍵列的值,您可以使用范圍讀取數據按照第一個主鍵列確定范圍讀取數據。
查詢方式 | 說明 | 適用場景 |
調用GetRow接口讀取一行數據。 | 適用于能確定完整主鍵且要讀取行數較少的場景。 | |
調用BatchGetRow接口一次請求讀取多行數據或者一次對多張表進行讀取。 BatchGetRow操作由多個GetRow子操作組成,構造子操作的過程與使用GetRow接口時相同。 | 適用于能確定完整主鍵,且要讀取行數較多或者要讀取多個表中數據的場景。 | |
調用GetRange接口讀取一個范圍內的數據。 GetRange操作支持按照確定范圍進行正序讀取和逆序讀取,可以設置要讀取的行數。如果范圍較大,已掃描的行數或者數據量超過一定限制,會停止掃描,并返回已獲取的行和下一個主鍵信息。您可以根據返回的下一個主鍵信息,繼續發起請求,獲取范圍內剩余的行。 | 適用于能確定完整主鍵范圍或者主鍵前綴的場景。 重要 如果不能確定主鍵前綴,您也可以通過設置完整主鍵范圍均為虛擬點INF_MIN和INF_MAX進行全表數據掃描,但是執行此操作會消耗較多計算資源,請謹慎使用。 | |
調用GetRangeIterator接口迭代讀取數據。 | 適用于能確定完整主鍵范圍或者主鍵前綴,且需要迭代讀取的場景。 |
前提條件
- 已初始化Client,詳情請參見初始化。
- 已創建數據表并寫入數據。
讀取單行數據
調用GetRow接口讀取一行數據。讀取的結果可能有如下兩種:
如果該行存在,則返回該行的各主鍵列以及屬性列。
如果該行不存在,則返回中不包含行,并且不會報錯。
接口
/// <summary>
/// 根據給定的主鍵讀取單行數據。
/// </summary>
/// <param name="request">查詢數據的請求</param>
/// <returns>GetRow的響應</returns>
public GetRowResponse GetRow(GetRowRequest request);
/// <summary>
/// GetRow的異步形式。
/// </summary>
public Task<GetRowResponse> GetRowAsync(GetRowRequest request);
參數
參數 | 說明 |
tableName | 數據表名稱。 |
primaryKey | 行的主鍵。主鍵包括主鍵列名、主鍵類型和主鍵值。 重要 設置的主鍵個數和類型必須和數據表的主鍵個數和類型一致。 |
columnsToGet | 讀取的列集合,列名可以是主鍵列或屬性列。
說明
|
maxVersions | 最多讀取的版本數。 重要 maxVersions與timeRange必須至少設置一個。
|
timeRange | 讀取版本號范圍或特定版本號的數據。更多信息,請參見TimeRange。 重要 maxVersions與timeRange必須至少設置一個。
SpecificTime和 時間戳的單位為毫秒,最小值為0,最大值為 |
filter | 使用過濾器,在服務端對讀取結果再進行一次過濾,只返回符合過濾器中條件的數據行。更多信息,請參見過濾器。 說明 當columnsToGet和filter同時使用時,執行順序是先獲取columnsToGet指定的列,再在返回的列中進行條件過濾。 |
示例
讀取一行數據
以下示例用于讀取一行數據。
//定義行的主鍵,必須與創建表時的TableMeta中定義的一致。
PrimaryKey primaryKey = new PrimaryKey();
primaryKey.Add("pk0", new ColumnValue(0));
primaryKey.Add("pk1", new ColumnValue("abc"));
try
{
//構造查詢請求對象,此處未指定讀取的列,默認讀取整行數據。
var request = new GetRowRequest(TableName, primaryKey);
//調用GetRow接口查詢數據。
var response = otsClient.GetRow(request);
//輸出此行的數據,此處省略,詳見示例代碼的GitHub鏈接。
//如果沒有拋出異常,則說明執行成功。
Console.WriteLine("Get row succeeded.");
}
catch (Exception ex)
{
//如果拋出異常,則說明執行失敗,處理異常。
Console.WriteLine("Update table failed, exception:{0}", ex.Message);
}
詳細代碼請參見GetRow@GitHub。
使用過濾器讀取一行數據
使用過濾器讀取一行數據。
以下示例用于查詢數據后只返回col0和col1的數據,同時在col0列和col1列進行過濾。過濾條件是col0等于5或者col1不等于ff。
//定義行的主鍵,必須與創建表時的TableMeta中定義的一致。
PrimaryKey primaryKey = new PrimaryKey();
primaryKey.Add("pk0", new ColumnValue(0));
primaryKey.Add("pk1", new ColumnValue("abc"));
var rowQueryCriteria = new SingleRowQueryCriteria("SampleTable");
rowQueryCriteria.RowPrimaryKey = primaryKey;
//條件1為col0列的值等于5。
var filter1 = new RelationalCondition("col0",
RelationalCondition.CompareOperator.EQUAL,
new ColumnValue(5));
//條件2為col1列的值不等于ff。
var filter2 = new RelationalCondition("col1", RelationalCondition.CompareOperator.NOT_EQUAL, new ColumnValue("ff"));
//構造組合條件,包括條件1和條件2,關系是OR。
var filter = new CompositeCondition(CompositeCondition.LogicOperator.OR);
filter.AddCondition(filter1);
filter.AddCondition(filter2);
rowQueryCriteria.Filter = filter;
//設置要查詢和返回的行,查詢和過濾的順序是先在行的[col0,col1]列上查詢,然后再按條件過濾。
rowQueryCriteria.AddColumnsToGet("col0");
rowQueryCriteria.AddColumnsToGet("col1");
//構造GetRowRequest。
var request = new GetRowRequest(rowQueryCriteria);
try
{
//查詢。
var response = otsClient.GetRow(request);
//輸出數據或者相關邏輯操作,此處省略。
//如果沒有拋出異常,則說明執行成功。
Console.WriteLine("Get row with filter succeeded.");
}
catch (Exception ex)
{
//如果拋出異常,則說明執行失敗,處理異常。
Console.WriteLine("Get row with filter failed, exception:{0}", ex.Message);
}
詳細代碼請參見GetRowWithFilter@GitHub。
批量讀取數據
調用BatchGetRow接口一次請求讀取多行數據,也支持一次對多張表進行讀取。BatchGetRow由多個GetRow子操作組成。構造子操作的過程與使用GetRow接口時相同。
BatchGetRow的各個子操作獨立執行,表格存儲會分別返回各個子操作的執行結果。
注意事項
由于批量讀取可能存在部分行失敗的情況,失敗行的錯誤信息在返回的BatchGetRowResponse中,但并不拋出異常。因此調用BatchGetRow接口時,需要檢查返回值,判斷每行的狀態是否成功。
批量讀取的所有行采用相同的參數條件,例如
ColumnsToGet=[colA]
,表示要讀取的所有行都只讀取colA列。BatchGetRow操作單次支持讀取的最大行數為100行。
接口
/// <summary>
/// <para>批量讀取一個或多個表中的若干行數據。</para>
/// <para>BatchGetRow操作可視為多個GetRow操作的集合,各個操作獨立執行,獨立返回結果,獨立計算服務能力單元。</para>
/// 與執行大量的GetRow操作相比,使用BatchGetRow操作可以有效減少請求的響應時間,提高數據的讀取速率。
/// </summary>
/// <param name="request">請求實例</param>
/// <returns>響應實例</returns>
public BatchGetRowResponse BatchGetRow(BatchGetRowRequest request);
/// <summary>
/// BatchGetRow的異步形式。
/// </summary>
public Task<BatchGetRowResponse> BatchGetRowAsync(BatchGetRowRequest request);
示例
以下示例用于批量一次讀取10行。
//構造批量讀的請求對象,設置10行數據的主鍵。
List<PrimaryKey> primaryKeys = new List<PrimaryKey>();
for (int i = 0; i < 10; i++)
{
PrimaryKey primaryKey = new PrimaryKey();
primaryKey.Add("pk0", new ColumnValue(i));
primaryKey.Add("pk1", new ColumnValue("abc"));
primaryKeys.Add(primaryKey);
}
try
{
BatchGetRowRequest request = new BatchGetRowRequest();
request.Add(TableName, primaryKeys);
//調用BatchGetRow接口查詢10行數據。
var response = otsClient.BatchGetRow(request);
var tableRows = response.RowDataGroupByTable;
var rows = tableRows[TableName];
//輸出rows中的數據,此處省略,詳見示例代碼的GitHub鏈接。
//批量操作可能部分成功部分失敗,需要檢查每行的狀態是否成功,詳見示例代碼的GitHub鏈接。
}
catch (Exception ex)
{
//如果拋出異常,則說明執行失敗,處理異常。
Console.WriteLine("Batch get row failed, exception:{0}", ex.Message);
}
詳細代碼請參見BatchGetRow@GitHub。
范圍讀取數據
調用GetRange接口讀取一個范圍內的數據。
GetRange操作支持按照確定范圍進行正序讀取和逆序讀取,可以設置要讀取的行數。如果范圍較大,已掃描的行數或者數據量超過一定限制,會停止掃描,并返回已獲取的行和下一個主鍵信息。您可以根據返回的下一個主鍵信息,繼續發起請求,獲取范圍內剩余的行。
表格存儲表中的行都是按照主鍵排序的,而主鍵是由全部主鍵列按照順序組成的,所以不能理解為表格存儲會按照某列主鍵排序,這是常見的誤區。
注意事項
GetRange操作遵循最左匹配原則,讀取數據時,依次比較第一主鍵列到第四主鍵列。例如表的主鍵包括PK1、PK2、PK3三個主鍵列,讀取數據時,優先比較PK1是否在開始主鍵與結束主鍵的范圍內,如果PK1在設置的主鍵范圍內,則不會再比較其他的主鍵,返回在PK1主鍵范圍內的數據;如果PK1在設置的主鍵邊界上,則繼續比較PK2是否在開始主鍵與結束主鍵的范圍內,以此類推。關于范圍查詢原理的更多信息,請參見GetRange范圍查詢詳解。
GetRange操作可能在如下情況停止執行并返回數據。
掃描的行數據大小之和達到4 MB。
掃描的行數等于5000。
返回的行數等于最大返回行數。
當前剩余的預留讀吞吐量已全部使用,余量不足以讀取下一條數據。
當使用GetRange掃描的數據量較大時,表格存儲每次請求僅會掃描一次(行數大于5000或者大小大于4 MB停止掃描),超過限制的數據不會繼續返回,需要通過翻頁繼續獲取后面的數據。
接口
/// <summary>
/// 根據范圍條件獲取多行數據。
/// </summary>
/// <param name="request">請求實例</param>
/// <returns>響應實例</returns>
public GetRangeResponse GetRange(GetRangeRequest request);
/// <summary>
/// GetRange的異步版本。
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public Task<GetRangeResponse> GetRangeAsync(GetRangeRequest request);
參數
參數 | 說明 |
tableName | 數據表名稱。 |
direction | 讀取方向。
假設同一表中有兩個主鍵A和B,A小于B,如果正序讀取 |
inclusiveStartPrimaryKey | 本次范圍讀的起始主鍵和結束主鍵,起始主鍵和結束主鍵需要是有效的主鍵或者是由INF_MIN和INF_MAX類型組成的虛擬點,虛擬點的列數必須與主鍵相同。 其中INF_MIN表示無限小,任何類型的值都比它大;INF_MAX表示無限大,任何類型的值都比它小。
數據表中的行按主鍵從小到大排序,讀取范圍是一個左閉右開的區間,正序讀取時,返回的是大于等于起始主鍵且小于結束主鍵的所有的行。 |
exclusiveEndPrimaryKey | |
limit | 數據的最大返回行數,此值必須大于 0。 表格存儲按照正序或者逆序返回指定的最大返回行數后即結束該操作的執行,即使該區間內仍有未返回的數據。此時可以通過返回的斷點記錄本次讀取到的位置,用于下一次讀取。 |
columnsToGet | 讀取的列集合,列名可以是主鍵列或屬性列。
說明
|
maxVersions | 最多讀取的版本數。 重要 maxVersions與timeRange必須至少設置一個。
|
timeRange | 讀取版本號范圍或特定版本號的數據。更多信息,請參見TimeRange。 重要 maxVersions與timeRange必須至少設置一個。
SpecificTime和 時間戳的單位為毫秒,最小值為0,最大值為 |
filter | 使用過濾器,在服務端對讀取結果再進行一次過濾,只返回符合過濾器中條件的數據行。更多信息,請參見過濾器。 說明 當columnsToGet和filter同時使用時,執行順序是先獲取columnsToGet指定的列,再在返回的列中進行條件過濾。 |
nextStartPrimaryKey | 根據返回結果中的nextStartPrimaryKey判斷數據是否全部讀取。
|
示例
以下示例用于按照范圍讀取數據。
//讀取(0, INF_MIN)到(100, INF_MAX)范圍內的所有行。
var inclusiveStartPrimaryKey = new PrimaryKey();
inclusiveStartPrimaryKey.Add("pk0", new ColumnValue(0));
inclusiveStartPrimaryKey.Add("pk1", ColumnValue.INF_MIN);
var exclusiveEndPrimaryKey = new PrimaryKey();
exclusiveEndPrimaryKey.Add("pk0", new ColumnValue(100));
exclusiveEndPrimaryKey.Add("pk1", ColumnValue.INF_MAX);
try
{
//構造范圍讀的請求對象。
var request = new GetRangeRequest(TableName, GetRangeDirection.Forward,
inclusiveStartPrimaryKey, exclusiveEndPrimaryKey);
var response = otsClient.GetRange(request);
//如果一次沒有返回所有數據,則需要繼續查詢。
var rows = response.RowDataList;
var nextStartPrimaryKey = response.NextPrimaryKey;
while (nextStartPrimaryKey != null)
{
request = new GetRangeRequest(TableName, GetRangeDirection.Forward,
nextStartPrimaryKey, exclusiveEndPrimaryKey);
response = otsClient.GetRange(request);
nextStartPrimaryKey = response.NextPrimaryKey;
foreach (RowDataFromGetRange row in response.RowDataList)
{
rows.Add(row);
}
}
//輸出rows中的數據,此處省略,詳見示例代碼的GitHub鏈接。
//如果沒有拋出異常,則說明執行成功。
Console.WriteLine("Get range succeeded");
}
catch (Exception ex)
{
//如果拋出異常,則說明執行失敗,處理異常。
Console.WriteLine("Get range failed, exception:{0}", ex.Message);
}
詳細代碼請參見GetRange@GitHub。
迭代讀取數據
調用GetRangeIterator接口迭代讀取數據。
接口
/// <summary>
/// 根據范圍條件獲取多行數據,返回用來迭代每一行數據的迭代器。
/// </summary>
/// <param name="request"><see cref="GetIteratorRequest"/></param>
/// <returns>返回<see cref="RowDataFromGetRange"/>的迭代器。</returns>
public IEnumerable<RowDataFromGetRange> GetRangeIterator(GetIteratorRequest request);
示例
以下示例用于迭代讀取(0, "a")
到(1000, "xyz")
范圍內的所有行。
//讀取(0, "a")到(1000, "xyz")范圍內的所有行。
PrimaryKey inclusiveStartPrimaryKey = new PrimaryKey();
inclusiveStartPrimaryKey.Add("pk0", new ColumnValue(0));
inclusiveStartPrimaryKey.Add("pk1", new ColumnValue("a"));
PrimaryKey exclusiveEndPrimaryKey = new PrimaryKey();
exclusiveEndPrimaryKey.Add("pk0", new ColumnValue(1000));
exclusiveEndPrimaryKey.Add("pk1", new ColumnValue("xyz"));
//構造一個CapacityUnit,用于記錄迭代過程中消耗的CU值。
var cu = new CapacityUnit(0, 0);
try
{
//構造一個GetIteratorRequest,也支持使用過濾條件。
var request = new GetIteratorRequest(TableName, GetRangeDirection.Forward, inclusiveStartPrimaryKey,
exclusiveEndPrimaryKey, cu);
var iterator = otsClient.GetRangeIterator(request);
//遍歷迭代器,讀取數據。
foreach (var row in iterator)
{
//處理邏輯。
}
Console.WriteLine("Iterate row succeeded");
}
catch (Exception ex)
{
Console.WriteLine("Iterate row failed, exception:{0}", ex.Message);
}
詳細代碼請參見GetRangeIterator@GitHub。