初級読了 3 分

DynamoDBのアイテムベース操作

DynamoDBのAPIは3つのファミリーに分かれます:プライマリキーで単一のアイテムを操作する アイテムベースの操作、1つのパーティション内の範囲を読み取るQuery、そして すべてを読み取るScanです。本ガイドは最初のファミリー — 最もよく使う4つの操作、 GetItemPutItemUpdateItemDeleteItemを扱います。これらはDynamoDBが提供する 中で最も安価で高速な呼び出しであり、その区別(特にPutUpdate)を正しく理解すれば、 不慮のデータ損失バグの一群を防げます。

DynamoDBのアイテムベース操作とは?

DynamoDBのアイテムベース操作とは、完全なプライマリキーで単一のアイテムを対象とする4つの呼び出しです:GetItemはアイテムを読み取り、PutItemはアイテムを作成または完全に置き換え、UpdateItemは特定の属性をその場で変更し、DeleteItemはアイテムを削除します。それぞれがちょうど1つのアイテムだけを対象とするため、多数のアイテムを読み取るQueryScanとは違い、最も高速で最も安価な呼び出しになります。

  • GetItem — 完全なプライマリキーで1つのアイテムを読み取る。
  • PutItem — 1つのアイテムを作成または完全に置き換える
  • UpdateItem — 1つのアイテムを作成、またはその特定の属性をその場で変更する
  • DeleteItem — 完全なプライマリキーで1つのアイテムを削除する。
  • 4つすべてが完全なプライマリキーを必要とする(パーティションキー、テーブルにソート キーがあればそれも) — ちょうど1つのアイテムを指定する。
  • PutItemはアイテム全体を上書きし、UpdateItemは外科的に変更する — これらを混同 すると、属性が静かに消える。

決定的な特徴:1つのアイテム、完全なキー

すべてのアイテムベース操作は、完全なプライマリキーで単一のアイテムを対象とします。 これこそが速くて安い理由です — 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)。
アイテム全体を置き換える一部の属性だけ変更し、残りは保既存のアイテムを 1 件変更する?PutItemUpdateItem

経験則:既存のアイテムを変更するならUpdateItemを使いPutItemは本当に 「このアイテムを完全な新しい状態として書き込む」という意味のときだけ使いましょう。 PutItemUpdateItemはどちらも 条件式を受け付けるので、書き込みを条件付きに できます(「まだ存在しない場合のみ」)。

DynoTableでのアイテムベース操作

これらの操作の背後にある生のAPI呼び出しを確認したいですか? DynamoDB式ビルダーで式と型付き値マップを組み立て、 DynamoDB JSONコンバーターでプレーンJSONのアイテムをAPIの型付き形式に変換してください。

DynoTableでは、同じ作業が視覚的になります:グリッドでアイテムを開いて読み取り (GetItem)、属性を編集してコミットし(UpdateItem)、行を追加または置き換え (PutItem)、または削除します — 1回に1つのアイテムを。

DynoTable の Quick View で単一のアイテムを読み取り、Edit Item と Copy as JSON アクションが表示されているところ。
DynoTable の Quick View で単一のアイテムを読み取り、Edit Item と Copy as JSON アクションが表示されているところ。

落とし穴と次のステップ

  • PutItemはアイテム全体を置き換える — 残りを失わずにいくつかのフィールドを変更する には、UpdateItemを使いましょう。
  • 完全なプライマリキーを知っている必要がある — キーがないならアイテム操作ではなく Query/Scanです。
  • 多数のアイテムを一度に? 1つずつループしてはいけません — バッチ操作はそれらをより少ない往復にまとめます。
  • 古い値/新しい値が必要? 後続のGetItemの代わりに ReturnValuesを設定しましょう。
  • 関連: QueryとScanが多数読み取り側を扱っています。

1行もAPIコードを書かずにアイテムを読み書き・削除したいですか? DynoTableをダウンロードして、テーブルを直接操作してください。

コスト:1つのアイテム、1ホップ

アイテムベースの読み取りは、DynamoDBで最も安価にアドレス指定できるアクセスです。2 KBの 行に対するGetItemは、結果整合性のRCUを1消費します(4 KBブロック1つ、切り上げ)。 パーティションキーとソートキーを知っていて同じ行を返すQueryも同じキャパシティです — ただしパーティションキーしか知らずアプリケーションコードでフィルタするなら、その パーティション内のすべてのアイテム分を払うことになります。

操作必要なキー典型的な用途キャパシティの形
GetItem完全なプライマリキーIDによるポイント読み取りアイテムあたり1ブロック
PutItem完全なプライマリキーアイテム全体の作成または置き換え1 KBあたり1 WCU、切り上げ
UpdateItem完全なプライマリキー属性のパッチ書き込むアイテムサイズで課金
DeleteItem完全なプライマリキー行の削除アイテムサイズの書き込みと同じ
Query + filterパーティション(+任意のソート条件)1パーティション内の多数のアイテム一致したアイテムの合計

代表的なアイテムをアイテムサイズ計算機に貼り付け、 ホットな経路がGetItemをループで回すのか、キーの効いた1回のQueryで済むのかを比べる ときは、料金計算ツールで秒あたりのリクエスト数を 掛けてみましょう。

書き込みの条件式

PutItemUpdateItemはどちらも任意の 条件式を受け付けます。典型的なパターン:

  • attribute_not_exists(pk) をputに — 競合なしの作成専用インサート。
  • attribute_exists(pk) をupdateに — うっかりスタブを作るのを拒否する。
  • plan = :old をupdateに — 楽観的並行制御。別のライターが先にplanを変更していたら 再試行する。

DeleteItemも条件をサポートします — たとえばstatus = :closedのときだけ削除する、 というふうに。条件は別途の読み取り料金を加えません。DynamoDBは書き込みの試行中に、 保存されているアイテムに対して条件を評価します。

条件はDynamoDB式ビルダーで視覚的に構築し、 ConditionExpressionExpressionAttributeNamesExpressionAttributeValuesを SDK呼び出しにコピーしましょう。

冪等性と上書きの安全性

条件のないPutItemは、アイテム全体に対する最後の書き手が勝つ方式です。Webhookの ハンドラーやSQSのコンシューマーでは、処理済みマーカー属性に対する attribute_not_existsとputを組み合わせるか、attribute_not_exists(processed)で ガードしたSET processed = :trueUpdateItemを使いましょう。

監査ログのために以前の属性値が必要なときは、先行するGetItemの代わりに同じ UpdateItemReturnValuesを追加してください — 往復は1回、読み取りと書き込みの競合もありません。

正しいアイテム操作を選ぶ

意図呼び出しガード
ユーザーIDでプロフィールを読むGetItem
不在ならユーザーを作成PutItemattribute_not_exists(pk)
メールを変更し他のフィールドは保持UpdateItem任意でemail <> :old
設定ブロブ全体を置き換えPutItemペイロードが完全なときだけ
クローズ済みチケットを削除DeleteItemstatus = :closed
既知のキーで50件のチケットを読むBatchGetItem50回の直列GetItemではなく

DynoTableでの書き込みのステージング

DynoTableはUpdateItemPutItemをコミット前にローカルでステージングします。属性の 差分を確認し、任意でPartiQLのチェックを実行してからコミットすると、上記の実際のAPI 呼び出しに対応づけられます。行の一括削除は内部で BatchWriteItemにまとめられ、未処理アイテムは 再試行されます。

SDKコードの生成には、式ビルダーで更新句を 組み立て、出力されたSDK v3のスニペットをハンドラーのテストの隣に貼り付けましょう。

更新日