Amazon DynamoDBは、AWSが提供するサーバーレスでフルマネージドなNoSQLデータベースです。サーバーの構築もエンジンのバージョン更新も不要な代わりに、テーブル同士の結合やSQLのGROUP BYのような集計を持ちません。RDS(リレーショナルデータベース)と同じ感覚で設計すると、リリース後に検索軸が増えた時点で行き詰まります。この記事では、RDSとの使い分けの基準、読み4KB・書き1KBで数える料金、DynamoDB LocalとAWS CLI・boto3での使い方、ホットパーティションを避けるキー設計、集計の逃がし先までを、2026年10月時点の公式ドキュメントの数値で整理します。
まとめ:DynamoDBを選ぶ条件と料金・設計の結論
先に結論を置きます。
- 正体:サーバーとバージョンを持たないNoSQL。3つのアベイラビリティゾーンへの自動複製と可用性SLA 99.99%、保存時の暗号化が既定で付きます。
- RDSとの分かれ目:主要な読み取りをキー指定で処理でき、残る検索のScanや集計のコストも許容できるならDynamoDB、検索条件の組み替えや集計が業務の中心ならRDSかAuroraです。
- 上限:1項目400KB、Queryの結果は1回1MBまで。大きなファイルはS3に置き、DynamoDBにはキーとメタデータだけを持たせます。
- 料金:オンデマンドはリクエスト数、プロビジョンドは確保した容量に課金。2024年11月1日にオンデマンドのスループット単価が50%下がり、小規模なら月数ドルで収まります。
- 使い方の最短路:Dockerイメージ
amazon/dynamodb-localを8000番で起動し、AWS CLIに--endpoint-urlを渡せば課金なしでテーブル作成からqueryまで通せます。 - 集計:SUMやGROUP BYによる集計は提供されず、Query・ScanのCOUNTも読み取り容量とページングを必要とするため、大規模な集計はStreams+Lambdaの増分集計、S3エクスポート+Athena、Redshiftへのゼロ ETL 統合のいずれかへ逃がします。
判断に迷ったら、主要な読み方を「誰が・どのキーで・どの範囲を読むか」の形で列挙し、すべてをキーかインデックスで引けるかを確かめてください。列挙が終わらない、または検索条件を利用者が自由に組み替える要件が中心なら、RDSかAuroraを選びます。以下、根拠と手順を順に示します。
Amazon DynamoDBとは:公式定義と標準で付く機能の全体像
製品名で調べている段階なら、「何が最初から付いていて、何を自分で設定するのか」を先に押さえると、後の設計判断で迷いません。
サーバーレス・フルマネージド・NoSQLで読む公式の定義と得意・苦手
公式ドキュメント「What is Amazon DynamoDB?」は、DynamoDBを「サーバーレスでフルマネージドな分散NoSQLデータベースで、どの規模でも1桁ミリ秒の性能を出す」と定義しています。提供開始は2012年です。公式は、DynamoDBにはメジャー・マイナー・パッチのバージョンが存在せず、メンテナンスウィンドウも無いと明記しています。RDBではエンジンのサポート期限や更新方針に応じたアップグレード計画が必要ですが、DynamoDBでは利用者がエンジンのバージョン更新を計画する必要はありません。
データモデルはキー・バリュー型とドキュメント型の両方を扱えます。強整合性の読み込みとACIDトランザクションにも対応するため、注文確定のように複数項目をまとめて更新する処理も書けます。一方でJOIN演算子は持たず、公式は往復回数を減らすためにデータを非正規化するよう勧めています。キー以外の条件で全件を読むScanはテーブル全体を読むので遅く高コストで、SUMやGROUP BYによる集計は提供されません。ただし、Query・Scanの Select=COUNT で件数を取得でき、通常の読み取りと同じ容量を消費します。
得意なのは、キーで1件を引く操作とソートキーの範囲で引く操作を、データ量に関係なく安定した速度で捌くことです。セッション、ショッピングカート、IoTの計測値、ゲームの状態、通知の既読管理がこの形に当てはまります。キーバリューストアという分類の考え方そのものはKVS(キーバリューストア)の仕組みとRDBとの使い分けで、Redisを動かしながら説明しています。
可用性SLA・暗号化・PITRなど標準で付く機能と追加設定が要る機能
同じ公式ドキュメントに並ぶ運用機能を、追加の設定が要るかどうかで分けました。
| 機能 | 公式が示す内容 | 有効化 |
|---|---|---|
| AZ間の複製 | 3AZへ自動複製・SLA 99.99% | 既定 |
| 保存時の暗号化 | 全データを既定で暗号化 | 既定 |
| グローバルテーブル | 複数リージョン・SLA 99.999% | 要設定 |
| ポイントインタイム復旧 | 1〜35日の範囲を秒単位で復元 | 要設定 |
| DynamoDB Streams | 変更履歴を24時間保持 | 要設定 |
| TTL | 期限切れ項目を自動削除 | 要設定 |
| DAX | 読み取りを最大10倍に高速化 | 別構築 |
既定で付くのは複製と暗号化の2つです。保存時の暗号化はAWS KMSの鍵で行い、AWS所有キー(追加料金なし)、AWSマネージドキー、カスタマー管理キーから選べます。アクセス制御はIAMで行い、データベース用のユーザー名とパスワードは存在しません。接続文字列を秘匿する代わりに、IAMポリシーの範囲をどう絞るかと、CloudTrailで誰がどのテーブルを操作したかを追える状態にするのが守りの中心になります。
課金の範囲には注意が要ります。公式は、読み書きと保存量に加えて「有効化したオプション機能」にも課金すると説明しています。PITRやStreamsを本番で一括有効にする前に、どの機能に費用が乗るかを料金ページで確かめてください。多リージョン複製の挙動はDynamoDB Global Tables(グローバルテーブル)の仕組みと料金、期限切れ項目の削除はDynamoDB TTLの設定方法と自動削除の仕組み、埋め込みベクトルの類似検索はDynamoDBのベクトル検索の手順と料金で個別に扱っています。
テーブル・項目・属性とキーの構造と設計を縛る上限値
コマンドを打つ前に、DynamoDBが何をどう格納しているかを押さえます。キーは後から変えられないため、ここを飛ばすとテーブルの作り直しになります。
テーブル・項目・属性の3階層とRDBの表・行・列との対応
公式のコアコンポーネント解説では、テーブルが項目(item)の集合で、項目が属性(attribute)の集合だと定義されています。
| DynamoDB | RDBの近い概念 | 違い |
|---|---|---|
| テーブル | テーブル | 固定スキーマを持たない |
| 項目(アイテム) | 行 | 項目ごとに属性構成が違ってよい |
| 属性 | 列 | キー以外は事前定義が不要 |
| パーティションキー | 主キーの一部 | 格納先パーティションを決める・必須 |
| ソートキー | 複合主キーの一部 | 同一パーティション内の並び順・任意 |
同じテーブルの中で、ある項目は Phone を持ち、別の項目は Address という入れ子のオブジェクトを持つ構造が許されます。入れ子は32段まで許容されます。列追加のマイグレーションが要らない反面、書き込む側の規律を保つ仕組みが無いと、3か月後に status と Status が混在したテーブルが残ります。
パーティションキーとソートキーで決まる物理配置とキーに使える型
プライマリキーは、パーティションキー単独の単純キーか、パーティションキーとソートキーを組み合わせた複合キーのどちらかです。パーティションキーの値は内部のハッシュ関数に渡され、その出力で項目の格納先パーティションが決まります。
ソートキーは、同じパーティションキーを持つ項目の並び順と範囲検索を担う任意のキーです。複合キーにすると同じパーティションキー値の項目がソートキー順に並んで格納され、「ある顧客の2026年9月の注文だけ」のような範囲クエリが1回で済みます。1対多の関係を1テーブルで表現する要がソートキーです。
キー属性に使える型は文字列・数値・バイナリの3つだけで、リストやマップはキーにできません。日付をキーに含めたいなら、ISO 8601形式の文字列にするか数値のエポック秒にするかを、この時点で決めておきます。
項目400KB・Query1MB・トランザクション100項目などの上限値
DynamoDBには設計を縛る固定の上限があり、引き上げられない値も含まれます。数値は公式の制約一覧とクォータ一覧の記載です。
| 項目 | 上限 | 引き上げ |
|---|---|---|
| 項目サイズ(属性名を含む) | 400KB | 不可 |
| キーの長さ | パーティション2,048B・ソート1,024B | 不可 |
| Query・Scanの1回の結果 | 1MB | 不可 |
| トランザクション | 100項目・4MB | 不可 |
| GSIの数(1テーブル) | 20 | 可 |
| LSIの数(1テーブル) | 5 | 不可 |
| LSIを持つ表の項目コレクション | 10GB | 不可 |
| 射影属性の合計 | 100 | 不可 |
| テーブル単位のスループット | 40,000 RRU・WRU | 可 |
実務で最初に当たるのは400KBと1MBです。属性名もサイズに数えるため、customer_shipping_address のような長い属性名を数百万件に持たせると、その分だけ容量と読み書きユニットを食います。画像やPDFはS3に置き、DynamoDBにはオブジェクトキーだけを持たせます。
射影属性の100という数字も見落とされがちです。ローカルとグローバル両方のセカンダリインデックスを合計した数で、射影タイプが KEYS_ONLY か ALL のインデックスは対象外のため、INCLUDE を多用する設計だけがこの壁に当たります。
DynamoDBとRDSの違いと使い分けの判断基準
DynamoDBとRDS(MySQLやPostgreSQLを動かすマネージドRDB)は、何を先に決めるかが逆です。DynamoDBはクエリの形を先に固める代わりに運用作業を手放せ、RDSはクエリの自由度を残す代わりにエンジンの版やインスタンスの管理が続きます。RDS側の仕組みはAmazon RDSの仕組み・対応エンジン・料金で、RDB全般とNoSQLの選び方はデータベースの種類とRDB・NoSQLの選び方で整理しています。
| 観点 | DynamoDB | RDS |
|---|---|---|
| データモデル | キー・バリュー+文書 | 表とSQL |
| 結合・集計 | 非対応 | 対応 |
| スキーマ | キーのみ事前定義 | 事前に定義 |
| スケール | 水平・自動 | 垂直+読み取りレプリカ |
| エンジン更新 | 発生しない | 計画して実施 |
| アクセス制御 | IAMポリシー | DBユーザー中心 |
| 課金 | リクエスト量か確保容量 | インスタンス時間+ストレージ |
DynamoDBを選んでよい条件と料金面で有利になるデータ
採用の前提は1つです。アクセス経路が事前に列挙でき、その大半がパーティションキーの指定で完結すること。これが満たせないなら、ほかの条件がどれだけ合っていても選びません。前提を満たしたうえで、項目が1KB前後に収まる(書き込み単位が小さく済む)こと、平常時とピーク時でトラフィックが桁違いに動く(オンデマンドで空き容量に払わずに済む)ことが重なるほど、料金面でRDSより有利になります。負荷が一定なら、後述のプロビジョンドで単価を下げられます。
典型は、セッション管理、ショッピングカート、イベントログ、APIのレート制御、注文や予約のように主体ごとに引く履歴データです。いずれも「誰の」「いつからいつまで」というキーで引き切れます。公式ドキュメントが挙げる用途も、金融の取引台帳、ゲームのプレイヤーデータとリーダーボード、動画配信の視聴リストと、主体のキーで引く形がそろっています。
RDSを選ぶべき要件とDynamoDBを後から苦しめる失敗パターン
次のどれかに当てはまるなら、DynamoDBは選びません。
- 管理画面で検索条件の組み合わせを利用者が自由に選べる(受発注・顧客管理・在庫照会)
- 月次の売上集計や帳票出力が主目的で、リアルタイム性が要らない
- 受注・在庫・請求の同時更新が日常的に発生し、100項目・4MBのトランザクション上限に収まらない
- チームにキー設計の経験者がおらず、要件もまだ動いている
失敗の型はこうです。初期要件が「ユーザーIDで引くだけ」だったためDynamoDBを採用し、リリース後に「部署別の月次集計を出したい」「ステータス横断で検索したい」という要求が続く。GSIを足して凌ぐうちに射影属性100の上限に近づき、RDBなら1本のSQLで済む集計に、専用のインデックスとバッチを作り続けることになります。公式のNoSQL設計指針も、限られた方法なら効率よく引ける一方、その範囲を外れたクエリは高価で遅くなると書いています。
現実の構成では、全部を1つのデータストアに寄せる必要はありません。業務データの本体はRDSかAurora、高頻度で単純なデータはDynamoDB、と1システムの中で併用する形が一般的です。RDBのままスケールと可用性も欲しい場合の受け皿はAmazon AuroraとRDSの違い・料金モデルで比べています。どのデータをどちらに置くかの線引きやキー設計のレビューから相談したい場合は、AWS・Google Cloud・Azureのインフラ構築支援で要件の棚卸しから対応しています。
DynamoDB LocalとAWS CLI・boto3で使い方を試す手順
AWSアカウントに課金せずに挙動を確かめられるよう、まずローカルで動かします。事前にDocker Compose、AWS CLI、Python環境を用意し、Python環境にはboto3をインストールしてください。以下のYAMLはcompose.yamlとして保存します。同じコマンドを本番に向けるときは --endpoint-url を外し、ローカル用に設定した環境変数の認証情報を解除し、有効な認証情報とIAM権限を設定します。環境変数のダミー認証情報は、aws configure で保存した認証情報より優先されるため、そのままでは本番に接続できません。
docker composeでDynamoDB Localを8000番に立ち上げる設定
公式のDynamoDB Localデプロイ手順の定義をそのまま使います。-sharedDb を付けると、認証情報やリージョンが違っても同じデータベースファイルを参照するため、CLIとアプリの両方から同じテーブルが見えます。
services:
dynamodb-local:
command: "-jar DynamoDBLocal.jar -sharedDb -dbPath ./data"
image: "amazon/dynamodb-local:latest"
container_name: dynamodb-local
ports:
- "8000:8000"
volumes:
- "./docker/dynamodb:/home/dynamodblocal/data"
working_dir: /home/dynamodblocal
起動は docker compose up -d の1行です。-dbPath とボリュームの組み合わせにより、コンテナを落としてもデータはホスト側に残ります。-dbPath を省略するとカレントディレクトリのファイルに保存され、インメモリ動作になるのは -inMemory を指定した場合です。ボリュームを省略すると、コンテナを削除・再作成した際にデータを失う可能性があります。
公式はv3.xを現行、v2.xをレガシーと区分しており、DynamoDB Localのリリース履歴では2026年10月15日の3.3.2が最新です(稼働中の版はJARに -version を渡せば確認できます)。v2.6.0以降はJava実行環境(JRE)17以降が必要なので、JARを直接動かすCIのベースイメージがJava 11のままなら起動に失敗します。
AWS CLIによるテーブル作成・書き込み・単一項目取得・Queryの4操作
DynamoDB Localは認証情報の中身を検証しませんが、値そのものは必須です。ダミー値を環境変数に入れ、注文データを想定して複合キーとGSIを持つテーブルを作ります。
export AWS_ACCESS_KEY_ID=fakeMyKeyId
export AWS_SECRET_ACCESS_KEY=fakeSecretAccessKey
export AWS_DEFAULT_REGION=ap-northeast-1
aws dynamodb create-table \
--table-name Orders \
--attribute-definitions \
AttributeName=PK,AttributeType=S \
AttributeName=SK,AttributeType=S \
AttributeName=Status,AttributeType=S \
--key-schema \
AttributeName=PK,KeyType=HASH \
AttributeName=SK,KeyType=RANGE \
--billing-mode PAY_PER_REQUEST \
--global-secondary-indexes '[{"IndexName":"StatusIndex","KeySchema":[{"AttributeName":"Status","KeyType":"HASH"},{"AttributeName":"SK","KeyType":"RANGE"}],"Projection":{"ProjectionType":"KEYS_ONLY"}}]' \
--endpoint-url http://localhost:8000
KeyType=HASH がパーティションキー、RANGE がソートキーです。属性定義に並べるのはキーとインデックスに使う属性だけで、Amount のような非キー属性を書くとエラーになります。作成できたら項目を1件入れ、キー完全一致の取得と前方一致のqueryを投げます。
aws dynamodb put-item \
--table-name Orders \
--item '{"PK":{"S":"CUSTOMER#1001"},"SK":{"S":"ORDER#2026-09-07#001"},"Status":{"S":"SHIPPED"},"Amount":{"N":"12800"}}' \
--endpoint-url http://localhost:8000
aws dynamodb get-item \
--table-name Orders \
--key '{"PK":{"S":"CUSTOMER#1001"},"SK":{"S":"ORDER#2026-09-07#001"}}' \
--endpoint-url http://localhost:8000
aws dynamodb query \
--table-name Orders \
--key-condition-expression "PK = :pk AND begins_with(SK, :prefix)" \
--expression-attribute-values '{":pk":{"S":"CUSTOMER#1001"},":prefix":{"S":"ORDER#2026-09"}}' \
--endpoint-url http://localhost:8000
ソートキーを ORDER#日付#連番 の順に並べておくと、begins_with で「2026年9月の注文だけ」を1回のqueryで取り出せます。全件を読むScanと違い、queryは対象パーティションだけを読むので速く安価です。キー属性の定義はテーブル作成後に変えられず、キー値も UpdateItem では書き換えられません。キーの形式を後から変えるには、新しい形式のキーで項目を書き直して旧項目を削除する移行が要ります。
boto3でqueryを書き1MBの上限をページングで越えるPythonコード
アプリケーションからはBoto3のDynamoDBガイドが示すリソースAPIが扱いやすく、CLIで必要だった {"S": ...} の型記述子を書かずにPythonの辞書のまま読み書きできます。queryの結果は1回1MBで打ち切られるため、応答に LastEvaluatedKey がある間は続きを取りに行くループが要ります。書き忘れると、データが増えた時点で「一部しか返らない」不具合になります。
import boto3
from decimal import Decimal
from boto3.dynamodb.conditions import Key
# ローカル検証用の接続。本番では endpoint_url と認証情報の行を消し、IAMロールに任せる
dynamodb = boto3.resource(
"dynamodb",
endpoint_url="http://localhost:8000",
region_name="ap-northeast-1",
aws_access_key_id="fakeMyKeyId",
aws_secret_access_key="fakeSecretAccessKey",
)
table = dynamodb.Table("Orders")
table.put_item(
Item={
"PK": "CUSTOMER#1001",
"SK": "ORDER#2026-09-25#002",
"Status": "PENDING",
"Amount": Decimal("5400"),
}
)
def orders_of_month(customer: str, ym: str) -> list[dict]:
items = []
kwargs = {
"KeyConditionExpression": Key("PK").eq(customer)
& Key("SK").begins_with(f"ORDER#{ym}")
}
while True:
resp = table.query(**kwargs)
items.extend(resp["Items"])
if "LastEvaluatedKey" not in resp:
return items
kwargs["ExclusiveStartKey"] = resp["LastEvaluatedKey"]
for item in orders_of_month("CUSTOMER#1001", "2026-09"):
print(item["SK"], item["Status"], item["Amount"])
型の扱いで1つ詰まりやすい点があります。リソースAPIは数値属性を decimal.Decimal で返し、書き込みでPythonの float をそのまま渡すとエラーになります。金額や割合を小数で持つなら Decimal("12.5") のように文字列から変換して渡してください。まとまった件数を投入するときは batch_writer() を使うと、バッファリングと未処理項目の再送をSDKが引き受けます。
Node.jsで書く場合はAWS SDK for JavaScript v3の使い方とDynamoDBの実装例に、LambdaとAPI Gatewayを前段に置いてREST APIとして公開する流れはLambda・DynamoDB・API GatewayでREST APIを作るハンズオンにまとめています。起動したDynamoDB LocalにGUIで接続して設計を検証するならNoSQL Workbenchの使い方が使えます。
PartiQLでSQLのように書いてもScanになる条件
SQLに慣れているなら、DynamoDBが対応するPartiQL(SQL互換のクエリ言語)でSELECT・INSERT・UPDATE・DELETEを書けます。
aws dynamodb execute-statement \
--statement "SELECT * FROM Orders WHERE PK = 'CUSTOMER#1001'" \
--endpoint-url http://localhost:8000
ただし内部で走るのはキー検索のままです。公式のSELECT文の解説のとおり、WHERE句でパーティションキーを絞らず非キー属性だけを条件にしたSELECTはテーブル全体のScanになり、遅く高コストになります。SQL構文が使えても、RDBの自由な結合と集計が手に入るわけではありません。
アクセスパターンから決めるテーブル設計のベストプラクティス
DynamoDBの性能とコストは、テーブル設計でほぼ決まります。正規化してから考えるのではなく、「どんなクエリを何回叩くか」を先に列挙し、それを満たすキーとインデックスを逆算します。
設計前に確定させるデータ量・形状・速度の3つの前提
公式のNoSQL設計指針は、設計の第一歩を「システムが満たすべきクエリパターンを特定すること」と定義し、着手前に理解しておく性質を3つ挙げています。データ量(一度にどれだけ格納し、どれだけ要求されるか)、データ形状(クエリ時に整形せず、クエリされる形のまま並べる)、データ速度(ピーク時のクエリ負荷を先に把握し、I/O容量を使い切れるようキーを分散させる)です。
実務では、画面とバッチの一覧から「誰が・どのキーで・どの範囲を・毎秒何回読むか」を表にし、各行をキーかGSIで実現できるかを確かめてからテーブルを作ります。検索条件の追加・変更が今後も続くと分かっている要件なら、それ自体がRDSを優先する合図です。
ホットパーティションを避けるキーの選び方とライトシャーディング
最も避けたいのがホットパーティション、つまり特定のパーティションキーにアクセスが集中し、そこだけがスループット上限に張り付く状態です。当日の日付をそのままパーティションキーにしたり、人気の1ユーザーに書き込みが集まったりすると、テーブル全体には余裕があってもその1点で頭打ちになります。
回避策は、値の分布が広い属性をキーに選ぶことと、必要なら末尾に乱数や計算値のサフィックスを付けて書き込みを複数パーティションへ散らすこと(ライトシャーディング)です。公式のパーティションキー設計のベストプラクティスがこの考え方の原典です。サフィックスを付けると読む側は全サフィックスへ問い合わせて結果を合わせる必要があるため、書き込みが集中するキーに限って使います。
単一テーブル設計とGSI・LSIの使い分けの判断基準
公式指針は「DynamoDBアプリケーションではテーブル数をできるだけ少なく保つべき」と明記し、例外として大量の時系列データとアクセスパターンがまったく異なるデータセットの2つを挙げています。複数の実体(顧客・注文・商品)を1テーブルに置き、CUSTOMER#・ORDER# のようなキーの前置詞で引き分けるのが単一テーブル設計です。1回のqueryで関連データをまとめて取れる反面、アクセスパターンが変わると作り直しが重くなります。
判断を言い切ると、要件が動いている小〜中規模の案件は実体ごとにテーブルを分け、アクセスパターンが固まった段階で、関連データを一緒に読む頻度と移行コストを比較し、単一テーブル化が有利な場合に限って移行します。最初から単一テーブル設計で始めるのは、読み方の一覧が確定している場合に限ります。
1つのキー構成では引けないクエリが出てきたら、グローバルセカンダリインデックス(GSI)を足します。GSIは別のパーティションキーとソートキーを持てて後から追加でき、ローカルセカンダリインデックス(LSI)はパーティションキーが同じでソートキーだけが違うもので、テーブル作成時にしか定義できません。迷ったらGSIを選びます。GSIは対象属性の書き込みごとに追加の書き込みが発生するため、本数だけで設計の良否を判断せず、各GSIが支える検索、射影サイズ、追加の書き込み費用を確認します。既定上限の20本に近づく場合は、設計の見直しとクォータ引き上げの必要性を検討します。
RRU・WRUで数える料金の仕組みと容量モードの選び方
DynamoDBの料金は、読み書きの処理量とストレージが柱です。処理量の課金には、実際のリクエスト数に払うオンデマンドと、毎秒の容量を先に確保するプロビジョンドの2つのモードがあります。
読み4KB・書き1KBを単位とする課金単位の数え方と計算例
オンデマンドモードの公式解説は、課金単位を次のように定義しています。プロビジョンドでは同じ単位がRCU・WCUという名前になります。
| 操作 | 消費する単位 |
|---|---|
| 読み取り(結果整合性) | 4KBまでで0.5 RRU |
| 読み取り(強整合性) | 4KBまでで1 RRU |
| 読み取り(トランザクション) | 4KBまでで2 RRU |
| 書き込み | 1KBまでで1 WRU |
| 書き込み(トランザクション) | 1KBまでで2 WRU |
この非対称が見積もりの起点です。3KBの項目を1件書けば3WRU、同じ項目を強整合性で読めば1RRUです。書き込みは1KB単位で切り上がるので、1.2KBの項目を1回書くと2WRUを消費します。項目を1KB以内に収め、強整合が要らない読み取りを結果整合にするだけで、読み書きのコストは目に見えて下がります。
計算例を1つ置きます。4KB以下の項目を1日100万回、強整合性で読むと月3,000万RRUです。公式の料金ページのus-east-1(バージニア北部)の単価、100万RRUあたり0.125ドルで計算すると、月3.75ドル。結果整合にすれば半分になります。東京リージョンの単価とGSIやScanで請求が跳ねる条件を含めた月額の試算はDynamoDBの料金を東京リージョンの実額で試算するで扱っています。
2024年11月の50%値下げとDatabase Savings Plans・無料利用枠
AWSの発表によると、2024年11月1日からオンデマンドのスループット単価が50%引き下げられ、グローバルテーブルの複製書き込みも最大67%下がりました。立ち上げ期にオンデマンドを選ぶ理由が、この改定でさらに強くなっています。
定常負荷には、プロビジョンドのリザーブドキャパシティに加え、2025年12月に発表されたDatabase Savings Plansが使えます。DynamoDBではオンデマンドで最大18%、プロビジョンドで最大12%の割引で、契約は1年です。オンデマンドにも適用できるコミットメント割引なので、「容量は変動するが、対象サービス全体で毎時間の最低利用額を見込める」構成で検討できます。月額総額だけでなく、時間ごとの利用額を基にコミットメントを決めます。
常時無料枠には、Standardテーブルクラスの25GBのストレージと25WCU・25RCUのプロビジョンド容量が含まれます。枠はリージョン・支払者アカウント単位で適用され、テーブルごとに付与されるものではありません。新規アカウントの無料プラン(6か月・クレジット制)との境界はAWSを無料で使える範囲と6か月の期限で確認できます。
オンデマンドの初期スループットと容量モード切り替えの回数制限
「オンデマンドは無限にスケールする」という説明をよく見かけますが、公式は具体的な数字を示しています。新規のオンデマンドテーブルは毎秒4,000書き込みユニット・12,000読み取りユニットのウォームスループットで始まり、実際に処理できる件数は項目サイズや整合性によって変わります。そこを基準に、直近ピークの2倍までを即座に受け止めます。直近ピークの2倍を超える増加を30分以内に起こすとスロットリングが起こりえるため、キャンペーン開始時刻に負荷が跳ねる設計なら、増加を30分以上かけて分散させるか、事前ウォームを行います。
| 観点 | オンデマンド | プロビジョンド |
|---|---|---|
| 課金対象 | 実リクエスト数 | 確保した容量 |
| テーブル既定上限 | 40,000 RRU・WRU | 40,000 RCU・WCU |
| 他モードへの切替 | 随時 | 24時間に4回まで |
| 容量の引き下げ | 設定なし | 24時間で最大27回 |
トラフィックが読めない立ち上げ期はオンデマンド、負荷が定常的で予測できるようになったらプロビジョンド+オートスケーリング、という移行が定番です。プロビジョンドからオンデマンドへ戻せるのは24時間のローリングウィンドウで4回までなので、負荷試験のたびにモードを往復させる運用はこの上限に当たります。
事前ウォームはウォームスループットの値を引き上げる操作で、課金モードを変えずに実行できます。事前ウォームには、現在値から引き上げる差分に応じた一回限りの料金が発生します。必要に応じて段階的に引き上げ、WarmThroughputのStatusがACTIVEになったことを確認してから負荷を増やしてください。
aws dynamodb update-table \
--table-name Orders \
--warm-throughput ReadUnitsPerSecond=12345,WriteUnitsPerSecond=4567 \
--region ap-northeast-1
DynamoDBの大規模集計・分析を別サービスへ分離する3つの構成
DynamoDBにはSUMやGROUP BYによる集計がありません。Query・Scanの Select=COUNT で件数は取得できますが、読み取り容量の消費は減りません。また、Scanしてアプリ側で集計するとテーブル全体を読むので遅く高コストです。集計が後から必要になったら、DynamoDBの中で完結させようとせず、役割を分けます。
| 方法 | 向く用途 | 前提 |
|---|---|---|
| Streams+Lambda | リアルタイムの累計・件数 | Streamsの有効化 |
| S3エクスポート+Athena | 日次・月次のバッチ集計 | PITRの有効化 |
| ゼロ ETL 統合 | 本格的な分析・全文検索 | Redshift・OpenSearch |
リアルタイムの累計を持ちたいなら、DynamoDB Streamsの変更イベントをLambdaで処理し、変更前後の差分を集計項目へ反映します。同じイベントが再処理されても二重加算しないよう、冪等性を確保します。変更フィードという設計パターンそのものはチェンジフィードの実装と採用判断で、Lambda側の課金とコールドスタートはAWS Lambdaの仕組みと料金体系で扱っています。
日次・月次のレポートなら、S3へのテーブルエクスポートが素直です。PITRを有効にしたテーブルを、読み取り容量を消費せずにS3へ書き出せるので、本番の読み書きに影響を与えずにAmazon AthenaのSQLクエリで集計できます。
分析クエリを常時流すなら、ゼロ ETL 統合でパイプラインを自作せずに分析側へデータを渡します。Amazon OpenSearch Serviceへの統合は2023年11月、Amazon Redshiftへの統合は2024年10月に一般提供が始まっています。いずれも「DynamoDBは書き込みと単純検索の源泉、集計は別サービス」という分業で、これがコストと性能の両方を守る形です。集計が主要件だと最初から分かっているなら、前の章の基準どおりRDSを選びます。
よくある質問
Amazon DynamoDBの導入検討でよく聞かれる5つに答えます。
DynamoDBの読み方は何ですか?
「ダイナモディービー」と読みます。2007年にAmazonが発表した社内向けの分散キーバリューストア Dynamo の論文が名前の由来で、Amazon DynamoDBはその考え方を元に2012年にAWSのサービスとして提供が始まりました。
DynamoDBとRDSはどちらが安いですか?
アクセスの形で決まり、一概には言えません。少数のキー検索を大量に叩く用途では、アクセスがない間は読み書きのスループット料金が発生しないオンデマンドのDynamoDBが安くなりやすい一方、結合や集計を含むクエリを常時流す用途では、インスタンス課金でも1回のSQLで済むRDSのほうが総額で有利なことがあります。まず読み書きの回数と項目サイズを見積もり、RRU・WRUに換算してから比べてください。
DynamoDBは無料で使えますか?
常時無料枠には、Standardテーブルクラスの25GBのストレージと25WCU・25RCUのプロビジョンド容量が含まれます。リージョン・支払者アカウント単位の枠であり、テーブルごとの枠ではありません。オンデマンドのリクエストやPITRなどのオプション機能は枠の外です。課金を一切出さずに試すだけなら、DynamoDB Localを手元で動かすのが確実です。
DynamoDB Localと本番環境の違いは何ですか?
DynamoDB Localは開発とテスト用のローカル実装で、認証情報の検証を行わずダミー値でも動きます。容量モードやスループットの設定は受け付けますが、実際のスロットリングやレイテンシは本番と同じではありません。API互換なのでテーブル定義とクエリの検証には使え、SDKも接続先を endpoint_url で切り替えるだけで同じコードを流用できます。スループットの限界検証やコスト測定は実際のAWS環境で行ってください。
DynamoDBでスロットリングが起きたらどう対処しますか?
まず例外に含まれるスロットリングの理由と対象リソース(テーブルかGSIか)を確かめ、公式のスロットリング解説が挙げる4つ、つまりパーティション単位の上限超過、プロビジョンド容量の超過、アカウント単位のクォータ超過、オンデマンドで設定した最大スループットの超過のどれかに切り分けます。オンデマンドで急増が原因なら、直近ピークの2倍を超える増加を30分以内に起こしていないかを確かめ、ウォームスループットの事前引き上げを検討します。特定のキーに集中しているなら、パーティションキーにサフィックスを付けて分散させる設計変更が必要です。テーブル既定の40,000という上限に届いているなら、Service Quotasから引き上げを申請します。