DynamoDB のデータを表示、閲覧、編集する方法
DynamoDB テーブルに対して行う「見る」や「変える」はすべて、少数の API 操作 — GetItem、Query、
Scan、PutItem、UpdateItem、DeleteItem — のいずれかにマッピングされます。下層にリレーショナルな
テーブルビューアは存在しません。「テーブルを閲覧する」は文字どおり Scan であり、「行を編集する」は
に対する UpdateItem です。各クリックがどの操作にマッピングされるかを
知っていることが、安価な読み取りと、意図せず実行してしまうテーブル全体のスキャンとの分かれ目です。
DynoTable はまさにこれらの操作の上に載る GUI です — これから実行しようとしている操作とそのコストを、 ワイヤに届く前に示します。
DynamoDB テーブルを閲覧する方法
「中身を見る」ためにテーブルを開くのは Scan です — テーブルまたはインデックス内のすべての
アイテムを読み取ります(AWS:
「Amazon DynamoDB の Scan 操作は、テーブルまたはセカンダリインデックス内のすべてのアイテムを
読み取ります。」)。小さなテーブルなら問題ありませんが、大きなテーブルでは
Query vs Scan で扱う古典的なコストの落とし穴です。
単一の Scan は最大 1 MB のデータを返し、次のページを取得するための LastEvaluatedKey を渡します
— つまり「テーブル全体を閲覧する」は実際にはページングのループです
(AWS:
「単一の Scan リクエストは最大 1 MB のデータを取得できます」および「Scan レスポンスの
LastEvaluatedKey は、次の Scan リクエストの ExclusiveStartKey として使用する必要があります」)。
カーソルの仕組みと、なぜオフセット形式のページ番号がここに存在しないのかについては
ページネーション を参照してください。
DynamoDB のデータをフィルタ / スキャンする方法
落とし穴: はスキャンを節約しません。DynamoDB は読み取りが完了した 後 にフィルタを適用するため、残す行だけでなく、スキャンしたすべてのアイテムに対して料金を支払います。
フィルタ式は
Scanが完了した後、結果が返される前に適用されます。したがって、Scanは フィルタ式の有無にかかわらず、同じ量の読み取りキャパシティを消費します。 — AWS Scan ドキュメント
レスポンスはこれを可視化します。ScannedCount は「ScanFilter が適用される前に評価されたアイテムの
数」であり、Count はフィルタを通過したものです
(AWS)。
ScannedCount が高く Count がごくわずかなのは、非効率なスキャンの兆候です。
DynamoDB テーブルをクエリする方法
Query は安価で対象を絞った読み取りです — ただしパーティションキーが必要です。
AWS によると:
「パーティションキー属性の名前と、その属性の単一の値を指定する必要があります。Query はその
パーティションキー値を持つすべてのアイテムを返します。オプションで、ソートキー属性を指定し、
比較演算子を使って検索結果を絞り込むことができます。」
つまり Query は 1 つのパーティションキーの下のアイテムだけを読み取り、オプションでソートキー条件に
よって絞り込みます — テーブル全体を読むことは決してありません。パーティションキーがなければ Query
もなく、Scan に逆戻りです。その選択が DynamoDB における最も重要なコストの決定です。詳しい内訳は
Query vs Scan にあります。
us-east-1 のオンデマンドでは、テーブルを開いて「閲覧する」操作はページングされた Scan を
実行し、評価したアイテムごとに結果整合性で 4 KB あたり 0.5 RCU が課金されます — 1 KB の
行が入った 10 GB のテーブルを GUI でスクロールし、全部読み込んだ場合はおよそ 250 万 RCU
の桁になります。1 つのパーティションキーに絞った Query なら、そのアイテムコレクションだけを
読みます。閲覧とクエリの差は料金計算ツールで見積もれます。
プレースホルダー構文を手で書かずに KeyConditionExpression / FilterExpression を組み立てるには、
DynamoDB Expression Builder を使ってください — API が期待する
正確な names/values マップを出力します。
DynamoDB でアイテムを編集する方法
1 つのアイテムを編集するのは、その完全なプライマリキーに対する UpdateItem です。アイテム全体を
書き換えるのではなく、変更する属性だけを指定した を渡します。
UpdateItem
Key: { "PK": "USER#42", "SK": "PROFILE" }
UpdateExpression: SET email = :e, updatedAt = :t人がつまずく 2 つの事実があります。どちらも AWS のアイテムのドキュメント からです。
- プライマリキーの一部ではなく、全体を指定しなければなりません。 テーブルではパーティションキー と ソートキーです。任意の属性で 「行を編集する」ことはできません — それにはまずキーを見つけるためのスキャンが必要です。
UpdateItemはアップサートです。 「指定したキーを持つアイテムが存在しない場合、UpdateItemは 新しいアイテムを作成します。それ以外の場合は、既存のアイテムの属性を変更します。」キーのタイプミスは エラーになる代わりに、暗黙のうちに新しいアイテムを作成します。
アイテムを削除する方法
これも完全なプライマリキーで指定する DeleteItem です:
「DeleteItem は指定したキーを持つアイテムを削除します」
(AWS)。
編集と同じルールです — キー全体が必要なので、「status が 'open' のすべての行」を削除するのは
1 回の呼び出しではありません。キーを見つけるためにスキャン/クエリし、それぞれを削除します。
BatchWriteItem は最大 25 の put/delete リクエストをまとめます
(AWS:
「BatchWriteItem 操作には最大 25 個の個別の PutItem および DeleteItem リクエストを含めることが
できます」)が、それぞれは依然として 1 つのキーをターゲットにします — DELETE … WHERE はありません。
ネストされた / JSON データを表示する方法
DynamoDB のアイテムは型タグ付きのワイヤフォーマット(DynamoDB-JSON)で保存され、すべての値が
1 文字または 2 文字の型記述子(S、N、M、L、SS… — 記述子の完全なリストは
AWS のデータ型のドキュメント
にあります)を持ちます。プレーンな JSON にはセット型がないため、配列はリスト(L)としてラウンド
トリップし、決して文字列セット(SS)にはなりません — これは表示のバグではなく、実際の変換上の
制限です。完全な型マップは DynamoDB のデータ型 にあります。DynamoDB-JSON の
ブロブをプレーンな JSON に、またその逆に変換するには
DynamoDB JSON コンバータ を使ってください。
閲覧と編集の先へ: DynamoDB にはできないクエリ
Scan/Query/UpdateItem は表示と編集をカバーしますが、分析 はできません — DynamoDB には
JOIN、GROUP BY、COUNT/SUM のような集計関数がなく、
PartiQL もそれらを加えません。その SELECT 文法は単に
SELECT … FROM table [WHERE …] [ORDER BY …] で、結合やグループ化の句はありません
(AWS PartiQL SELECT リファレンス)。
そのため、各ステートメントは単一の Get/Query/Scan/Put/Update/Delete にマッピングされます。DynoTable の
SQL Workbench は、テーブルを DynamoDB の本物のクエリランタイムを通してマテリアライズし、その上で SQL を
実行することで、そのギャップを埋めます — DynamoDB のアクセスパターンのルール内で動く SQL です —
ただし日々の閲覧と編集には、上記の操作が道具箱のすべてです。
よくある質問
AWS コンソールを使わずに DynamoDB のデータを表示するには?
同じ Scan/Query 呼び出しを発行するデスクトップ GUI を使います。AWS コンソールはページ化された
スキャンでテーブルを閲覧します。DynoTable のような専用クライアントも同じことをしますが、消費した
キャパシティと実行している操作を表示します。
DynamoDB のアイテムを編集するには?
変更する属性だけを指定した SET 更新式で、アイテムの完全なプライマリキーに対して UpdateItem を
発行します。GUI ではセルをインライン編集します — それがあなたに代わってその UpdateItem に
コンパイルされます。
なぜフィルタしても依然としてテーブル全体のスキャンのコストがかかるのですか? DynamoDB はスキャンがアイテムを読み取った 後 にフィルタを適用するからです。フィルタで除外された アイテムも依然として読み取られ、計上されます。コストを削るには、スキャンではなくパーティションキー (または GSI)でクエリしてください。
一度に多くのアイテムを更新できますか?
UPDATE … WHERE はありません — 各 UpdateItem/DeleteItem は単一のプライマリキーをターゲットに
します。複数のアイテムを 1 つのアトミックなリクエストで変更するには、TransactWriteItems が最大
100 個の書き込みアクション(Update を含む)を適用し、すべて成功するかすべてロールバックします。
それ以外の場合は、スキャン/クエリでキーを集め、それぞれを書き込みます(BatchWriteItem あたり
最大 25 個)。
DynamoDB Local のテーブルも同じように閲覧できますか? はい — 同じ GUI をローカルのエンドポイントに向けます。DynamoDB Local を 参照してください。
DynamoDB テーブルを閲覧、フィルタ、インライン編集し — そして PartiQL にはできない SQL を実行したい ですか?DynoTable をダウンロードしましょう。