DynamoDB vs RDS — AWS データベースの選択基準
AWS でデータベースを選ぶとき、最もよく突き当たる分かれ道が DynamoDB と RDS です。結論を先に書くと、アクセスパターンが数種類に固定される大量・変動トラフィックのワークロードは DynamoDB、結合と集計、アドホックなクエリが必要な業務データは RDS です。 どちらが良いデータベースかという問題ではなく、クエリを今知っているのか、後で決めるのかという問題です。RDS 側の詳細な選択(インスタンスクラス、Aurora にするか)は RDS インスタンスクラスと Aurora vs RDS で扱いました。料金は us-east-1 基準です。
ひと目でわかる比較 #
| 区分 | DynamoDB | RDS |
|---|---|---|
| データモデル | キーバリュー・ドキュメント | リレーショナル (MySQL、PostgreSQL など) |
| クエリ | キーベースの照会 + セカンダリインデックス | SQL (結合、集計、アドホック) |
| スキーマ | 柔軟 (項目ごとに属性が自由) | 固定 (テーブル定義) |
| スケール | 自動の水平拡張、事実上無制限 | インスタンスサイズ + リードレプリカ |
| 運用 | サーバーレス (インスタンスなし) | インスタンス管理 (パッチは自動化) |
| 課金 | リクエスト単位 + 保存容量 | インスタンス時間 + ストレージ |
| アイドルコスト | 0 に収束 (オンデマンド) | インスタンスが動いている限り発生 |
モデルの違い — クエリをいつ決めるのか #
DynamoDB はアクセスパターンをテーブル設計の時点で固定するデータベースです。パーティションキーで項目を見つけ、ソートキーで範囲を切り、それ以外の照会はセカンダリインデックス(GSI)をあらかじめ作っておく必要があります。その代わりに得られるのがスケールの自由です。トラフィックが 10 倍になっても遅延は 1 桁ミリ秒に保たれ、パーティションは自動で増え、インスタンスという概念自体がないため運用の手間がほとんどかかりません。
RDS はクエリを後から決められるデータベースです。正規化したテーブルにデータを入れておけば、結合、集計、サブクエリでどんな質問でも投げられます。レポート、管理画面、「今月のカテゴリ別売上」のような要求は SQL の領分です。代償はスケールの上限です。書き込みは結局インスタンス 1 台の垂直拡張に頼ることになり、読み取りの分散もレプリカ管理という運用を伴います。
この違いがそのまま実務の判断基準になります。「どんなクエリが来るか、今すべて言えるか?」です。カート、セッション、注文処理、IoT イベントのようにパターンが固定されたワークロードは DynamoDB によく合い、質問が変わり続ける業務データは RDS が合います。
料金 — リクエスト単位 vs 時間単位 #
DynamoDB オンデマンドはリクエスト単位の課金です。書き込み 100 万件あたり約 $0.625、読み取り(強い整合性基準)100 万件あたり約 $0.125 で(2024 年 11 月の 50% 値下げ反映、結果整合性の読み取りはその半分)、保存は GB・月あたり約 $0.25(最初の 25GB 無料)です。トラフィックがなければ料金も 0 に収束し、スパイクが来てもリクエスト数の分だけ払います。予測可能な常時トラフィックなら、プロビジョンドモードとリザーブドキャパシティで単価をさらに下げられます。RI vs Savings Plans で扱ったとおり、この予約は SP ではなく DynamoDB 自体のリザーブドキャパシティです。
RDS はインスタンス時間の課金です。db.t4g.micro が月およそ $12、プロダクションでよく使う db.m8g.large が月およそ $123(シングル AZ)で、ストレージが加わります。トラフィックと無関係にかかる固定費なので、使用率が低い DB ほどリクエストあたりの実質単価は悪くなります。
損益分岐の計算はシンプルです。月のリクエストが数百万件台なら DynamoDB の料金は数ドルで、比較自体が成立しません。月に数十億件、常時高トラフィックの域に達すると、リクエスト課金の総額がインスタンスの固定費を超え始めます。そこがプロビジョンドモードへの切り替えや RDS との再比較のタイミングです。
DynamoDB の落とし穴 — 請求書と設計の両方から来ます #
- GSI は書き込みコストの倍数です: GSI ごとに項目の変更が複製されるため、GSI 3 個のテーブルの書き込み料金はおよそ 4 倍になります。「念のため」に作ったインデックスが請求書を掛け算します。
- スキャンは反則です: テーブル全体のスキャンは読んだ容量すべてに課金され、遅いです。スキャンが定期的に必要になったということは、アクセスパターンの設計が破綻したというシグナルで、RDS や分析スタックへデータを出すタイミングです。
- ホットパーティション: 特定のパーティションキーにトラフィックが集中すると、容量が余っていてもスロットリングがかかります。キー設計が性能設計そのものです。
- トランザクションは 2 倍: トランザクションの読み書きは通常リクエストの 2 倍の課金です。トランザクションが広範囲に必要なドメインなら、そもそもリレーショナルが合っているのではないかをまず見直します。
- RDS 側の落とし穴: 逆に RDS をサーバーレスのスタック(Lambda など)と組み合わせると、コネクションが殺到する問題があり、RDS Proxy のようなレイヤーが追加で必要になります。DynamoDB は HTTP API なのでこの問題がありません。
選択の手順 #
- クエリを今知っているかをまず見ます: アクセスパターンを列挙できるなら DynamoDB が候補、「どんな質問が来るかわからない」なら RDS です。
- 結合・集計・アドホックの要件を確認します: レポートと管理画面が DB に直接つながる必要があるなら RDS で確定です。DynamoDB でこれを真似る設計は、ほとんど後悔で終わります。
- トラフィックパターンを見ます: アイドル時間が長い、またはスパイクの大きいワークロードは、課金構造の上でオンデマンドの DynamoDB が有利です。常時均一の高トラフィックはプロビジョンドモードか RDS と比較します。
- 書き込みコストは GSI 込みで検算します: 項目サイズ × 書き込み数 × (1 + GSI 数) で計算して、初めて実際の請求書に近づきます。
- 併用を検討します: サービス本体の処理(注文、セッション)は DynamoDB、分析・レポートは RDS やウェアハウスに分けてストリームでつなぐ構成が、よくある着地点です。1 つですべてを解く必要はありません。
まとめ #
- アクセスパターンが固定された大量・変動トラフィックは DynamoDB、結合・集計・アドホックなクエリは RDS です。「クエリを今知っているか?」が最初の質問です。
- 課金構造が違います。DynamoDB オンデマンドはリクエスト単位(書き込み 100 万件 約 $0.625)でアイドルコストが 0 に収束し、RDS はインスタンス時間単位なので使用率が低いほど損をします。
- GSI は書き込み料金を倍数にし、スキャンは設計破綻のシグナルです。DynamoDB のコスト検算は GSI 込みが基本です。
- トランザクション中心で質問が変わり続ける業務データを DynamoDB に押し込むのが、最もよくある後悔の道です。逆方向(固定パターンを RDS に)はコストとスケールで損をします。
- サービス本体の処理は DynamoDB、分析はリレーショナルという併用構成がよくある正解です。コミットメント割引は SP ではなく、DynamoDB リザーブドキャパシティ・RDS RI をそれぞれに掛けます。