シングルテーブル設計
DynamoDB で複数のエンティティを 1 つのテーブルに格納し、効率的なアクセスパターンを実現する設計手法
DynamoDB設計
シングルテーブル設計とは
シングルテーブル設計は、DynamoDB で複数のエンティティ (ユーザー、注文、商品) を 1 つのテーブルに格納し、パーティションキー (PK) とソートキー (SK) の設計でアクセスパターンを最適化する手法である。Rick Houlihan (AWS) が提唱した。
マルチテーブル vs シングルテーブル
| 観点 | マルチテーブル | シングルテーブル |
|---|---|---|
| テーブル数 | エンティティごとに 1 テーブル | 1 テーブル |
| JOIN | 複数テーブルを個別にクエリ | 1 回のクエリで関連データ取得 |
| 管理 | テーブルが増える | 1 テーブルで完結 |
| 設計の難易度 | 低い (RDB 的) | 高い (アクセスパターン駆動) |
設計例: EC サイト
PK | SK | データ
USER#123 | PROFILE | { name: "Alice", email: "..." }
USER#123 | ORDER#001 | { total: 5000, status: "shipped" }
USER#123 | ORDER#002 | { total: 3000, status: "pending" }
ORDER#001 | ITEM#A | { product: "TypeScript本", price: 3000 }
ORDER#001 | ITEM#B | { product: "AWS本", price: 2000 }
アクセスパターン
// ユーザーのプロフィールを取得
await db.get({ Key: { pk: 'USER#123', sk: 'PROFILE' } });
// ユーザーの全注文を取得
await db.query({
KeyConditionExpression: 'pk = :pk AND begins_with(sk, :sk)',
ExpressionAttributeValues: { ':pk': 'USER#123', ':sk': 'ORDER#' },
});
// 注文の全アイテムを取得
await db.query({
KeyConditionExpression: 'pk = :pk AND begins_with(sk, :sk)',
ExpressionAttributeValues: { ':pk': 'ORDER#001', ':sk': 'ITEM#' },
});
GSI (Global Secondary Index)
GSI1PK | GSI1SK | データ
STATUS#shipped | 2026-04-01 | ORDER#001
STATUS#pending | 2026-03-28 | ORDER#002
// ステータスで注文を検索 (GSI)
await db.query({
IndexName: 'GSI1',
KeyConditionExpression: 'GSI1PK = :status',
ExpressionAttributeValues: { ':status': 'STATUS#shipped' },
});
設計の手順
1. アクセスパターンを全て洗い出す
2. PK/SK の設計を決める
3. GSI が必要なパターンを特定
4. テストデータで検証
シングルテーブルが適さないケース
| ケース | 推奨 |
|---|---|
| アクセスパターンが不明確 | マルチテーブル (後から変更しやすい) |
| 小規模プロジェクト | マルチテーブル (シンプル) |
| 複雑な検索が必要 | OpenSearch と併用 |
シングルテーブル設計の関連書籍も参考になる。