使用項目和屬性 - Amazon DynamoDB

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

使用項目和屬性

在 Amazon DynamoDB 中,項目是屬性的集合。每個屬性都有名稱和數值。屬性值可以是純量、集合,或文件類型。如需詳細資訊,請參閱Amazon DynamoDB:運作方式

DynamoDB 針對基本建立、讀取、更新和刪除 (CRUD) 功能提供四項作業。所有這些操作都是不能中斷的。

  • PutItem:建立項目。

  • GetItem:閱讀項目。

  • UpdateItem:更新項目。

  • DeleteItem:刪除項目。

這些操作每一項都需要您指定希望處理之項目的主索引鍵。例如,若要使用 GetItem 讀取項目,您必須指定該項目的分割區索引鍵和排序索引鍵 (若適用的話)。

除了四個基本CRUD操作之外,DynamoDB 還提供下列功能:

  • BatchGetItem:最多可從一或多個資料表讀取 100 個項目。

  • BatchWriteItem:在一或多個資料表中最多可建立或刪除 25 個項目。

這些批次處理作業將多項CRUD作業合併為單一要求。此外,批次操作會平行讀取和寫入項目,將回應延遲減至最低。

本節說明如何使用這些操作,並包含相關主題,例如條件式更新和原子計數器。本節還包括使用 AWS SDKs.

讀取項目

若要從 DynamoDB 資料表讀取項目,請使用 GetItem 操作。您必須提供資料表的名稱,以及您希望取得之項目的主索引鍵。

範例

下列 AWS CLI 範例說明如何從ProductCatalog表格中讀取項目。

aws dynamodb get-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"1"}}'
注意

使用 GetItem,您必須指定整個主索引鍵,而非其中一部分。例如,若資料表有複合主索引鍵 (分割區索引鍵和排序索引鍵),您必須提供分割區索引鍵的數值和排序索引鍵的數值。

根據預設,GetItem 請求會執行最終一致讀取。您可以使用 ConsistentRead 參數改為請求強烈一致讀取 (這會消耗額外的讀取容量單位,但會傳回最多 up-to-date 版本的項目。)

GetItem 會傳回項目所有的屬性。您可以使用投影表達式只傳回一部分的屬性。如需詳細資訊,請參閱 投射表達式

若要傳回 GetItem 使用的讀取容量單位總數,請將 ReturnConsumedCapacity 參數設為 TOTAL

範例

下面的 AWS Command Line Interface (AWS CLI)示例顯示了一些可選GetItem參數。

aws dynamodb get-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"1"}}' \ --consistent-read \ --projection-expression "Description, Price, RelatedItems" \ --return-consumed-capacity TOTAL

寫入項目

若要在 DynamoDB 資料表中建立、更新或刪除項目,請使用下列其中一項操作:

  • PutItem

  • UpdateItem

  • DeleteItem

針對每一項操作,您都必須指定整個主索引鍵,非僅指定一部分。例如,若資料表有複合主索引鍵 (分割區索引鍵和排序索引鍵),您必須提供分割區索引鍵的值和排序索引鍵的值。

若要傳回這些操作使用的寫入容量單位,請將 ReturnConsumedCapacity 參數設為下列其中一項:

  • TOTAL:傳回所耗用的寫入容量單位總數。

  • INDEXES:傳回所耗用的寫入容量單位總數,以及資料表的小計和受操作影響的任何次要索引。

  • NONE:不傳回寫入容量的詳細資訊。(此為預設值)。

PutItem

PutItem 會建立新的項目。若資料表中已存在具有相同索引鍵的項目,該項目會取代為新的項目。

範例

將新的項目寫入 Thread 表。Thread 的主索引鍵包含 ForumName (分割區索引鍵) 和 Subject (排序索引鍵)。

aws dynamodb put-item \ --table-name Thread \ --item file://item.json

--item 的引數會存放在 item.json 檔案中。

{ "ForumName": {"S": "Amazon DynamoDB"}, "Subject": {"S": "New discussion thread"}, "Message": {"S": "First post in this thread"}, "LastPostedBy": {"S": "fred@example.com"}, "LastPostDateTime": {"S": "201603190422"} }

UpdateItem

若不存在具有指定之索引鍵的項目,UpdateItem 會建立新的項目。否則,它會修改現有項目的屬性。

