初級読了 3 分

DynamoDB のデータ型:全型を例付きで

DynamoDB のすべての属性は、ワイヤ形式で1文字か2文字の型コードが付けられます。 この型は値の格納方法とアイテムサイズへの数え方の両方を左右するため、 どんな型があるかを知っておくことが重要です。

DynamoDB はどんなデータ型をサポートしていますか?

DynamoDB は3つのカテゴリにわたる10種類のデータ型をサポートしています。スカラーは String(S)、Number(N)、Binary(B)、Boolean(BOOL)、Null(NULL)です。ドキュメントは Map(M)と List(L)で、他の型をネストします。セットは String Set(SS)、Number Set(NS)、Binary Set(BS)で、順序なし・同種・空でない、という性質を持ちます。キーにできるのは SNB のみです。

コードカテゴリJSON / JS 相当例(DynamoDB-JSON)
SStringスカラーstring{"S": "Ada"}
NNumberスカラーnumber{"N": "37"}
BBinaryスカラーUint8Array / base64{"B": "ZGF0YQ=="}
BOOLBooleanスカラーboolean{"BOOL": true}
NULLNullスカラーnull{"NULL": true}
MMapドキュメントobject{"M": {"k": {"S": "v"}}}
LListドキュメントarray{"L": [{"N": "1"}]}
SSString setセット—(JSON 型なし){"SS": ["a", "b"]}
NSNumber setセット{"NS": ["1", "2"]}
BSBinary setセット{"BS": ["ZA=="]}

スカラー

  • S — 文字列(UTF-8。文字数ではなくバイト長でサイズが決まる)。
  • N — 数値。精度を保つため文字列として送られ、最大38桁。
  • B — バイナリ。base64 エンコードで送られる。
  • BOOLtrue / false
  • NULL — 明示的な null マーカー。

ドキュメント

  • M — マップ(オブジェクト)。ネストされた各属性は自身の型タグを保持する。
  • L — リスト。要素は型が混在してもよい。
{"profile": {"M": {"name": {"S": "Ada"}, "age": {"N": "37"}}}}

セット

  • SS — 文字列セット、NS — 数値セット、BS — バイナリセット。

セットは順序なし・同種で、空にはできません。重要なのは、素の JSON にはセット型が存在しないことです。配列はリスト(L)としてラウンドトリップし、SS/NS にはなりません。これはバグではなく実際の変換上の制限です。 DynamoDB-JSON コンバーター の注記を参照してください。

どの型をキーにできますか?

