入門閱讀時間 2 分鐘

如何在 DynamoDB 中刪除多個項目

DynamoDB 裡沒有 DELETE FROM table WHERE …。每一次刪除都以一個 項目的完整主索引鍵為目標——這個 API 沒有批量刪除操作、沒有 truncate,而 DELETE 陳述式每條也只移除恰好一個 項目。所以「刪除多個項目」永遠是一個兩步驟的工作:找出那些 索引鍵,然後對每個索引鍵發出一次刪除,並為了輸送量而分批。

本指南涵蓋各種分批選項、全有或全無的交易式變體、刪光整張資料表的 情況,以及如何在 GUI 中用一次選取加兩個按鍵做到同樣的事。

我要如何在 DynamoDB 中刪除多個項目?

先蒐集你想刪掉的項目的主索引鍵(透過 QueryScan), 然後分批刪除:BatchWriteItem 每次呼叫最多接受 25 個 DeleteRequestTransactWriteItems 可原子式地刪除最多 100 個項目,而 PartiQL 的 DELETE 陳述式可以用 BatchExecuteStatement 一次批 25 條。 在 DynoTable 中,你選取那些列、按 ⌘⌫ 把刪除 暫存起來,然後檢視並提交。

步驟 0:蒐集索引鍵

刪除需要完整的主索引鍵——在 資料表上那就是 分割區索引鍵 排序索引鍵 (AWS: 「對每個主索引鍵,你必須提供 所有 的索引鍵屬性」)。你 無法用一個任意的屬性來刪除,所以「刪除每個 status = 'archived' 的項目」得從一次讀取開始:

  • 如果條件落在一個索引鍵(或一個 GSI 索引鍵)上,一次 有針對性的 Query 就能便宜地蒐集到那些索引鍵。
  • 否則就是一次帶過濾的 Scan——不管有沒有過濾,它都會讀取(並計費)整張 資料表;見 query vs scan

用一個只回傳索引鍵屬性的 ProjectionExpression,並沿著 LastEvaluatedKey 走到底(分頁),否則你會 悄悄地只刪掉第一個 1 MB 分頁裡的那些。

方法 1:BatchWriteItem(每次呼叫最多 25 個刪除)

BatchWriteItem 每次呼叫最多捆 25 個 put/delete 請求或 16 MBAWS API 參考: 「單一次 BatchWriteItem 呼叫最多可透過網路傳輸 16MB 的資料, 其中包含最多 25 個項目的 put 或 delete 操作」)。

aws dynamodb batch-write-item --request-items '{
  "Orders": [
    {"DeleteRequest": {"Key": {"PK": {"S": "ORDER#1001"}, "SK": {"S": "META"}}}},
    {"DeleteRequest": {"Key": {"PK": {"S": "ORDER#1002"}, "SK": {"S": "META"}}}},
    {"DeleteRequest": {"Key": {"PK": {"S": "ORDER#1003"}, "SK": {"S": "META"}}}}
  ]
}'

批次有三個常常絆倒人的特性——全都直接出自 API 參考

  • 它不是原子的。BatchWriteItem 中指定的各個 PutItemDeleteItem 操作是原子的;但 BatchWriteItem 整體 不是。」有些刪除可能落地,其他的沒有。
  • 你必須重試 UnprocessedItems 被節流的請求會以與請求相同的形狀 回到回應的 UnprocessedItems 對應表中—— 「通常,你會在迴圈中呼叫 BatchWriteItem」,而且 AWS「強烈 建議你在重試之間使用指數退避演算法」。
  • 沒有條件。「你無法在各別的 put 與 delete 請求上指定 條件」——條件式刪除得改走 DeleteItem 或 交易。批次也會拒絕在同一次呼叫中對同一個索引鍵下兩個 操作。

那個迴圈的形狀——按 25 個切塊、送出、把剩下的帶著退避重新排隊—— 就是批次操作中講的同一套。

方法 2:TransactWriteItems(原子式刪除)

當一組刪除必須一起成功或一起失敗時——比如移除一個父項目 和它的 子項目——就用 TransactWriteItems:最多 100 個動作(刪除、放入、更新、條件檢查)原子式地套用, 並允許逐項目的 。代價是:一次交易式 寫入花費一般寫入兩倍的寫入容量。完整的機制 (冪等 token、TransactionCanceledException、成本數學)在 DynamoDB 交易

方法 3:PartiQL DELETE,分批執行

PartiQL 並沒有解除逐鍵規則——它只是換個拼法。開發人員指南 說得很明白 (PartiQL DELETE): 「你一次只能刪除一個項目。你無法發出單一條刪除多個項目的 DynamoDB PartiQL 陳述式」,而且 WHERE 條件 「必須解析為單一個主索引鍵值」。

要刪除數個項目,你把單項目陳述式分批—— BatchExecuteStatement 每批最多執行 25 條陳述式(全部是讀取或全部是寫入,絕不混用):