您可以使用更新表達式指定您希望修改的屬性及其新值。如需詳細資訊,請參閱 更新表達式

在更新表達式中,您會使用表達式屬性值做為實際數值的預留位置。如需詳細資訊,請參閱 表達式屬性值

範例

修改 Thread 項目中的各種屬性。選用的 ReturnValues 參數會在項目更新之後顯示更新後的項目。如需詳細資訊,請參閱 傳回值

aws dynamodb update-item \ --table-name Thread \ --key file://key.json \ --update-expression "SET Answered = :zero, Replies = :zero, LastPostedBy = :lastpostedby" \ --expression-attribute-values file://expression-attribute-values.json \ --return-values ALL_NEW

--key 的引數會存放在 key.json 檔案中。

{ "ForumName": {"S": "Amazon DynamoDB"}, "Subject": {"S": "New discussion thread"} }

--expression-attribute-values 的引數會存放在 expression-attribute-values.json 檔案中。

{ ":zero": {"N":"0"}, ":lastpostedby": {"S":"barney@example.com"} }

DeleteItem

DeleteItem 會刪除具有指定之索引鍵的項目。

範例

下列 AWS CLI 範例顯示如何刪除Thread項目。

aws dynamodb delete-item \ --table-name Thread \ --key file://key.json

傳回值

在某些案例中,您可能會希望 DynamoDB 傳回修改前或修改後的特定屬性值。PutItemUpdateItemDeleteItem 操作具有 ReturnValues 參數,您可以使用此參數傳回修改前或修改後的屬性值。

ReturnValues 的預設值為 NONE,表示 DynamoDB 不會傳回任何已修改的屬性資訊。

以下是由 DynamoDB API 作ReturnValues業組織的其他有效設定。

PutItem

  • ReturnValues: ALL_OLD

    • 若您覆寫現有項目,ALL_OLD 會傳回覆寫前的整個項目。

    • 若您寫入原先不存在的項目,ALL_OLD 將不具任何效果。

UpdateItem

UpdateItem 最常見的用法便是更新現有的項目。但是,UpdateItem 實際上執行的是 upsert,表示若項目尚未存在,它會自動建立項目。

  • ReturnValues: ALL_OLD

    • 若您更新現有項目,ALL_OLD 會傳回更新前的整個項目。

    • 若您更新原先不存在的項目 (upsert),ALL_OLD 將不具任何效果。

  • ReturnValues: ALL_NEW

    • 若您更新現有項目,ALL_NEW 會傳回更新後的整個項目。

    • 若您更新原先不存在的項目 (upsert),ALL_NEW 會傳回整個項目。

  • ReturnValues: UPDATED_OLD

    • 若您更新現有項目,UPDATED_OLD 只會傳回更新後的屬性在更新前的樣子。

    • 若您更新原先不存在的項目 (upsert),UPDATED_OLD 將不具任何效果。

  • ReturnValues: UPDATED_NEW

    • 若您更新現有項目,UPDATED_NEW 只會傳回受影響的屬性在更新後的樣子。

    • 若您更新原先不存在的項目 (upsert),UPDATED_NEW 只會傳回更新後的屬性在更新後的樣子。

DeleteItem

  • ReturnValues: ALL_OLD

    • 若您刪除現有項目,ALL_OLD 會傳回您刪除該項目前的整個項目。

    • 若您刪除原先不存在的項目,ALL_OLD 不會傳回任何資料。

批次操作

針對需要讀取或寫入多個項目的應用程式,DynamoDB 提供 BatchGetItemBatchWriteItem 操作。使用這些操作可減少您應用程式與 DynamoDB 之間網路來回行程的次數。此外,DynamoDB 會平行執行個別讀取或寫入操作。您的應用程式可從此平行處理原則中獲益,而無須管理並行或執行緒。

批次操作本質上是多個讀取或寫入請求的包裝函式。例如,若 BatchGetItem 請求包含五個項目,DynamoDB 就會代您執行五個 GetItem 操作。同樣的,若 BatchWriteItem 請求包含兩個 PUT 請求和四個刪除請求,則 DynamoDB 就會執行兩個 PutItem 請求和四個 DeleteItem 請求。

