DynamoDBのアイテムベース操作
DynamoDBのAPIは3つのファミリーに分かれます:プライマリキーで単一のアイテムを操作する
アイテムベースの操作、1つのパーティション内の範囲を読み取るQuery、そして
すべてを読み取るScanです。本ガイドは最初のファミリー — 最もよく使う4つの操作、
GetItem、PutItem、UpdateItem、DeleteItemを扱います。これらはDynamoDBが提供する
中で最も安価で高速な呼び出しであり、その区別(特にPutとUpdate)を正しく理解すれば、
不慮のデータ損失バグの一群を防げます。
DynamoDBのアイテムベース操作とは?
DynamoDBのアイテムベース操作とは、完全なプライマリキーで単一のアイテムを対象とする4つの呼び出しです:GetItemはアイテムを読み取り、PutItemはアイテムを作成または完全に置き換え、UpdateItemは特定の属性をその場で変更し、DeleteItemはアイテムを削除します。それぞれがちょうど1つのアイテムだけを対象とするため、多数のアイテムを読み取るQueryやScanとは違い、最も高速で最も安価な呼び出しになります。
GetItem— 完全なプライマリキーで1つのアイテムを読み取る。PutItem— 1つのアイテムを作成または完全に置き換える。UpdateItem— 1つのアイテムを作成、またはその特定の属性をその場で変更する。DeleteItem— 完全なプライマリキーで1つのアイテムを削除する。- 4つすべてが完全なプライマリキーを必要とする(パーティションキー、テーブルにソート キーがあればそれも) — ちょうど1つのアイテムを指定する。
PutItemはアイテム全体を上書きし、UpdateItemは外科的に変更する — これらを混同 すると、属性が静かに消える。
決定的な特徴:1つのアイテム、完全なキー
すべてのアイテムベース操作は、完全なプライマリキーで単一のアイテムを対象とします。 これこそが速くて安い理由です — DynamoDBはパーティションキーをハッシュし、まっすぐその アイテムにたどり着いて完了します。フィルタリングもスキャンもありません。完全なキーが わからないなら、これらは適したツールではありません。そのためにあるのが QueryとScanです。
USER#<id>をキーにしたユーザーアカウントを運用しているとします:
PK: USER#204 email, displayName, plan, createdAtUSER#204に対するGetItem→ そのユーザーに直接アクセス。USER#204に対するDeleteItem→ そのユーザーを削除。
どちらも正確なキーが必要です。キーがなければ、アイテムベース操作はできません。
PutItemとUpdateItem — 痛い目を見るやつ
これは身につけておく価値のある区別です:
PutItemはアイテム全体を書き込む。USER#204がすでに存在していて、{email, displayName}だけでPutItemすると、既存のplanとcreatedAt属性は 消えます — putはアイテム全体を置き換えるのであって、マージしません。UpdateItemは指定したものだけを変更する。SET email = …を伴うUpdateItemは、他の すべての属性をそのまま残し、アイテムが存在しなければ作成します(upsert)。
経験則:既存のアイテムを変更するならUpdateItemを使い、PutItemは本当に
「このアイテムを完全な新しい状態として書き込む」という意味のときだけ使いましょう。
PutItemとUpdateItemはどちらも
条件式を受け付けるので、書き込みを条件付きに
できます(「まだ存在しない場合のみ」)。
DynoTableでのアイテムベース操作
これらの操作の背後にある生のAPI呼び出しを確認したいですか? DynamoDB式ビルダーで式と型付き値マップを組み立て、 DynamoDB JSONコンバーターでプレーンJSONのアイテムをAPIの型付き形式に変換してください。
DynoTableでは、同じ作業が視覚的になります:グリッドでアイテムを開いて読み取り
(GetItem)、属性を編集してコミットし(UpdateItem)、行を追加または置き換え
(PutItem)、または削除します — 1回に1つのアイテムを。

落とし穴と次のステップ
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で済むのかを比べる
ときは、料金計算ツールで秒あたりのリクエスト数を
掛けてみましょう。
書き込みの条件式
PutItemとUpdateItemはどちらも任意の
条件式を受け付けます。典型的なパターン:
attribute_not_exists(pk)をputに — 競合なしの作成専用インサート。attribute_exists(pk)をupdateに — うっかりスタブを作るのを拒否する。plan = :oldをupdateに — 楽観的並行制御。別のライターが先にplanを変更していたら 再試行する。
DeleteItemも条件をサポートします — たとえばstatus = :closedのときだけ削除する、
というふうに。条件は別途の読み取り料金を加えません。DynamoDBは書き込みの試行中に、
保存されているアイテムに対して条件を評価します。
条件はDynamoDB式ビルダーで視覚的に構築し、
ConditionExpressionとExpressionAttributeNames、ExpressionAttributeValuesを
SDK呼び出しにコピーしましょう。
冪等性と上書きの安全性
条件のないPutItemは、アイテム全体に対する最後の書き手が勝つ方式です。Webhookの
ハンドラーやSQSのコンシューマーでは、処理済みマーカー属性に対する
attribute_not_existsとputを組み合わせるか、attribute_not_exists(processed)で
ガードしたSET processed = :trueのUpdateItemを使いましょう。
監査ログのために以前の属性値が必要なときは、先行するGetItemの代わりに同じ
UpdateItemにReturnValuesを追加してください —
往復は1回、読み取りと書き込みの競合もありません。
正しいアイテム操作を選ぶ
| 意図 | 呼び出し | ガード |
|---|---|---|
| ユーザーIDでプロフィールを読む | GetItem | — |
| 不在ならユーザーを作成 | PutItem | attribute_not_exists(pk) |
| メールを変更し他のフィールドは保持 | UpdateItem | 任意でemail <> :old |
| 設定ブロブ全体を置き換え | PutItem | ペイロードが完全なときだけ |
| クローズ済みチケットを削除 | DeleteItem | status = :closed |
| 既知のキーで50件のチケットを読む | BatchGetItem | 50回の直列GetItemではなく |
DynoTableでの書き込みのステージング
DynoTableはUpdateItemとPutItemをコミット前にローカルでステージングします。属性の
差分を確認し、任意でPartiQLのチェックを実行してからコミットすると、上記の実際のAPI
呼び出しに対応づけられます。行の一括削除は内部で
BatchWriteItemにまとめられ、未処理アイテムは
再試行されます。
SDKコードの生成には、式ビルダーで更新句を 組み立て、出力されたSDK v3のスニペットをハンドラーのテストの隣に貼り付けましょう。