[
  {"Statement": "DELETE FROM \"Orders\" WHERE PK = 'ORDER#1001' AND SK = 'META'"},
  {"Statement": "DELETE FROM \"Orders\" WHERE PK = 'ORDER#1002' AND SK = 'META'"}
]
aws dynamodb batch-execute-statement --statements file://statements.json

一個沒有釘死完整索引鍵的 WHERE 會失敗——不存在 DELETE FROM Orders WHERE status = 'archived'。更多 PartiQL 模式(以及 背後的限制)在 PartiQL 範例PartiQL vs SQL

刪除所有項目(truncate)

DynamoDB 沒有 truncate。你的選項,按優先順序:

  1. 刪除並重建資料表。 逐項目刪光整張資料表要為每個項目 計費一次寫入;DeleteTable + CreateTable 完全繞過那整筆 寫入帳單。要注意的是:資料表設定——索引、TTL、、 容量模式、標籤——不會自己回來;你要在建立時重新宣告它們 (用基礎設施即程式碼的話這根本不算事)。
  2. 讓項目過期。 如果你真正想要的是「刪除所有早於 X 的東西」,TTL 會在背景刪除過期項目, 不消耗寫入容量——一場慢動作的批量刪除, 而且不花一毛錢。
  3. Scan + 批次刪除方法 1), 當資料表必須保持上線、而且只有一部分要刪時——你為每個被掃描的 項目付一次讀取,再為每個被刪除的項目付一次寫入。

在 DynoTable 中刪除多個項目

上面那套先選再刪的流程——查詢、蒐集索引鍵、切塊、重試—— 正是 GUI 應該包辦的苦工。在 DynoTable 中,它就是一次表格 選取:

  1. 執行或過濾一次查詢,讓你想刪掉的 那些列出現在畫面上。
  2. 選取它們並按 ⌘⌫——每個被選取的列都變成一個暫存 刪除。此時還沒有任何東西碰到 DynamoDB:那些列在表格中染成紅色, 並以可檢視的卡片出現在暫存面板中。
  3. 檢視,然後提交。提交會以帶有樂觀鎖定條件的 TransactWriteItems 批次送出——一個暫存刪除只有在項目仍然 存在時才會執行——而大型暫存批次會自動切塊,以維持在 DynamoDB 的交易限制之內。⌘⇧⌫ 會跳過檢視, 把選取的刪除與提交合成一組按鍵一次做完。
DynoTable 中的暫存刪除:被選取的列在表格中染成紅色,每一列都是提交前暫存面板中一張可檢視的卡片。
DynoTable 中的暫存刪除:被選取的列在表格中染成紅色,每一列都是提交前暫存面板中一張可檢視的卡片。

這個範圍是誠實的:你刪除的是你選取的那些列——一次經過檢視、 提交前可反悔的操作——而不是一場盲目的全表 truncate。要 清空整張資料表,就刪掉並重建它(見上)。

如果某次刪除需要一個手寫的條件(attribute_exists、版本 檢查),就在 DynamoDB Expression Builder 中組出確切的 ConditionExpression + 佔位符對應,然後把它掛到一次 DeleteItem 或一筆交易上。

常見問答

我可以在一次 DynamoDB 呼叫中刪除多個項目嗎? 可以——用 BatchWriteItem 最多 25 個(盡力而為,要重試 UnprocessedItems), 或用 TransactWriteItems 原子式地最多 100 個。兩者都要求每個項目給出完整的 主索引鍵;兩者都不接受用「where」條件來挑選項目。

DynamoDB 有 DELETE WHERE 嗎? 沒有。低階 API 和 PartiQL 都無法按條件刪除——PartiQL 的 DELETE 要求一個「解析為單一個主索引鍵值」的 WHERE。 你先查詢或掃描出那些索引鍵,然後逐一刪除。

我要如何刪除 DynamoDB 資料表中的所有項目? 要整個清空,就刪除並重建資料表——這樣可以避免為每個項目付 一次寫入。對於按時間的清理,用 TTL,它刪除 過期項目而不消耗寫入容量。當資料表必須保持上線時, Scan + 批次刪除是備案。

為什麼我批次刪除之後項目又出現了? 幾乎總是沒重試的 UnprocessedItems:一次被節流的 BatchWriteItem 會把失敗的刪除悄悄放回回應裡,而沒有對它們做迴圈的程式碼 「跑完了」但項目還在資料表裡。用指數退避重試,直到那個對應表 回來是空的為止。

刪除項目要花多少錢? 每次刪除都是一次標準寫入(每 1 KB 一個 WCU,在 交易裡加倍),而找出那些索引鍵也要花讀取。用 定價計算器估算損害。

想先看清楚你要刪的是什麼嗎?下載 DynoTable—— 選取那些列、用 ⌘⌫ 暫存刪除、檢視差異, 確定了再提交。

已更新