Table Store提供了BatchGetRow,BatchWriteRow和GetRange等多行操作的介面。

说明 以下操作為同步介面的樣本,非同步介面的操作請參見非同步介面

批量讀(BatchGetRow)

批量讀取一個或多個表中的若干行資料。

BatchGetRow操作可視為多個GetRow操作的集合,各個操作獨立執行,獨立返回結果,獨立計算服務能力單元。與執行大量的GetRow操作相比,使用BatchGetRow操作可以有效減少請求的回應時間,提高資料的讀取速率。

BatchGetRow可能出現以下兩種錯誤:

  • 請求整體錯誤,比如網路錯誤。這類錯誤存放在batchGetRow()的傳回值裡。
  • 請求整體沒有錯誤,但個別行出錯。這類錯誤存放在相應的行的結果裡。

樣本

BatchGetRowRequest req;
{
    MultiPointQueryCriterion& criterion = req.mutableCriteria().append();
    IVector<MultiPointQueryCriterion::RowKey>& rowkeys = criterion.mutableRowKeys();
    {
        MultiPointQueryCriterion::RowKey& exist = rowkeys.append();
        exist.mutableGet().append() = PrimaryKeyColumn(
            "pkey",
            PrimaryKeyValue::toStr("some key"));
        exist.mutableUserData() = &userDataForSomeKey;
    }
    {
        MultiPointQueryCriterion::RowKey& exist = rowkeys.append();
        exist.mutableGet().append() = PrimaryKeyColumn(
            "pkey",
            PrimaryKeyValue::toStr("another key"));
        exist.mutableUserData() = &userDataForAnotherKey;
    }
    criterion.mutableTable() = "YourTable";
    criterion.mutableMaxVersions().reset(1);
}
BatchGetRowResponse resp;
Optional<OTSError> res = client.batchGetRow(resp, req);
说明 詳細代碼可在 batchGetRow@GitHub擷取。

批量寫(BatchWriteRow)

批量插入、修改或刪除一個或多個表中的若干行資料。

BatchWriteRow操作可視為多個PutRow、UpdateRow、DeleteRow操作的集合,各個操作獨立執行,獨立返回結果,獨立計算服務能力單元。

BatchWriteRow可能出現以下兩種錯誤:

  • 請求整體的錯誤,比如網路逾時。這類錯誤存放在batchWriteRow()傳回值中。
  • 單行上的錯誤,比如主索引值不合法。這類錯誤存放在BatchWriteRowResponse中的每一行上。

樣本

static const char kPutRow[] = "PutRow";
static const char kUpdateRow[] = "UpdateRow";
static const char kDeleteRow[] = "DeleteRow";

BatchWriteRowRequest req;
{
    // put row
    BatchWriteRowRequest::Put& put = req.mutablePuts().append();
    put.mutableUserData() = kPutRow;
    put.mutableGet().mutableTable() = kTableName;
    PrimaryKey& pkey = put.mutableGet().mutablePrimaryKey();
    pkey.append() = PrimaryKeyColumn(
        "pkey",
        PrimaryKeyValue::toStr("row to put"));
}
{
    // update row
    BatchWriteRowRequest::Update& update = req.mutableUpdates().append();
    update.mutableUserData() = kUpdateRow;
    update.mutableGet().mutableTable() = kTableName;
    PrimaryKey& pkey = update.mutableGet().mutablePrimaryKey();
    pkey.append() = PrimaryKeyColumn(
        "pkey",
        PrimaryKeyValue::toStr("row to update"));
    RowUpdateChange::Update& attr = update.mutableGet().mutableUpdates().append();
    attr.mutableType() = RowUpdateChange::Update::kPut;
    attr.mutableAttrName() = "attr0";
    attr.mutableAttrValue().reset(AttributeValue::toStr("some value"));
}
{
    // delete row
    BatchWriteRowRequest::Delete& del = req.mutableDeletes().append();
    del.mutableUserData() = kDeleteRow;
    del.mutableGet().mutableTable() = kTableName;
    PrimaryKey& pkey = del.mutableGet().mutablePrimaryKey();
    pkey.append() = PrimaryKeyColumn(
        "pkey",
        PrimaryKeyValue::toStr("row to delete"));
}
BatchWriteRowResponse resp;
Optional<OTSError> res = client.batchWriteRow(resp, req);
说明 詳細代碼可在 batchWriteRow@GitHub擷取。

