入門閱讀時間 3 分鐘

DynamoDB 基於項的操作

DynamoDB 的 API 分為三大類:基於項的操作,按主索引鍵作用於單個項;Query,讀取一個分割區 內的一段範圍;以及 Scan,讀取所有內容。本指南講第一類——你用得最多的四個操作: GetItemPutItemUpdateItemDeleteItem。它們是 DynamoDB 提供的最便宜、最快的呼叫, 而把它們的區分搞對(尤其是 PutUpdate)能避免一整類意外丟資料的 bug。

什麼是 DynamoDB 基於項的操作?

DynamoDB 基於項的操作,是按完整主索引鍵作用於單個項的那四個呼叫:GetItem 讀取它,PutItem 建立或完全替換它,UpdateItem 原地修改指定屬性,DeleteItem 刪除它。每個操作都恰好針對一個項,因而是最快、最便宜的呼叫——不同於一次讀取多項的 Query 和 Scan。

  • GetItem —— 按完整主索引鍵讀取一個項。
  • PutItem —— 建立或完全替換一個項。
  • UpdateItem —— 建立或原地修改某個項的指定屬性
  • DeleteItem —— 按完整主索引鍵刪除一個項。
  • 這四個都需要完整主索引鍵(分割區索引鍵,若表有排序索引鍵還需排序索引鍵)—— 它們精確定位到恰好一個項。
  • PutItem 覆蓋整個項;UpdateItem 是外科手術式的 —— 把它們搞混,屬性就會悄悄消失。

決定性特徵:一個項,完整鍵

每個基於項的操作都按完整主索引鍵定位單個項。這正是它們快且便宜的原因 —— DynamoDB 對分割區索引鍵 做雜湊,直奔那個項,完事。沒有過濾,沒有掃描。如果你不知道完整鍵,這些就不是合適的工具;那是 Query 和 Scan 的用武之地。

假設你管理以 USER#<id> 為鍵的使用者帳戶:

PK: USER#204   email, displayName, plan, createdAt
  • USER#204 執行 GetItem → 直接得到那個使用者。
  • USER#204 執行 DeleteItem → 刪除那個使用者。

兩者都需要確切的鍵。沒有鍵,就沒有基於項的操作。

PutItemUpdateItem —— 會咬人的那個

這個區分值得牢牢記住:

  • PutItem 寫入整個項。 如果 USER#204 已存在,而你用僅含 {email, displayName}PutItem,那麼現有的 plancreatedAt 屬性就沒了 —— put 替換整個項,它不合並。
  • UpdateItem 只改你指定的內容。SET email = …UpdateItem 會保持其他所有屬性 不變,並在項不存在時建立它(一次 upsert)。
替換整個項改一部分屬性,保留其餘修改一個已存在的項?PutItemUpdateItem

經驗法則:要修改一個已存在的項就用 UpdateItem,僅當你確實是指「把這個項寫成全新的完整 狀態」時才用 PutItemPutItemUpdateItem 都接受一個 條件運算式,讓你可以讓寫入有條件地進行(「僅當它尚 不存在時」)。

DynoTable 中的基於項的操作

想看這些操作背後的原始 API 呼叫嗎?在 DynamoDB 運算式構建器中組裝運算式和型別化的值對映, 用 DynamoDB JSON 轉換器把純 JSON 項轉換成 API 的型別化格式。

在 DynoTable 中,同樣的工作變成了視覺化:在網格中開啟一個項來讀取它(一次 GetItem), 編輯屬性並提交(一次 UpdateItem),新增或替換一行(一次 PutItem),或者刪除一行—— 每次操作一個項。

在 DynoTable 的 Quick View 中讀取單個項,附帶 Edit Item 和 Copy as JSON 操作。
在 DynoTable 的 Quick View 中讀取單個項,附帶 Edit Item 和 Copy as JSON 操作。