一般而言,除非批次中所有的請求皆失敗,否則批次操作不會失敗。例如,假設您執行 BatchGetItem 操作,但批次中一個個別的 GetItem 請求失敗。在此案例中,BatchGetItem 會傳回失敗 GetItem 請求的索引鍵和資料。其他批次中的 GetItem 請求則不會受到影響。

BatchGetItem

單一 BatchGetItem 操作可包含最多 100 個個別 GetItem 請求,並可擷取最多 16 MB 的資料。此外,BatchGetItem 操作可從多個資料表擷取項目。

範例

Thread 表擷取兩個項目,使用投影表達式卻只傳回一部分的屬性。

aws dynamodb batch-get-item \ --request-items file://request-items.json

--request-items 的引數會存放在 request-items.json 檔案中。

{ "Thread": { "Keys": [ { "ForumName":{"S": "Amazon DynamoDB"}, "Subject":{"S": "DynamoDB Thread 1"} }, { "ForumName":{"S": "Amazon S3"}, "Subject":{"S": "S3 Thread 1"} } ], "ProjectionExpression":"ForumName, Subject, LastPostedDateTime, Replies" } }

BatchWriteItem

BatchWriteItem 操作可包含最多 25 個個別 PutItemDeleteItem 請求,並可寫入最多 16 MB 的資料。(個別項目的大小上限為 400 KB。) 此外,BatchWriteItem 操作可在多個資料表中寫入或刪除項目。

注意

BatchWriteItem 不支援 UpdateItem 請求。

範例

將兩個項目寫入 ProductCatalog 表。

aws dynamodb batch-write-item \ --request-items file://request-items.json

--request-items 的引數會存放在 request-items.json 檔案中。

{ "ProductCatalog": [ { "PutRequest": { "Item": { "Id": { "N": "601" }, "Description": { "S": "Snowboard" }, "QuantityOnHand": { "N": "5" }, "Price": { "N": "100" } } } }, { "PutRequest": { "Item": { "Id": { "N": "602" }, "Description": { "S": "Snow shovel" } } } } ] }

原子計數器

您可以使用 UpdateItem 操作實作原子計數器:原子計數器為在不影響其他寫入請求的情況下,無條件遞增的數字屬性。(所有寫入請求都會按照接收的順序套用)。使用原子計數器,更新便不是等冪的。換言之,每次呼叫 UpdateItem 時,數值就會增加或減少。如果用於更新原子計數器的增量值是正的,那麼它可能會導致多計。如果增量值為負數,則可能會導致少計。

您可以使用原子計數器追蹤網站的訪客數。在此案例中,您的應用程式會增加數值,無論目前的數值為何。若 UpdateItem 操作失敗,應用程式可能只會重試操作。這可能會導致計數器更新兩次,但您或許可以容忍計數器些微多計或少計網站的訪客數。

原子計數器不適用於無法容忍多計或少計的情況 (例如銀行的應用程式)。在此案例中,使用條件式的更新而非原子計數器會更安全。

如需詳細資訊,請參閱增加和減少數值屬性

範例

下列 AWS CLI 範例會將Price產品遞增 5。在此範例中,已知項目在計數器更新之前存在。因為 UpdateItem 並非等冪,Price 會在每次執行此程式碼時增加。

aws dynamodb update-item \ --table-name ProductCatalog \ --key '{"Id": { "N": "601" }}' \ --update-expression "SET Price = Price + :incr" \ --expression-attribute-values '{":incr":{"N":"5"}}' \ --return-values UPDATED_NEW

條件式寫入

根據預設,DynamoDB 的寫入操作 (PutItemUpdateItemDeleteItem) 為非條件式操作:每項操作都會覆寫具有指定主索引鍵的現有項目。

DynamoDB 可選擇性的支援這些操作的條件式寫入。條件式寫入只有在項目屬性滿足一或多個預期條件時才會成功。否則會傳回錯誤。

條件式寫入會根據項目的最新更新版本檢查其條件。請注意,如果該項目以前不存在,或者對該項目的最新成功操作是刪除,則條件寫入將找不到以前的項目。

條件式寫入在許多情況下都很有幫助。例如,您可能會希望 PutItem 操作僅在沒有具有相同主索引鍵的項目時才成功。或者,您可以防止 UpdateItem 操作修改其中一個屬性為特定數值的項目。

條件式寫入在多個使用者嘗試修改相同項目的案例中會很有幫助。考慮下圖,其中兩名使用者 (Alice 和 Bob) 正在處理 DynamoDB 表中同一個項目。