範圍讀(GetRange)

讀取指定主鍵範圍內的資料。

建議使用RangeIterator。構造RangeIterator需要提供:

  • 非同步用戶端

  • RangeQueryCriterion與單行讀的PointQueryCriterion類似,但RangeQueryCriterion還需要:

    • 定義範圍的起始點(包含)和終止點(不包含)。除了正常主鍵索引值之外,還可以使用“負無窮大”(嚴格小於所有正常主鍵列值)和“正無窮大”(嚴格大於所有正常主鍵列值)兩個特殊值。

    • 設定正序讀取(由小及大)或者反序讀取(由大及小)。預設為正序讀取。正序讀取時,起始點須小於終止點;反序讀取時,起始點須大於終止點。

RangeIterator對象是個Iterator,提供三個介面:

  • moveNext()將RangeIterator對象移動到下一行。剛構造出來的RangeIterator對象必須調用moveNext()才可以取值。如果讀取資料失敗,moveNext()會將錯誤顯示在傳回值中。

  • valid()給出RangeIterator對象是否走到了範圍的終點。

  • 如果valid()為true,則可以通過get()讀取到行對象。您可以將get()返回的行對象的內容搬移走以避免記憶體複製。如果移到他處,緊接著的get()將返回搬移後的內容。

樣本

RangeQueryCriterion query;
query.mutableTable() = "YourTable";
query.mutableMaxVersions().reset(1);
{
    PrimaryKey& start = query.mutableInclusiveStart();
    start.append() = PrimaryKeyColumn(
        "pkey",
        PrimaryKeyValue::toInfMin());
}
{
    PrimaryKey& end = query.mutableExclusiveEnd();
    end.append() = PrimaryKeyColumn(
        "pkey",
        PrimaryKeyValue::toInfMax());
}
auto_ptr<AsyncClient> aclient(AsyncClient::create(client));
RangeIterator iter(*aclient, query);
for(;;) {
    Optional<OTSError> err = iter.moveNext();
    if (err.present()) {
        // do something with err
        abort();
    }
    if (!iter.valid()) {
        break;
    }
    Row& row = iter.get();
    // do something with row
}
说明 詳細代碼可在 GetRange@GitHub擷取。

指定列讀取

Table Store支援無限寬度的行,但一般無需讀取整行,只需指定若干列讀取即可。 QueryCriterion(PointQueryCriterion、MultiPointQueryCriterion和RangeQueryCriterion的基類)提供了mutableColumnsToGet()方法來指定需要讀取的列,既可以是屬性列,也可以是主鍵列,如果為空白則讀取整行。

如果指定的列在讀取的行上不存在,返回的結果裡便缺失這個列。Table Store不提供預留位置。

在範圍讀中,如果指定的列全部是屬性列,而範圍內某行恰好缺少全部指定的列,那麼在結果中並不會出現這一行。如果確實需要感知到該行,可以將主鍵列加入到指定列之中。

指定版本讀取

每個屬性列可以包含多個版本,每個版本號碼(時間戳記)對應一個列值。讀取的時候可以指定讀取多少個版本(mutableMaxVersions())以及讀取的版本範圍(mutableTimeRange())。

最大版本數和版本範圍,至少指定其中一項:

  • 如果僅指定版本數,則返回所有版本裡從新到舊至多指定數量個資料。
  • 如果僅指定版本範圍,則返回該範圍內所有資料。
  • 如果同時指定版本數和版本範圍,則返回版本範圍內從新到舊至多指定數量個資料。

條件寫

條件寫是指在寫一行之前先檢查條件,當條件成立才實際寫入。Table Store保證條件檢查和寫入的原子性。

Table Store支援行存在性條件和列值條件:

  • 行存在性條件分為以下幾種:

    • Ignore:忽略。預設值,無論行是否存在都寫入。
    • ExpectExist:期望存在。行存在則寫入。
    • ExpectNotExist:期望不存在。行不存在則寫入。
  • 列值條件等同於過濾器