キーとキーは、テーブル上でも任意のインデックス上でも、スカラーでなければならず、しかも SNB のいずれかに限られます。boolean、set、map、list をキーにはできません。値を1つの S に連結して「複合」キーをモデル化してください(例: ORDER#2026#42)。

知っておきたい制限

  • 1つのアイテムの上限は 400 KB です。ネストされたものも含め、すべての属性名と値が対象です。
  • 数値は最大38桁の精度を持ちます(正・負のいずれも)。
  • マップとリストは32レベルまで深くネストできます。
  • セットは空でなく同種です。空のセットも、SN の混在もできません。

なぜ型がコストに影響するのか

アイテムサイズは属性名のバイト数と値のバイト数の合計で、各型のサイズの数え方は異なります。数値は圧縮され、boolean と null は1バイト、マップとリストは要素ごとのオーバーヘッドが加わります。そのサイズが読み取り/書き込みの キャパシティユニットに切り上げられます。 アイテムサイズ計算機で実際のアイテムを計測してください。

DynoTable でやってみる

上で述べたセットとリストの区別は、ツールがたいてい隠してしまうものです。DynoTable のアイテムエディターは、フォーマット切り替えでこれを明示します。

  • 素の JSON — プリミティブは素のまま("age": 30)ですが、セットは型ラッパーを保持してラウンドトリップに耐えます: "tags": { "SS": ["a", "b"] }"scores": { "NS": ["1.5", "2.5"] }。これは日常的な編集向けの読みやすい形式です。
  • DynamoDB JSON — AWS 標準の形式で、すべての 値が型タグを持ちます: "age": { "N": "30" }"name": { "S": "alice" }

両者を切り替えると、各スカラー・ドキュメント・セット型がワイヤ上でどう表現されるかが正確に分かります。そしてセット型には素の JSON 相当がないため、この切り替えは、アイテム全体を手作業でマーシャリングせずに SS/NS/BS を手で書き起こす唯一の方法でもあります。

数値セットと文字列セットを持つアイテムを表示している DynoTable のアイテムエディターと、素の JSON / DynamoDB-JSON の切り替え。
数値セットと文字列セットを持つアイテムを表示している DynoTable のアイテムエディターと、素の JSON / DynamoDB-JSON の切り替え。

DynoTable を試すと、アイテムを編集しながら各属性の型とライブのバイト数を確認でき、さらに各型タグを読み取ってくれる SQL Workbench で型付き属性をまたいでフィルタや集計ができます。アプリなしでマーシャリング済みのブロブを変換するには、DynamoDB-JSON コンバーターがブラウザ内で同じラウンドトリップを行います。

型を意図して選ぶ

ワイヤ形式は中立ではありません。キー、サイズ、そしてクエリの仕方を制約します。

必要なもの推奨避けるもの理由
プライマリキーやインデックスキーSNBBOOLML、セットキーはスカラーの S/N/B でなければならない
正確な小数の金額文字列としての Nアプリコード内の JSON 数値ワイヤ上で38桁の精度
アイテム上の一意なタグSS文字列の Lセットは重複排除、リストは重複可
順序のある履歴L またはソートキーSSセットは順序なし
ネストしたプロフィールMフラット化した S の JSONマップは型付きの子要素を保持
バイナリのサムネイルBS に入れた Base64B がネイティブのバイナリ型

よくある間違いは、素の JSON で tags: ["a","b"] を保存し、SDK にそれを L として マーシャリングさせておきながら、SS を期待する ConditionExpression がなぜ一致しないのかと 悩むことです。アイテムサイズ計算機と DynoTable のフォーマット切り替えは、書き込みが着地する 前にそれを目に見えるようにします。

実際の単位でのサイズ例

最小限のユーザープロフィールを取り上げます。

{
  "pk": {"S": "USER#42"},
  "email": {"S": "a@example.com"},
  "plan": {"S": "pro"},
  "score": {"N": "1280"}
}

このアイテムをアイテムサイズ計算機に貼り付けて みてください。属性名にもよりますが、典型的な結果はおよそ 80〜120 バイトです — 4 KB の 読み取りブロック1つに十分収まるので、GetItem は結果整合性の RCU 1 で済みます (ベーステーブルで結果整合性を受け入れるならその半分)。2 KB の bio マップを足しても、 4 KB を超えるまで同じ読み取りは1ブロックに収まります。

ネストしたマップは要素ごとに課金されます。子属性の名前と型付きの値がそれぞれバイトを 加えます。M の中に M が深くネストした木は、同じ情報を持つフラットな属性よりも速く アイテムを 400 KB の上限へ押し上げます。

数値が文字列として運ばれる理由

DynamoDB は N の値を最大38桁の10進文字列として保存します。JavaScript の数値は IEEE-754 の倍精度浮動小数点で、有効桁数はおよそ15〜17桁です。9007199254740993 を素の JSON 経由でマーシャリングすると黙って丸められることがあります。DynamoDB JSON 経由なら 正確な文字列 "9007199254740993" が保たれます。

数値を比較する式を書くときも、プレースホルダは ExpressionAttributeValues の中で文字列 形式のままです: {":n":{"N":"42"}}式ビルダーは そのマップを正しく出力するので、タグのないリテラルを ConditionExpression に混ぜずに 済みます。

アプリケーションコードでのセット

JSON にセット型がないため、アプリケーションコードはしばしば配列を使います。ドメインが 一意性を要求するなら — タグの集合、ロールの集合、ID の集合 — SS/NS/BS を明示的に 書きましょう。DynoTable の素の JSON モードは編集中もセットのラッパーを見えるまま保ち、 DynamoDB JSON の切り替えは標準の { "SS": [...] } 形式を表示します。

クエリでのアクセスについては、セットはキーになれないことを思い出してください。ルック アップ用の ID は S または N のキーとしてモデル化し、セット値の属性はキー条件の後に フィルタされるペイロードのフィールドとして保存します — 大規模にメンバーシップで検索する 必要があるなら、メンバーシップを隣接アイテムとして非正規化しましょう。

DynoTable での練習手順

テーブルに接続し、任意のアイテムを開き、ライブのバイトカウンターを見ながら素の JSON と DynamoDB JSON を切り替えてみてください。LSS に変えてコミットすると、差分が型タグ を明示します。SQL Workbench で型付きの列に対して SELECT を実行すると、文字列・数値・ マップが結果グリッド上で別々の型として現れます。これは、インポートした CSV データが すべて文字列だと決めつけていたときに役立ちます。

CLI で属性ディスクリプタを当てずっぽうに書く代わりに、型付きのコントロールで編集する にはDynoTable をダウンロードしてください。

更新日