初級読了 2 分

DynamoDB のデータを表示、閲覧、編集する方法

DynamoDB テーブルに対して行う「見る」や「変える」はすべて、少数の API 操作 — GetItemQueryScanPutItemUpdateItemDeleteItem — のいずれかにマッピングされます。下層にリレーショナルな テーブルビューアは存在しません。「テーブルを閲覧する」は文字どおり 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 文字の型記述子(SNMLSS… — 記述子の完全なリストは AWS のデータ型のドキュメント にあります)を持ちます。プレーンな JSON にはセット型がないため、配列はリスト(L)としてラウンド トリップし、決して文字列セット(SS)にはなりません — これは表示のバグではなく、実際の変換上の 制限です。完全な型マップは DynamoDB のデータ型 にあります。DynamoDB-JSON の ブロブをプレーンな JSON に、またその逆に変換するには DynamoDB JSON コンバータ を使ってください。

閲覧と編集の先へ: DynamoDB にはできないクエリ

Scan/Query/UpdateItem は表示と編集をカバーしますが、分析 はできません — DynamoDB には JOINGROUP BYCOUNT/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 をダウンロードしましょう。

更新日