使用者 Alice 和 Bob 嘗試修改 Id 1 的項目,展示需要條件式寫入。

假設愛麗絲使 AWS CLI 用將Price屬性更新為 8。

aws dynamodb update-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"1"}}' \ --update-expression "SET Price = :newval" \ --expression-attribute-values file://expression-attribute-values.json

--expression-attribute-values 的引數會存放在 expression-attribute-values.json 檔案中:

{ ":newval":{"N":"8"} }

現在假設 Bob 稍後發行一個相似的 UpdateItem 請求,但將 Price 變更為 12。對 Bob 而言,--expression-attribute-values 參數看起來如下。

{ ":newval":{"N":"12"} }

Bob 的請求會成功,但 Alice 先前做出的更新便會遺失。

若要請求條件式 PutItemDeleteItemUpdateItem,您可以指定條件表達式。條件表達式為包含屬性名稱、條件運算子和內建函數的字串。整個表達式都必須評估為 true。否則,操作會失敗。

現在考慮下圖,示範條件式寫入如何阻擋覆寫 Alice 的更新。

條件式寫入可防止使用者 Bob 的更新覆寫使用者 Alice 對相同項目的變更。

Alice 首先會嘗試將 Price 更新為 8,但只有在目前的 Price 為 10 時才可以。

aws dynamodb update-item \ --table-name ProductCatalog \ --key '{"Id":{"N":"1"}}' \ --update-expression "SET Price = :newval" \ --condition-expression "Price = :currval" \ --expression-attribute-values file://expression-attribute-values.json

--expression-attribute-values 的引數會存放在 expression-attribute-values.json 檔案中。

{ ":newval":{"N":"8"}, ":currval":{"N":"10"} }

Alice 的更新會成功,因為條件評估的結果為 true。

接下來,Bob 會嘗試將 Price 更新為 12,但目前的 Price 必須為 10 才能成功。對 Bob 而言,--expression-attribute-values 參數看起來如下。

{ ":newval":{"N":"12"}, ":currval":{"N":"10"} }

因為 Alice 先前已將 Price 更新為 8,條件表達式評估的結果為 false,因此 Bob 的更新會失敗。

如需詳細資訊,請參閱 條件表達式

條件式寫入等冪性

如果針對正受到更新的相同屬性進行條件式檢查,則條件式寫入可能為等冪。此表示僅在項目中的某個屬性值符合您在要求時所預期的值,DynamoDB 才會執行特定的寫入要求。

例如,假設您發出 UpdateItem 請求將項目的 Price 增加 3,但只有在目前的 Price 為 20 時才可以。在傳送請求後、取得結果前,發生網路錯誤,因此您不知道請求是否成功。因為此條件式寫入是等冪的,所以您可以重試相同的 UpdateItem 請求,且 DynamoDB 只有在目前的 Price 為 20 時才會更新項目。

條件式寫入使用的容量單位

若在條件式寫入期間,ConditionExpression 評估的結果為 false,DynamoDB 仍然會使用資料表的寫入容量:使用的量取決於現有項目的大小 (或最少為 1)。例如,如果現有項目為 300kb,而您嘗試建立或更新的新項目為 310kb,那麼條件失敗時,使用的寫入容量單位將是 300,條件成功時則會是 310。如果這是新項目 (沒有現有項目),那麼條件失敗時,使用的寫入容量單位將是 1,條件成功時則會是 310。

注意

寫入操作只會使用寫入容量單位。它們永遠不會使用讀取容量單位。

失敗的條件式寫入會傳回 ConditionalCheckFailedException。發生這種情況時,您不會在回應中收到有關已使用之寫入容量的任何資訊。

若要傳回條件式寫入期間使用的寫入容量單位數,請使用 ReturnConsumedCapacity 參數:

  • TOTAL:傳回所耗用的寫入容量單位總數。

  • INDEXES:傳回所耗用的寫入容量單位總數,以及資料表的小計和受操作影響的任何次要索引。

  • NONE:不傳回寫入容量的詳細資訊。(此為預設值)。

注意

與全域次要索引不同,本機次要索引會與其資料表共用佈建的輸送容量。本機次要索引上的讀取和寫入活動會使用其資料表佈建的輸送容量。