陷阱與後續步驟

  • PutItem 替換整個項 —— 要在不丟失其餘屬性的前提下只改幾個欄位,用 UpdateItem
  • 你必須知道完整主索引鍵 —— 沒有鍵就意味著用 Query/Scan,而非基於項的操作。
  • 一次要處理很多項? 別逐個迴圈呼叫這些操作 —— 批次操作能把它們摺疊進更少的往返。
  • 需要拿回舊值/新值? 設定 ReturnValues,而不是再補一次 GetItem
  • 相關: Query 與 Scan 講了讀取多項的那一面。

想讀、寫、刪項而一行 API 程式碼都不寫嗎?下載 DynoTable,直接操作你的表。

成本:一件物品,一跳

基於項目的讀取是 DynamoDB 中最便宜的可定址訪問。 GetItem 開啟 2 KB 行消耗 1 最終一致的 RCU(一個 4 KB 塊,四捨五入)上)。 Query 返回同一行,因為您知道分割區索引鍵並且排序索引鍵花費相同的容量 - 但如果您只知道分割區索引鍵並且在應用程式程式碼中進行過濾,您需要為分割區中的每個項目付費。

營運需要鑰匙典型用途容量形狀
GetItem完整主索引鍵按 id 讀取的點每件物品 1 塊
PutItem完整主索引鍵建立或替換整個項目每 KB 1 WCU,四捨五入
UpdateItem完整主索引鍵補丁屬性書面物品尺寸賬單
DeleteItem完整主索引鍵刪除行與寫入商品尺寸相同
Query + 過濾分割區(+可選排序條件)一個分割區中有許多項目匹配項總和

將代表性項目貼上到 item-size calculator,然後乘以每秒請求數 pricing calculator 當熱路徑使用時迴圈中的 GetItem 與鍵控良好的 Query

寫入的條件運算式

PutItemUpdateItem 都接受可選 condition expressions。典型模式:

  • attribute_not_exists(pk) on put — 僅建立插入,無需競爭。
  • attribute_exists(pk) 更新時 — 拒絕意外建立存根。
  • plan = :old 更新時 — 樂觀並行;如果有其他作家則重試先改變計劃。

DeleteItem也支援條件——僅當status = :closed時才刪除,for 示例。條件不另加單獨讀取費用; DynamoDB 評估它們在寫入嘗試期間針對儲存的項目。在視覺上構建條件 DynamoDB expression builder;複製 ConditionExpressionExpressionAttributeNamesExpressionAttributeValues 進入您的 SDK 呼叫。

冪等性和覆蓋安全性

沒有條件的 PutItem 是整個項目的最後寫入者獲勝。對於網路鉤子處理程式或 SQS 消費者,在已處理的資料上將 put 與 attribute_not_exists 配對標記屬性,或使用 UpdateItemSET processed = :true 保護 attribute_not_exists(processed)。當您需要稽核日誌的先前屬性值時,請新增 ⟦5⟧ 放在同一個 UpdateItem 上之前的 GetItem — 一個往返,沒有讀/寫競爭。

選擇正確的項目操作

意向致電守衛
按使用者 ID 讀取個人資料GetItem
如果不存在則建立使用者PutItemattribute_not_exists(pk)
更改電子郵件,保留其他欄位UpdateItem可選 email <> :old
替換整個配置 blobPutItem僅當有效負載完成時
刪除已關閉的票證DeleteItemstatus = :closed
透過已知金鑰讀取 50 張票BatchGetItem不是 50× GetItem 連續

暫存寫入DynoTable

DynoTable 在提交之前在本地暫存 UpdateItemPutItem。你評論屬性差異,執行可選的 PartiQL 檢查,然後提交 - 對映到上面真正的API呼叫。批次行刪除批次進入 ⟦2⟧ 在引擎蓋下重試在未加工的物品上。對於 SDK 程式碼生成,請在 expression builder 並貼上發出的處理程式測試旁邊的 SDK v3 片段。

已更新