RDS か DynamoDB どちらを使うか迷ったので選び方を整理してみた
製造ビジネステクノロジー部の小林です。
最近、データベースを構築するとき、RDS と DynamoDB のどちらにしよう...と少し迷うことがありました。
これまでは「RDS は JOIN が多いとき、DynamoDB は高速に通信したいときに使う」といったざっくりとした理解でしたが、せっかくの機会なので今回は両者の違いと選定基準を改めて整理してみました!
結論
まずは全体像です。RDS 側は Aurora(Aurora Serverless v2 を含む)もまとめて扱っています。
| 観点 | RDS / Aurora | DynamoDB |
|---|---|---|
| SQL | 使える | 使えない(独自 API) |
| JOIN(テーブルの結合) | 得意 | 苦手 |
| 自由な集計・分析 | 得意 | 苦手 |
| アクセスパターン | 後から自由に変えられる | 最初に決めておく必要がある |
| 急激なアクセス増加 | スケールアップに時間がかかることがある | 瞬間的なアクセス急増にも対応できる |
| サーバーレス構成 | 可能(Aurora Serverless v2) | 可能(元々サーバーレス設計) |
| ゼロスケール | 可能(最小 0 ACU に対応) | 可能(オンデマンドなら常時ゼロ) |
| 料金モデル | インスタンス/ACU の稼働時間ベース | リクエスト量 + 保存量ベース |
迷ったときは、次の表を目安にしてください。
| こんなときは… | おすすめ |
|---|---|
| SQL や JOIN を使いたい | RDS / Aurora |
| 後からいろんな角度で集計・分析したい | RDS / Aurora |
| SQL の資産・慣れがある | RDS / Aurora |
| 検索の仕方が最初から決まっている | DynamoDB |
| 極端なアクセス急増に耐えたい | DynamoDB |
これらの表で「なぜそうなるのか」は、後半の「使い分けの判断ポイント」で 1 つずつ掘り下げます。ここでは全体像だけ押さえます。
Amazon RDS とは
Amazon RDS(Relational Database Service)は、リレーショナルデータベースをマネージドで提供するサービスです。表と表の関係を SQL で扱う「RDB」を AWS 上で動かすものです。
対応エンジンは 8 種類です。Aurora(PostgreSQL 互換 / MySQL 互換)、RDS for PostgreSQL、RDS for MySQL、RDS for MariaDB、RDS for SQL Server、RDS for Oracle、RDS for Db2。使い慣れた RDB をそのまま持ち込みやすいのが強みです。
Amazon DynamoDB とは
Amazon DynamoDB は、フルマネージドの NoSQL データベースです。SQL で行を結合するのではなく、「パーティションキー」と「ソートキー」でアイテムを一意に特定して高速に読み書きします。
キーバリュー+ドキュメント型で、1 アイテムに JSON のようなネスト構造を格納できます。ただし 1 アイテムの上限は 400 KB です。
料金モードは、使った分だけ課金される「オンデマンド」と、容量を事前に見積もる「プロビジョンド」の 2 つです。
データモデルの違いを図で見る
両者の違いは図で見ると理解しやすいため、簡単な EC サイト(顧客と注文)を例に、データの持ち方を比べてみます。
RDS では Customer(顧客)と Order(注文)を別々の表に持ち、外部キーで関連付け、注文履歴を出すときに JOIN します。
DynamoDB では、顧客とその注文を「同じパーティションキー(PK)を持つアイテム群」として 1 つのテーブルに同居させます。実際の中身は次のようなイメージです。
| PK(パーティションキー) | SK(ソートキー) | その他の属性 |
|---|---|---|
CUSTOMER#123 |
PROFILE |
name, email |
CUSTOMER#123 |
ORDER#2026-07-20 |
status, total_amount |
CUSTOMER#123 |
ORDER#2026-07-21 |
status, total_amount |
顧客プロフィールも注文履歴も、PK が同じ CUSTOMER#123 の行として並んでいます。JOIN する代わりに、PK = CUSTOMER#123 で 1 回引くだけで、その顧客の情報と注文をまとめて取り出せる、という発想です。
SK(ソートキー)で PROFILE と ORDER#... を区別し、注文を日付順に並べられます。
同じデータを、RDS は正規化して JOIN、DynamoDB は最初からアクセスパターンに沿って寄せておく。この設計思想の違いが、それぞれの得意分野・不得意分野を決定づけています。
使い分けの判断ポイント
判断軸を 8 つに分けて見ていきます。
アクセスパターンが決まっているか
RDS は SQL であとから思いついたクエリにも柔軟に対応できます。任意条件での検索・集計が多い管理画面などに向いています。
一方 DynamoDB は「どのキーで、どの順序で引くか」を先に決めておく必要があります。読み取りが原則としてパーティションキー(+ソートキー)を指定する Query を前提としているためです。キー以外の属性で検索したい場合は、あらかじめセカンダリインデックス(GSI / LSI)を張る必要があります。
しかし LSI はテーブル作成時にしか作れず(GSI は後から追加可能)、「どう引くか」を後から変えるのはコストが高くつきます。DynamoDB がアクセスパターンの固まったサービスに向くのは、この最初の設計が効いてくるためです。
集計・分析のしやすさ
RDS は SUM / COUNT / GROUP BY や JOIN が使えるので、「月別売上」「顧客ごとの平均購入額」のような集計を 1 本の SQL で自由に投げられます。
一方 DynamoDB には SQL 的な集計機能がほぼありません。PartiQL for DynamoDB がサポートする集約関数は SIZE のみで、SUM や GROUP BY は使えません。
読み取りはキー指定の Query かテーブル全走査の Scan が基本で、Scan はデータ量に比例して遅く・高コストになるため日常的な集計には向きません。
DynamoDB で分析したい場合は、S3 へエクスポートして Athena で SQL を投げる、Redshift へ連携するなど、集計は別サービスに寄せるのが定石です。
スケールとトラフィック
RDS はインスタンスを選んで動かすモデルで、想定を超える負荷にはスケールアップやリードレプリカで対応します。
DynamoDB はテーブルサイズに実質的な上限がなく、オンデマンドならリクエスト量に応じて自動でスケールします。SNS でバズって一気に跳ねる、といった急増に強いです。
スキーマの変化
RDS は表ごとにスキーマが決まっており、カラム追加はマイグレーションで対応します。型がしっかりしているぶん、整合性をスキーマ側で担保できます。
DynamoDB はキー以外がスキーマレスに近く、アイテムごとに違う属性・型を持てます。同じ Users テーブルに、次のようなアイテムが共存できます。
{ "userId": "u001", "name": "Alice", "email": "a@example.com" }
{ "userId": "u002", "name": "Bob", "age": 30, "hobbies": ["golf", "camera"] }
{ "userId": "u003", "displayName": "Carol", "profile": { "bio": "hi" } }
RDS なら ALTER TABLE が必要な属性追加も、DynamoDB は「アプリ側で新しい属性を書き込むだけ」で済みます。しかし、属性名や型のゆらぎ(email と mail の混在、age の文字列と数値の混在など)を止めてくれません。
TypeScript の型 + Zod のようなバリデーション、dynamodb-toolbox や ElectroDB などのマッパー層、命名規約でアプリ側の規律を作るのが定番です。
料金の考え方
RDS は「稼働時間 + ストレージ + I/O」の課金で、動いている限り一定額かかります。アクセスがない時間帯でもコストが発生します。
DynamoDB のオンデマンドは「読み書きした分 + ストレージ」の従量課金で、リクエストがゼロならストレージ代だけです。アクセスに波があるサービスと相性が良いです。
サーバーレス構成とゼロスケール
RDS も Aurora Serverless v2 を使えば、負荷に応じて容量(ACU)が自動で増減し、最小 0 ACU まで下げて自動的に一時停止(オートポーズ)できます。使われていない間のコストをほぼゼロに近づけられる一方、停止状態からの復帰には多少のラグがあります。
DynamoDB はもともとサーバーレス設計で、サーバーやインスタンスの管理は不要です。オンデマンドモードなら、リクエストが来ない間はストレージ代だけで済み、常時ゼロスケールに近い状態で運用できます。
トランザクションと整合性
RDS は複数テーブルにまたがるトランザクション・外部キー・厳密な整合性が自然に使えます。「お金」「在庫と注文」のような処理は RDS の得意分野です。
DynamoDB もトランザクション(TransactWriteItems / TransactGetItems)を使えますが、扱えるアイテム数などに独自の制約があります。トランザクションを多用する前提なら RDS が楽です。
運用の手間
RDS はマネージドとはいえ、インスタンス選定・Multi-AZ・パラメータグループ・パッチ適用・リードレプリカなど、データベースを運用する意識が必要です
DynamoDB はテーブルを作ればほぼ運用不要です。バックアップ・暗号化・高可用性は最初から有効かワンクリック。
どちらを選ぶかのフローチャート
ここまでの判断ポイントを、目安としてフローチャートにまとめます。
具体的なユースケース例
RDS が向くケースです。
- 任意条件の検索・集計が多い画面
- 会計・在庫・予約のように厳密なトランザクションが必要
- 既存のオンプレ RDB を設計そのままで移行したい
- BI ツール(QuickSight や Tableau など)から SQL で直接分析したい
DynamoDB が向くケースです。
- ユーザーデータやセッションを低レイテンシで大量に読み書き(例:ゲーム)
- IoT デバイスからの時系列データを高スループットで受け止める
- API Gateway + Lambda のサーバーレス構成で DB もマネージドに寄せる
- トラフィックが読めないキャンペーン系サービスを余裕を持って捌く
どちらか一方に決めきる必要はなく、ユーザーマスタは RDS、リアルタイム性が要るログや通知は DynamoDB、といったハイブリッド構成も一般的です。
まとめ
RDS と DynamoDB の使い分けをまとめてみました。調べる前は「JOIN するなら RDS、とにかく速くしたいなら DynamoDB」くらいの理解でしたが、実際は優劣ではなく設計思想が違い、得意なことも別物でした。
また、片方に決めきる必要もなく、ユーザーマスタは RDS、リアルタイム性が要る部分は DynamoDB、とハイブリッドに組み合わせることで、より効率的なアーキテクチャにできそうです。
この記事がどなたかの参考になれば幸いです!







