AWS DynamoDBの設計入門|RDSとの使い分けとパーティションキー・GSI設計の実践
DynamoDBとは?RDSとは異なる「NoSQL」の世界
私がAWSを使った開発を始めたとき、最初に戸惑ったのがDynamoDBの設計思想でした。RDS(MySQLやPostgreSQL)に慣れていると、テーブル設計の考え方がまったく違うので混乱します。実際にX投稿ボットのデータ管理やLambdaとの連携でDynamoDBを使ってきた経験をもとに、実践的に解説します。
DynamoDBはAWSのフルマネージドNoSQLデータベースサービスです。スケーラビリティが高く、ミリ秒単位のレスポンスを実現します。サーバーレスアーキテクチャとの親和性が非常に高いのが特徴です。
RDSとDynamoDBの使い分け
どちらを使うべきか迷ったときの判断基準を整理します。
RDSが適しているケース
- 複雑なJOINやトランザクションが必要
- スキーマが固定されており変更が少ない
- レポーティングや集計クエリが多い
- 既存のRDB設計資産がある
DynamoDBが適しているケース
- 大量の読み書きが発生し、スケーリングが必要
- データ構造が柔軟で属性が変わる可能性がある
- LambdaなどのサーバーレスFunctionと組み合わせる
- 特定のキーでのシンプルなCRUD操作が中心
実際の現場では「とりあえずRDS」という選択をする方が多いですが、アクセスパターンが明確でスケーラビリティが必要な場合はDynamoDBのほうが圧倒的にコスト・パフォーマンスが優れます。
DynamoDB設計の核心:パーティションキーとソートキー
DynamoDBの設計でもっとも重要なのがキー設計です。
パーティションキー(Partition Key)
データを分散させるためのキーです。同じパーティションキーを持つデータは同じパーティションに格納されます。アクセスが集中しないよう、カーディナリティ(値の多様性)が高いものを選ぶのが鉄則です。
ソートキー(Sort Key)
パーティションキーと組み合わせて使うオプションのキーです。同じパーティションキー内でデータを並べ替えたり、範囲クエリを実行したりできます。
設計例:ユーザーのアクティビティログを管理する場合
- パーティションキー:userId(ユーザーID)
- ソートキー:timestamp(タイムスタンプ)
この設計により「特定ユーザーの最新ログを時系列で取得」というクエリが効率的に実行できます。
GSI(グローバルセカンダリインデックス)の活用
DynamoDBではパーティションキー以外の属性でも検索したい場面があります。そのときに使うのがGSI(Global Secondary Index)です。
先ほどの例でいうと「特定のステータス(status=’active’)のユーザーを全件取得したい」という要件が出た場合、statusをパーティションキーとするGSIを作成することで対応できます。
講師として見ていると、GSIの設計を後から変更しようとしてコスト爆発が起きるケースがあります。アクセスパターンは設計段階でしっかり洗い出しておくことが重要です。
DynamoDBの料金モデル:オンデマンドvs.プロビジョンド
- オンデマンドモード:アクセス量に応じた従量課金。開発・検証環境や予測が難しいシステムに向く
- プロビジョンドモード:読み書きキャパシティユニット(RCU/WCU)を事前に設定。安定したトラフィックなら安価になる。Auto Scalingと組み合わせることで柔軟性も確保できる
まとめ:アクセスパターンから設計する
DynamoDBの設計はRDSとは逆順です。「どんなクエリを実行するか(アクセスパターン)」を先に決めて、そこからテーブル設計を考えます。この考え方に慣れると、サーバーレスアーキテクチャの設計力が一気に上がります。
パーティションキーの設計:DynamoDB設計の核心
DynamoDBで最も重要な設計要素がパーティションキーです。パーティションキーの選び方でパフォーマンスが大きく変わります。
良いパーティションキーの条件:
- カーディナリティが高い:値の種類が多いほどデータが分散される。ユーザーIDや注文IDなどは適切
- 均一にアクセスされる:特定のパーティションキーだけに集中するとホットパーティション問題が発生する
NG例: ステータス(active/inactive)をパーティションキーにするのは最悪のパターンです。2種類の値にデータが集中し、RCU/WCUがホットパーティションに偏ります。
GSI(グローバルセカンダリインデックス)の活用
DynamoDBはデフォルトではパーティションキー(+ソートキー)でしか検索できません。別の属性で検索したい場合にGSIを使います。
例:ユーザーIDをパーティションキーにしたテーブルで「メールアドレスでユーザーを検索したい」場合、メールアドレスをパーティションキーにしたGSIを追加します。
- GSIの注意点:GSI用の追加RCU/WCUが必要。インデックスのサイズや読み書き頻度を考慮してキャパシティを設定する
- 投影属性:GSIに含める属性を絞る(ALL・KEYS_ONLY・INCLUDE)ことでコストを最適化できる
DynamoDBのキャパシティモード
- プロビジョンドキャパシティ:RCU・WCUを事前に設定する。予測可能なワークロードに向いており、Auto Scalingと組み合わせると効果的
- オンデマンドキャパシティ:使った分だけ課金。突発的なトラフィックにも自動対応するが、プロビジョンドより単価が高い。開発環境やアクセス予測が困難なサービスに適している
私がX投稿ボットのデータ管理でDynamoDBを使ったとき、アクセス量が少なくかつ予測しにくかったためオンデマンドモードを選択しました。コストを抑えながら柔軟に動作させられました。
LambdaとDynamoDBの連携パターン
DynamoDBはLambdaと非常に相性が良く、サーバーレスアーキテクチャの定番構成です。
import boto3
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('MyTable')
# アイテムの書き込み
table.put_item(Item={
'userId': 'user-001',
'createdAt': '2026-04-13T00:00:00Z',
'status': 'active'
})
# パーティションキーで検索
response = table.get_item(Key={'userId': 'user-001'})
item = response.get('Item')
まとめ:DynamoDB設計の3原則
- パーティションキーはカーディナリティが高いものを選ぶ:データが均一に分散される設計が重要
- GSIで検索の柔軟性を確保する:ただしコストへの影響を意識して最小限に留める
- キャパシティモードはワークロードに合わせて選ぶ:本番はプロビジョンド、開発・小規模はオンデマンドが基本
DynamoDBはRDBの感覚で設計すると必ず失敗します。「アクセスパターン(どうやって検索するか)を先に決めてからテーブルを設計する」という考え方がDynamoDB設計の根本です。まずアクセスパターンの洗い出しから始めてみてください。



