目次

Amazon DynamoDB 完全ガイド 2026

初心者から実務者向けの包括的解説

Amazon DynamoDB は、任意のスケールで一桁ミリ秒の応答時間を実現する フルマネージド・サーバーレス NoSQL データベース です。スキーマレス設計、自動シャーディング、マルチ AZ 耐久性が特徴で、秒間数十万リクエストのワークロードに対応します。本ドキュメントは、DynamoDB の概念・アーキテクチャ・設計パターン・エコシステム・最新動向を体系的に解説する包括的ガイドです。

ドキュメントの目的

本ガイドは以下を対象としています。

  • 初心者向け: DynamoDB とは何か、なぜ必要かを学びたい方
  • 開発者向け: テーブル設計・キー設計・アクセスパターン定義を実装したい方
  • データアーキテクト向け: Single Table Design / Multi-table Design を検討したい方
  • SRE / インフラ向け: グローバルテーブル・レプリケーション・ディザスタリカバリを構築したい方
  • 意思決定者向け: RDS vs DynamoDB、Cassandra / MongoDB / Cosmos DB との比較・投資判断

2026 年の DynamoDB エコシステム

  • DynamoDB v2 API(プレビュー): パフォーマンス向上、新データ型対応
  • オンデマンドスループット改善: 更な コスト削減、ウォームアップ時間短縮
  • リソースベースポリシー: IAM ロールなしの直接制御
  • Zero-ETL: Redshift / OpenSearch との統合、ノーコード同期
  • Aurora DSQL 登場(2024-2025): 関連クエリが必要な用途への代替案
  • Vector Search(プレビュー): ベクトル埋め込みの直接保存・検索
  • PartiQL オプション: SQL ライク構文での簡易クエリ

定義

AWS 公式による定義:

“Amazon DynamoDB is a fully managed, serverless, key-value NoSQL database designed in the cloud for modern web apps.”

特徴:

  • フルマネージド: インフラ管理不要、AWS が可用性・耐久性を保証
  • サーバーレス: インスタンス管理、スケーリング、バックアップが自動
  • ミリ秒レイテンシー: 平均 1-2ms の応答時間
  • 無制限スケール: テーブルサイズ・リクエストスループットの上限なし(パーティション数による)

目次

  1. 概要
  2. DynamoDB が解決する課題
  3. 主な特徴
  4. アーキテクチャ
  5. キー設計(最重要)
  6. セカンダリインデックス
  7. キャパシティモード
  8. 主要ユースケース
  9. データモデリング
  10. DynamoDB Streams と CDC
  11. グローバルテーブル
  12. トランザクション
  13. DAX(DynamoDB Accelerator)
  14. バックアップと復元
  15. エクスポートと統合
  16. 暗号化とセキュリティ
  17. パフォーマンスチューニング
  18. コスト最適化
  19. 他の類似ツールとの比較
  20. クライアント・エコシステム
  21. ベストプラクティス
  22. トラブルシューティング
  23. 2025-2026 最新動向
  24. 学習リソース
  25. 実装例・活用シーン
  26. 導入ロードマップ
  27. 実装チェックリスト
  28. まとめ
  29. 参考文献

概要

初心者向けメモ: DynamoDB は「データベース」と聞くと RDS(MySQL / PostgreSQL)を想像するかもしれませんが、全く異なります。DynamoDB は キーを指定して高速にデータを取る ことに特化した NoSQL DB です。「複雑な JOIN が必要」「複数テーブルの複合条件クエリ」が必要なら RDS を選びます。「秒間数万リクエスト」「スキーマ変更が頻繁」「グローバル配信」なら DynamoDB を選びます。

DynamoDB は、キーバリュー + ドキュメント DB のハイブリッド型で、以下を実現します:

  • 一桁ミリ秒レイテンシー(平均 1-2ms): 世界規模のトラフィックスパイクにも対応
  • スキーマレス設計: 属性の動的追加が可能、テーブル構造の柔軟性
  • 自動スケーリング: トラフィック増減に自動対応、キャパシティプラニング不要
  • マルチ AZ 耐久性: 99.99% の可用性、複数アベイラビリティゾーンへの自動レプリケーション
  • グローバルテーブル: マルチリージョン複製で 99.999% SLA

DynamoDB の位置づけ

【図1】AWS データベーススタックにおける DynamoDB の位置:

graph TD
    Apps[アプリケーション]
    
    Apps -->|複雑SQL JOIN 必要| RDS[RDS/Aurora<br/>リレーショナル]
    Apps -->|JSON ドキュメント| DocDB[DocumentDB<br/>MongoDB互換]
    Apps -->|キーバリュー高速| DDB[DynamoDB<br/>NoSQL]
    Apps -->|グラフ検索| Neptune[Neptune<br/>グラフDB]
    Apps -->|全文検索| OpenSearch[OpenSearch<br/>検索]
    
    RDS -->|複合分析| Redshift[Redshift<br/>DWH]
    DDB -->|リアルタイムログ| Loki["Loki / CloudWatch"]
    DDB -->|ベクトル検索| Bedrock["Bedrock<br/>生成AI"]

DynamoDB が解決する課題

1. RDS のスケールアウト限界

❌ RDS の問題:

  • Read Replica で水平スケール可能だが、Write は PK ノードに集約
  • マスターノード故障時のフェイルオーバーは 30-60 秒のダウンタイム発生
  • 秒間 10 万リクエスト規模になると、シャーディング実装が複雑化

✅ DynamoDB の解決:

  • 自動パーティショニング、秒間 100 万リクエスト対応可能
  • Read / Write 分離不要、全リージョンでマルチアクティブ読み書き
  • キャパシティ設定のみで、オペレーション管理ゼロ

2. 運用管理コストの削減

❌ 自作 Cassandra / MongoDB の問題:

  • クラスタ管理、バージョン更新、パッチ適用が自社責任
  • ディスク容量管理、レプリケーション監視
  • 障害時の復旧手順が複雑

✅ DynamoDB のメリット:

  • AWS が 99.99% 可用性を保証
  • 自動バックアップ(PITR 35 日)、自動フェイルオーバー
  • CloudTrail / CloudWatch で監視・ロギング自動

3. グローバルサービス対応

❌ シングルリージョン DB の問題:

  • 東京リージョンのユーザーは OK だが、NY・シドニーユーザーは遅延大
  • マルチリージョンレプリケーション実装が複雑

✅ DynamoDB グローバルテーブルの利点:

  • 複数リージョンでの読み書き可能、低レイテンシーローカルアクセス
  • リージョン間自動複製、地域障害時の自動フェイルオーバー
  • 99.999% SLA(最高レベルの可用性)

4. スキーマ変更の柔軟性

❌ RDS のスキーマ固定性:

  • 新しいカラム追加には ALTER TABLE + ロック
  • 大規模テーブルでは数時間のダウンタイム発生

✅ DynamoDB のスキーマレス性:

  • 新しい属性は任意に追加可能、既存データに影響なし
  • 属性追加に伴う速度低下なし

主な特徴

特徴 説明
一桁ミリ秒レイテンシー 平均 1-2ms の応答時間、P99 も 10ms 以下
スキーマレス テーブル作成後に属性追加可、JSON ネスト可
自動シャーディング パーティションキー分散で自動スケール
マルチ AZ 耐久性 99.9999999999%(12 個の 9)のデータ耐久性
グローバルテーブル 複数リージョンでの読み書き、99.999% SLA
オンデマンドスケーリング トラフィックに自動対応、キャパシティプラニング不要
TTL 管理 期限切れレコードの自動削除
DynamoDB Streams 変更ログを 24 時間保持、イベント駆動アーキテクチャ対応
Transactions ACID トランザクション、複数アイテム更新
DAX キャッシュ マイクロ秒レイテンシー(ミリ秒から 10 倍高速化)

アーキテクチャ

初心者向けメモ: DynamoDB のアーキテクチャは 4 層に分かれます。

  1. テーブル層 - ユーザーが作成・管理
  2. パーティション層 - AWS が自動分散(見えない)
  3. レプリケーション層 - 複数 AZ / リージョン自動複製
  4. API 層 - SDK から GetItem / Query / Scan を呼び出し

DynamoDB のデータ構造

【図2】テーブル → パーティション → レプリカの階層構造:

graph TD
    Table["テーブル<br/>(ユーザーが見る視点)"]
    
    Table -->|Partition Key<br/>ハッシュ分散| P1["Partition 1<br/>(user_id: a*)<br/>3,000 RCU<br/>1,000 WCU"]
    Table -->|Partition Key| P2["Partition 2<br/>(user_id: b*)<br/>3,000 RCU<br/>1,000 WCU"]
    Table -->|Partition Key| P3["Partition N<br/>(user_id: z*)<br/>3,000 RCU<br/>1,000 WCU"]
    
    P1 -->|リアルタイム複製| AZ1["AZ1 レプリカ"]
    P1 -->|リアルタイム複製| AZ2["AZ2 レプリカ"]
    P1 -->|リアルタイム複製| AZ3["AZ3 レプリカ"]

主要概念

概念 説明 制約・上限
テーブル 複数アイテムの集合 最大 400 KB/アイテム、無制限テーブルサイズ
アイテム 1 行(レコード)に相当 最大 400 KB
属性 カラムに相当、ネスト可 最大深さ 32
Partition Key(PK) アイテムの一意識別子、ハッシュ値でパーティション決定 必須、最大 2 KB
Sort Key(SK) 同一 PK 内のソート順序、複合主キー構成 省略可、最大 1 KB
Global Secondary Index(GSI) テーブルとは異なる PK/SK を定義可 最大 20 個(増加可能)
Local Secondary Index(LSI) PK は同一、SK のみ変更 テーブル作成時のみ定義、最大 5 個

パーティション設計

DynamoDB は Partition Key のハッシュ値 でデータを複数パーティションに自動分散:

ユーザーID = "user_12345"
  ↓
hash("user_12345") % num_partitions
  ↓ 例:Partition 7
  ↓
Partition 7(3,000 RCU + 1,000 WCU の上限)

各パーティションの上限:

  • Read Capacity Unit(RCU):最大 3,000 / 秒
  • Write Capacity Unit(WCU):最大 1,000 / 秒

ホットパーティション(特定 PK への集中)を避けるキー設計が重要。


キー設計(最重要)

初心者向けメモ: DynamoDB の性能・コストは 90% キー設計 で決まります。RDS のように「後で JOIN で対応」はできません。設計段階でアクセスパターンを明確にし、それに合わせてキーを決めることが必須です。

主キー戦略

1. シンプルな主キー(PK のみ)

テーブル: Users
├── PK: user_id
├── Attributes: name, email, created_at, ...

用途: ユーザーマスターデータ、シングルアクセス

クエリ例:

GetItem(user_id = "user_123")  → 完全一致検索のみ
Scan で name 検索? → NG(テーブル全読み、コスト爆発)

2. 複合主キー(PK + SK)

テーブル: Orders
├── PK: user_id(パーティション分散)
├── SK: order_id(同一ユーザー内でソート)
├── Attributes: amount, status, created_at, ...

用途: 1:N 関係(ユーザー 1 人 → 複数注文)

クエリ例:

GetItem(user_id = "user_123", order_id = "order_456")
  → 完全一致検索

Query(user_id = "user_123")
  → 同一ユーザーの全注文取得

Query(user_id = "user_123", order_id BETWEEN "2024-01" AND "2024-12")
  → ユーザーの特定期間注文のみ取得

アクセスパターン先行設計

ステップ 1:アクセスパターンを列挙

  1. ユーザー ID で注文を全て取得
  2. ステータスが「未配送」の注文のみフィルタ
  3. 注文日時が 2024-01-01 以降の注文
  4. 注文ステータス(“pending”, “shipped”, “delivered”)で検索

ステップ 2:キー設計検討

❌ アンチパターン:
PK: order_id
SK: status
→ 理由:user_id で検索不可

✅ 推奨:
PK: user_id
SK: created_at (ISO 8601 形式)
GSI1_PK: status
GSI1_SK: created_at
→ 理由:PK で user_id 検索、GSI で status 検索 可能

ホットパーティション回避

❌ アンチパターン 1:ステータスを PK にする

  • PK: status (“active”, “inactive” のみ 2 種類)
  • → 問題:全トラフィックが 2 パーティションに集約
  • → パーティションあたり 3,000 RCU / 1,000 WCU 上限に即座に達する

❌ アンチパターン 2:タイムスタンプ PK

  • PK: date (“2026-04-26” など、日単位)
  • → 問題:今日のデータに全トラフィック集約
  • → 過去のパーティションは遊休状態

✅ 推奨:Write Sharding

PK: order_type + "#" + suffix
  例:"order#" + random(0-99)
→ 同じ order_type でも 100 パーティションに分散
→ 秒間 3,000 * 100 = 30 万リクエスト対応可能

キー設計パターン表

パターン PK SK 向き
Entity entity_id - マスターデータ user_id
1:N 関係 parent_id child_id ユーザー:注文 user_id + order_id
タイムシリーズ device_id timestamp IoT / ログ sensor_id + unix_time
ステータス管理 resource_id status + created_at 状態遷移 order_id + (status + timestamp)
タグ検索 tag_name resource_id タグベース分類 “important” + task_id
逆ルックアップ email user_id メール → ID GSI 活用

セカンダリインデックス

初心者向けメモ: テーブルの主キーでは「あのアクセスパターン」に対応できない → 「セカンダリインデックス」で追加の視点を作ります。RDB の INDEX と異なり、完全に独立したテーブルに近い構造です。

GSI(Global Secondary Index)

テーブル: Orders
├── PK: user_id, SK: order_id
├── GSI1: PK=status, SK=created_at
│   └─ テーブルと別のパーティション、独立キャパシティ
└── Attributes: amount, shipping_address, ...

特徴:

  • テーブルから独立: 別キャパシティ設定
  • 最大 20 個 (増加リクエスト可)
  • 後から追加可能(オンラインで作成、既存テーブル無停止)
  • 弱整合性 (レプリケーションラグ数百ミリ秒)

用途例:

# テーブルは user_id で検索、GSI は status で検索
Query(status = "pending")  ← GSI 経由
  → "pending" の全注文(user_id 不問)取得

LSI(Local Secondary Index)

テーブル: Orders
├── PK: user_id (同一)
├── SK: order_id
├── LSI1: PK: user_id, SK: amount
│   └─ テーブルと同じパーティション
└── 強整合性クエリ可能

特徴:

  • PK は同一、SK のみ変更
  • テーブル作成時のみ定義 (後から追加不可)
  • 最大 5 個
  • テーブルと容量共有
  • 強整合性 クエリ可能

用途例:

# ユーザーの注文を金額でソート
Query(user_id = "user_123", amount > 10000)  ← LSI 経由、強整合

GSI vs LSI 比較表

GSI LSI
PK 変更 ✅ 可能 ❌ 不可(同一 PK)
SK 変更 ✅ 可能 ✅ 可能
キャパシティ 独立設定 テーブル共有
整合性 弱整合性 強整合性
作成タイミング いつでも テーブル作成時のみ
個数上限 20(増加可) 5
パーティション テーブル分離 テーブル同一
最大アイテムサイズ 10 GB(パーティション内) 10 GB

インデックス設計チェックリスト

✅ アクセスパターンごとに必要なキーを洗い出した ✅ GSI は最大 3-4 個に絞った(キャパシティ管理・コスト削減) ✅ 未使用インデックスは削除した(月 $0.25/GB のストレージ課金) ✅ スパース GSI(一部アイテムのみにキー属性がある)を活用した ✅ GSI SK に使う属性の cardinality は十分か確認した


キャパシティモード

初心者向けメモ: DynamoDB の料金体系は 2 種類。「オンデマンド = 従量課金」「プロビジョンド = 定額 + 予約割引」。本番環境では、アクセスパターンの予測可能性で選択します。スパイク型なら「オンデマンド」、定常なら「プロビジョンド + AutoScaling」が一般的。

オンデマンドモード(On-Demand)

課金 = (読み取り RRU 数) × $0.25/100万 RRU + (書き込み WRU 数) × $1.25/100万 WRU

特徴:

  • 従量課金 - 実際の読み書きのみ課金
  • 自動スケール - 突然の 100 倍トラフィック増でも対応可能
  • 初期キャパシティ不要 - キャパシティプラニングなし

向き:

  • ✅ アクセス量が不予測(スパイク型)
  • ✅ マイナー機能・テスト環境
  • ✅ 新規サービス立ち上げ(トラフィック予測困難)
  • ❌ ベースロードが大きい(50 万 RRU/日 以上)

価格イメージ:

  • 1 日 50 万リクエスト:$125 / 月(オンデマンド)
  • 同じ負荷:プロビジョンド 208 RCU($100/月)→ オンデマンドが高い

プロビジョンドモード(Provisioned)

課金 = 設定 RCU × $0.00013/時間 + 設定 WCU × $0.00065/時間
     + 予約割引(1 年 / 3 年 = 最大 50% 割引)

特徴:

  • 定額課金 - 設定容量に対する固定費
  • 予測可能な負荷向け - 定常的なトラフィック
  • オートスケーリング - Target Utilization に基づき自動調整

向き:

  • ✅ ベースロードが大きく定常的(100 万 RRU/日 以上)
  • ✅ オンデマンドより 50% 以上安い場合
  • ✅ 予約割引で 1 年 / 3 年コミット可能
  • ❌ トラフィック予測困難(スパイク)

オートスケーリング設定例:

ターゲット使用率:70%
最小キャパシティ:100 RCU
最大キャパシティ:10,000 RCU
  ↓
CPU 70% 超過 → キャパシティ自動上昇
CPU 70% 未満 → キャパシティ自動低下(1 分単位)

読み取り / 書き込みキャパシティユニット

RCU(Read Capacity Unit)- 読み取り

操作 アイテムサイズ 消費 RCU(強整合) 消費 RCU(弱整合)
GetItem 4 KB 以下 1 0.5
GetItem 4-8 KB 2 1
Query 4 KB 以下 × 100 件 100 50
Scan 4 KB 以下 × 1000 件 1000 500
TransactGetItem 4 KB 以下 2 1

WCU(Write Capacity Unit)- 書き込み

操作 アイテムサイズ 消費 WCU
PutItem 1 KB 以下 1
PutItem 1-2 KB 2
UpdateItem 1 KB 以下 1
DeleteItem 任意 1
TransactWriteItems 1 KB 以下 2
BatchWriteItem 1 KB 以下 × 25 件 25

計算例:

User テーブル:1 日 100 万 GetItem(4KB 以下)
 → 100 万 GetItem × 1 RCU = 100 万 RCU
 → 秒あたり:100 万 / 86,400 秒 ≈ 11.6 RCU 必要

モード選択フロー

graph TD
    Q1{トラフィック<br/>予測可能?}
    
    Q1 -->|YES| Q2{定常的で<br/>大規模?<br/>100万RRU+}
    Q1 -->|NO| OnDemand["オンデマンド<br/>✅ スパイク対応<br/>✅ 自動スケール"]
    
    Q2 -->|YES| Prov["プロビジョンド<br/>✅ 50%安い<br/>✅ 予約割引対象"]
    Q2 -->|NO| OnDemand2["オンデマンド<br/>✅ 小規模定常"]
    
    Prov -->|+ AutoScaling| ProvAS["プロビジョンド<br/>+ オートスケーリング<br/>✅ 最適解"]

主要ユースケース

初心者向けメモ: DynamoDB は「監視」「ログ」「キャッシュ」など 10+ のユースケースで活躍。ユースケースに合わせた設計パターンが存在します。

1. セッション・認証データ管理

テーブル: Sessions
├── PK: session_id
├── SK: user_id
├── TTL: expires_at (自動削除)
└── Attributes: jwt_token, ip_address, device_type

特徴:

  • ✅ TTL で期限切りセッション自動削除
  • ✅ ミリ秒レイテンシーでログイン高速化
  • ✅ 秒間数万ユーザー同時アクセス対応

コスト削減: TTL 削除に WCU 不要

2. リアルタイムアナリティクス・カウンター

テーブル: PageViews
├── PK: page_id
├── SK: timestamp
├── Attributes: user_count, session_count

特徴:

  • ✅ Atomic Counter(UpdateItem で +1)でアクセス数リアルタイム更新
  • ✅ IAM ロール限定で「匿名ユーザーがカウンター +1」を許可
  • ✅ DAX キャッシュで PV 閲覧を µs レイテンシー化

実装例:

client.update_item(
    TableName='PageViews',
    Key={'page_id': 'index.html', 'timestamp': '2026-04-26'},
    UpdateExpression='ADD views :inc',
    ExpressionAttributeValues={':inc': 1}
)

3. ゲーム - スコア・ランキング・アイテム管理

テーブル: PlayerScores
├── PK: player_id
├── SK: game_session_id
├── GSI: game_id + score (ランキング取得)
└── Attributes: score, level, items_owned, achievements

テーブル: Inventory
├── PK: player_id
├── SK: item_id
└── Attributes: quantity, rarity, equipped

特徴:

  • ✅ 秒間数十万プレイヤーの同時スコア更新
  • ✅ ランキング(Query(game_id, score DESC))高速取得
  • ✅ アイテム所有数の Atomic Counter 更新

ゲーム業界採用事例:

  • AWS Gaming Day(業界カンファレンス)で多数講演
  • モバイルゲーム企業の 70% 以上が DynamoDB 採用

4. IoT・時系列データ

テーブル: SensorReadings
├── PK: device_id
├── SK: timestamp (UNIX タイムスタンプ ISOの方が検索効率 ↑)
├── TTL: timestamp + 7 days (自動期限切れ削除)
└── Attributes: temperature, humidity, pressure, location

特徴:

  • ✅ Write Sharding で秒間数百万センサー読み込み対応
  • ✅ TTL で古いデータ自動削除(ディスク節約)
  • ✅ TimeToLive 機能でストレージコスト自動削減

IoT 企業採用事例:

  • AWS IoT Core との統合
  • AWS Greengrass 連携

5. E コマース - ショッピングカート・注文管理

テーブル: Carts
├── PK: user_id
├── SK: cart_session_id
├── TTL: session_expires_at
└── Attributes: items: [{product_id, quantity, price}], subtotal

テーブル: Orders
├── PK: order_id
├── SK: timestamp
├── GSI: user_id + timestamp (ユーザーの注文履歴)
└── Attributes: items, shipping_address, payment_status

特徴:

  • ✅ ショッピングカートはセッション永続化
  • ✅ ブラウザ購入継続時の復帰高速化
  • ✅ 注文データは GSI で「ユーザーの全注文」クエリ

6. リアルタイムメッセージング・チャット

テーブル: Messages
├── PK: conversation_id
├── SK: timestamp
├── GSI: user_id + timestamp (ユーザーの全会話)
└── Attributes: sender_id, content, media_urls

特徴:

  • ✅ 会話 ID でメッセージ時系列取得
  • ✅ DynamoDB Streams で WebSocket / Pub-Sub トリガー
  • ✅ DAX で頻繁にアクセスされる会話をキャッシュ

7. メタデータ・コンテンツ管理

テーブル: Content
├── PK: content_id
├── SK: version
├── Attributes: title, author, metadata (nested JSON), tags

特徴:

  • ✅ スキーマレスで属性動的追加
  • ✅ ネストされた JSON (List / Map)を直接保存
  • ✅ 複数バージョン管理(SK = version)

8. 推奨システム・人気度ランキング

テーブル: PopularityScores
├── PK: category
├── SK: popularity_score DESC
├── GSI: updated_at + category (最新更新順)
└── Attributes: product_id, views, likes, revenue

特徴:

  • ✅ Query で上位 N 件高速取得
  • ✅ UpdateItem で人気度リアルタイム更新

9. コンプライアンス・監査ログ

テーブル: AuditLog
├── PK: resource_type
├── SK: timestamp
├── Attributes: action, actor_id, target_id, changes, ip_address

特徴:

  • ✅ 改ざん防止:DynamoDB Streams で外部システムへリアルタイムレプリケーション
  • ✅ CloudTrail 連携で管理操作も記録
  • ✅ S3 Export で長期保管

10. SaaS マルチテナント

テーブル: Workspaces
├── PK: tenant_id
├── SK: resource_id
├── Attributes: org_name, members, settings, subscription_tier

テーブル: Invitations
├── PK: tenant_id
├── SK: invitation_code
├── TTL: expires_at
└── Attributes: invitee_email, role

特徴:

  • ✅ 各テナントデータを PK で完全分離
  • ✅ 招待コードは TTL で自動期限切れ
  • ✅ tenant_id がパーティションキー → テナント数に自動スケール

ユースケース適性マトリクス

ユースケース 適性 料金目安(月) 備考
セッション管理 ★★★★★ $50-200 TTL で自動削除
リアルタイム PV ★★★★★ $100-500 Atomic Counter
ゲームランキング ★★★★★ $200-1000 GSI ランキング
IoT タイムシリーズ ★★★★★ $500-2000 Write Sharding 必須
E コマース ★★★★ $300-1500 注文・カート分離
リアルタイムチャット ★★★★ $100-1000 Streams 連携
メタデータ管理 ★★★★ $50-500 スキーマレス活用
推奨エンジン ★★★★ $200-800 Streams → ML Pipeline
監査ログ ★★★ $100-500 S3 Export 併用
SaaS マルチテナント ★★★★ $500-3000 テナントスケーリング

データモデリング

初心者向けメモ: DynamoDB のデータモデリングは RDB と大きく異なります。RDB では「正規化」を重視し、データ冗長を排除します。DynamoDB では「非正規化」を重視し、アクセスパターンに合わせてデータを複製・集約します。これを Single Table Design と呼びます。

Single Table Design(推奨)

複数エンティティを 1 つのテーブルに統合:

テーブル: Orders
├── 行 1: PK=order#123, SK=order_metadata
│       └─ Attributes: status, created_at, total_amount
├── 行 2: PK=order#123, SK=customer#user_456
│       └─ Attributes: name, email, address
├── 行 3: PK=order#123, SK=item#product_789
│       └─ Attributes: quantity, price, sku
└── 行 4: PK=order#123, SK=shipment#tracking_001
        └─ Attributes: carrier, tracking_number, estimated_delivery

メリット:

  • ✅ 1 回の Query で注文 + 顧客 + アイテム + 配送情報を全取得
  • ✅ トランザクション(TransactWriteItems)で一括更新
  • ✅ JOIN 不要で高速(HTTP ラウンドトリップ 1 回)
  • ✅ ソート順序で関連データを自動グループ化

デメリット:

  • ❌ テーブル設計が複雑(アクセスパターン要綿密分析)
  • ❌ データ冗長増加(アイテム数増加 → ストレージ増加)
  • ❌ 複雑なテーブルスキャン不可(Scan は避ける)

Multi-Table Design(代替)

複数テーブルに分散:

テーブル: Orders
├── PK: order_id
├── Attributes: status, created_at, total_amount

テーブル: Customers
├── PK: customer_id
├── Attributes: name, email, address

テーブル: OrderItems
├── PK: order_id
├── SK: item_index
├── Attributes: product_id, quantity, price

メリット:

  • ✅ テーブル設計がシンプル
  • ✅ 学習曲線が緩い
  • ✅ 複数テーブルスキャン可能

デメリット:

  • ❌ HTTP ラウンドトリップ複数回(遅い)
  • ❌ 複数テーブル更新時のトランザクション複雑化
  • ❌ JOIN ロジックをアプリケーション側で実装

比較表

Single Table Design Multi-Table Design
アクセス速度 高速(1 Query) やや低速(複数 Query)
設計の複雑性 高い 低い
ストレージ効率 低い(冗長) 高い(正規化)
トランザクション 簡単 複雑
学習コスト 高い 低い
推奨対象 大規模・高トラフィック 小規模・学習目的

スキーマ設計ベストプラクティス

# ❌ アンチパターン:深いネスト
item = {
    'order_id': '123',
    'customer': {
        'personal': {
            'contact': {
                'email': 'user@example.com'  # 深すぎる
            }
        }
    }
}

# ✅ 推奨:フラットな属性
item = {
    'order_id': '123',
    'customer_email': 'user@example.com',
    'customer_name': 'John Doe'
}

# ✅ または:Map(JSON)活用
item = {
    'order_id': '123',
    'customer': {
        'email': 'user@example.com',
        'name': 'John Doe'
    }
}

DynamoDB Streams と CDC

初心者向けメモ: DynamoDB Streams は「テーブルへの全変更(Insert / Update / Delete)をログとして記録」する機能です。これを Lambda / Kinesis に繋げば、変更に応じたアクションを自動実行できます。これが イベント駆動アーキテクチャ の基盤です。

DynamoDB Streams の仕組み

テーブルへの書き込み
  ↓
DynamoDB Streams(変更ログ、24 時間保持)
  ├─→ AWS Lambda (トリガー)→ 検索インデックス更新 / 通知送信
  ├─→ Kinesis Data Streams (長期保持・分析)
  ├─→ AWS Glue (ETL パイプライン)
  └─→ 他リージョンのテーブル (グローバルテーブル複製に内部利用)

ストリームビュータイプ

ビュータイプ 説明 用途
KEYS_ONLY 変更されたアイテムキーのみ 変更通知のみ必要
NEW_IMAGE 新しい値のみ 新規アイテムをキャッシュに追加
OLD_IMAGE 旧値のみ 変更前後の差分監視
NEW_AND_OLD_IMAGES 新旧両方 変更内容を完全把握(最重い)

Lambda トリガーの実装例

# DynamoDB → Lambda トリガー
def lambda_handler(event, context):
    for record in event['Records']:
        if record['eventName'] == 'INSERT':
            # 新規アイテムを OpenSearch にインデックス化
            item = record['dynamodb']['NewImage']
            index_in_opensearch(item)
        
        elif record['eventName'] == 'MODIFY':
            # 変更後の値を Redshift に同期
            new_item = record['dynamodb']['NewImage']
            sync_to_redshift(new_item)
        
        elif record['eventName'] == 'REMOVE':
            # 削除されたアイテムをキャッシュから削除
            key = record['dynamodb']['Keys']
            remove_from_cache(key)

CDC(Change Data Capture)パターン

graph LR
    DDB["DynamoDB テーブル"]
    Stream["DynamoDB Streams"]
    Lambda["Lambda Function"]
    
    subgraph "下流システム"
        ES["OpenSearch<br/>(全文検索)"]
        Redis["Redis<br/>(キャッシュ)"]
        RDS["RDS<br/>(分析用複製)"]
    end
    
    DDB -->|変更ログ| Stream
    Stream -->|イベント| Lambda
    Lambda -->|インデックス更新| ES
    Lambda -->|キャッシュ更新| Redis
    Lambda -->|同期書き込み| RDS

グローバルテーブル

初心者向けメモ: DynamoDB グローバルテーブルは「複数リージョンで同じテーブルをマルチアクティブ複製」する機能です。東京のユーザーは東京リージョンのテーブルに、NY のユーザーは us-east-1 テーブルに読み書き → 自動複製で最終一貫性を保証。

グローバルテーブルの仕組み

リージョン A(ap-northeast-1)
┌─────────────────────┐
│ テーブル Order      │◄──────────┐
│ (Read/Write)        │           │
└─────────────────────┘           │
      │ ▲                    変更ログ複製
      │ │ DynamoDB Streams   (非同期、100-200ms)
      │ │                    │
      │ └────────────────────┼──────────┐
      │                      │          │
リージョン B(us-east-1)    │      リージョン C(eu-west-1)
┌─────────────────────┐      │  ┌──────────────────┐
│ テーブル Order      │      └─►│ テーブル Order  │
│ (Read/Write)        │         │ (Read/Write)    │
└─────────────────────┘         └──────────────────┘

特徴:

  • ✅ すべてのリージョンで読み書き可能(マルチアクティブ)
  • ✅ 可用性 SLA:99.999%(5 つの 9)
  • ✅ 複製遅延:通常 100-200ms(最終一貫性)
  • ✅ TTL・GSI も自動複製

競合解決戦略

複数リージョンで同時に同じアイテムを更新した場合:

東京リージョン:order_id#123 update → status = "shipped"
  ↑                                           ↑
  └─────────────────────────────────────────┘
                    200ms
  ↑                                           ↑
米国リージョン:order_id#123 update → status = "delivered"

デフォルト:Last Writer Wins(LWW)

  • タイムスタンプが新しい方が勝つ
  • アプリケーション論理が強く統制できる場合に有効

グローバルテーブルの構成

# Terraform で構成
resource "aws_dynamodb_table" "orders_global" {
  name = "orders"
  hash_key = "order_id"
  
  # グローバルテーブル有効化
  stream_specification {
    stream_enabled = true
    stream_view_type = "NEW_AND_OLD_IMAGES"
  }
  
  replica {
    region_name = "us-east-1"
  }
  
  replica {
    region_name = "eu-west-1"
  }
}

グローバル vs シングルリージョン比較

グローバルテーブル シングルリージョン
可用性 SLA 99.999% 99.99%
読み取りレイテンシー ローカル 1-2ms リモート 50-100ms
複製遅延 100-200ms N/A
構成複雑性 高い 低い
月額コスト 複製ストレージ分増加 基本料金のみ
**向き グローバルサービス 単一リージョン

トランザクション

初心者向けメモ: DynamoDB トランザクションは「複数アイテムの原子性更新」を実現します。全て成功 or 全て失敗(All-or-Nothing)。銀行口座振替(A から B への送金)など、一貫性が必須の処理に有効です。

TransactWriteItems(書き込みトランザクション)

import boto3

dynamodb = boto3.client('dynamodb')

response = dynamodb.transact_write_items(
    TransactItems=[
        {
            'Put': {
                'TableName': 'Accounts',
                'Item': {
                    'account_id': {'S': 'savings_123'},
                    'balance': {'N': '900'}  # 100 減少
                },
                'ConditionExpression': 'attribute_exists(account_id)'
            }
        },
        {
            'Put': {
                'TableName': 'Accounts',
                'Item': {
                    'account_id': {'S': 'checking_456'},
                    'balance': {'N': '1100'}  # 100 増加
                },
                'ConditionExpression': 'attribute_exists(account_id)'
            }
        }
    ]
)

特徴:

  • ✅ Put / Update / Delete / ConditionCheck を組み合わせ可
  • ✅ 最大 100 アイテムまたは 4 MB の制限
  • ✅ 同一リージョン内のみ(グローバルテーブル間不可)
  • ✅ WCU を 2 倍消費(通常 1 WCU = 1 KB,トランザクション = 2 WCU)

TransactGetItems(読み取りトランザクション)

response = dynamodb.transact_get_items(
    TransactItems=[
        {
            'Get': {
                'TableName': 'Accounts',
                'Key': {'account_id': {'S': 'savings_123'}}
            }
        },
        {
            'Get': {
                'TableName': 'Accounts',
                'Key': {'account_id': {'S': 'checking_456'}}
            }
        }
    ]
)

# 両方のアカウントが一貫した状態で読み込まれることを保証
accounts = response['Responses']

特徴:

  • ✅ 複数アイテムの一貫性読み込み
  • ✅ RCU を 2 倍消費(強整合)

条件付き更新(ConditionCheck)

# トランザクション内で条件を検証
{
    'Update': {
        'TableName': 'Orders',
        'Key': {'order_id': {'S': 'order_123'}},
        'UpdateExpression': 'SET #status = :new_status',
        'ConditionExpression': '#status = :old_status',  # 現在のステータス確認
        'ExpressionAttributeNames': {'#status': 'status'},
        'ExpressionAttributeValues': {
            ':new_status': {'S': 'shipped'},
            ':old_status': {'S': 'pending'}
        }
    }
}

DAX(DynamoDB Accelerator)

初心者向けメモ: DynamoDB のレイテンシーはすでに 1-2ms と高速ですが、「マイクロ秒」レベルが必要な場合(ゲーム内高頻度読み取り、リアルタイムビッド)は DAX を使います。インメモリキャッシュで 10 倍高速化します。

DAX の動作

アプリケーション
  │
  │ キャッシュあり?
  ▼
[DAX クラスター]
  ├─ ヒット:µs 単位で返却
  └─ ミス:DynamoDB へ問い合わせ → キャッシュに保存
  │
  ▼
DynamoDB テーブル

特徴:

  • ✅ レイテンシー:ミリ秒 → マイクロ秒(10-100 倍高速化)
  • ✅ 読み取りキャッシュ(デフォルト)
  • ✅ Write-through キャッシュ(書き込みも DAX 経由)
  • ✅ TTL で期限切りエントリ自動削除
  • ✅ VPC 内デプロイ(パブリックアクセス不可)

DAX クラスター構成

最小構成:1 ノード(テスト)
推奨構成:3 ノード(マルチ AZ)
最大構成:11 ノード(高可用性)

ノードサイズ:
├─ dax.r4.large (26 GB、$0.316/時間)
├─ dax.r4.xlarge (52 GB、$0.632/時間)
└─ dax.r4.2xlarge (104 GB、$1.265/時間)

月額コスト試算

DAX 3 ノード(dax.r4.large):
  = $0.316/時間 × 3 ノード × 730 時間(月)
  ≈ $692 / 月

DynamoDB 読み取り削減効果:
  キャッシュヒット率 90% の場合、RCU 90% 削減
  1,000 RCU × $0.00013/時間 × 730 時間 × 90% = $85 / 月削減

結論:DAX コスト > 削減額 → ハイトラフィック用途でのみ採算

DAX を使うべき用途

✅ ゲーム内ランキング(読み取り集中) ✅ リアルタイムビッディング ✅ 広告配信ターゲティング(頻繁な参照) ✅ キャッシュミス後の MISS 処理が遅い場合

❌ 書き込み主体のワークロード ❌ データ鮮度が重要(リアルタイム要求) ❌ キャッシュ一貫性が複雑


バックアップと復元

初心者向けメモ: DynamoDB はマネージドサービスなので自動バックアップが有効。PITR(Point-in-Time Recovery)で過去 35 日間の任意の時点に復元可能。削除したデータ復旧も簡単。

PITR(Point-in-Time Recovery)

特徴:

  • ✅ 自動有効化(デフォルト ON)
  • ✅ 35 日間の履歴保持
  • ✅ 秒単位で復元時点指定可
  • ✅ 新規テーブルとして復元(既存テーブル上書きなし)

用途:

  • 誤削除データの復旧
  • ランサムウェア対策(一定期間前の状態に戻す)
  • テーブルスキーマリセット

復元例:

# AWS CLI で 24 時間前に復元
aws dynamodb restore-table-to-point-in-time \
  --source-table-name Orders \
  --target-table-name Orders-restored \
  --restore-date-time 2026-04-25T10:00:00Z

オンデマンドバックアップ

特徴:

  • ✅ 手動作成・スケジューリング
  • ✅ テーブル容量に関係なく瞬時完了
  • ✅ 無期限保持(削除まで)
  • ✅ 月あたり 1 テーブル 1 個は無料

用途:

  • 大型リリース前の事前バックアップ
  • 外部コンプライアンス要件対応(監査証跡)
  • 長期アーカイブ

バックアップストレージ料金

PITR:無料(テーブルストレージと同額)
オンデマンドバックアップ:$0.10/GB/月

例)500 GB テーブルの 7 世代バックアップ保持:
  = 500 GB × 7 × $0.10 = $350 / 月

エクスポートと統合

初心者向けメモ: DynamoDB のデータを S3 にエクスポート → Athena / Redshift / OpenSearch で分析。これが「Zero-ETL」フロー。Lambda / Glue 不要で完全にノーコード。

S3 エクスポート

DynamoDB テーブル
  │
  ▼(ParquetまたはJSON形式)
S3 バケット(テーブル内容をスナップショット)
  │
  ├─→ Athena(SQL クエリ)
  ├─→ Redshift(DWH に一括ロード)
  ├─→ OpenSearch(フルテキスト検索)
  ├─→ QuickSight(BI ダッシュボード)
  └─→ SageMaker(機械学習)

特徴:

  • ✅ テーブル無停止でエクスポート
  • ✅ Parquet 形式で高圧縮(ストレージ 80% 削減)
  • ✅ 指定時点のスナップショット(PITR と連携可)

Athena で即座に分析:

-- S3 内の Parquet ファイルに SQL クエリ
SELECT user_id, COUNT(*) as order_count
FROM s3://my-bucket/exports/orders/
WHERE created_at > '2026-04-01'
GROUP BY user_id
ORDER BY order_count DESC;

Redshift Zero-ETL

# DynamoDB → Redshift(完全自動複製)
aws dynamodb create-replica(
  TableName: Orders,
  ReplicaArn: arn:aws:redshift:...
)
 リアルタイムで Redshift に複製
  複雑な JOIN / 集計可能

OpenSearch Zero-ETL

DynamoDB テーブル
  │ Streams トリガー
  ▼
Lambda Function
  │(インデックスリクエスト)
  ▼
OpenSearch ドメイン
  │(全文検索インデックス)
  ▼
Kibana ダッシュボード

暗号化とセキュリティ

初心者向けメモ: DynamoDB は保存時・転送時・アクセス制御の 3 層でセキュリティを確保。デフォルトでも AWS 所有キー(AES256)で暗号化されていますが、本番環境では KMS カスタマーマネージドキーを使用。

保存時暗号化(Encryption at Rest)

キー管理方式 説明 コスト
AWS 所有キー AWS が完全管理、デフォルト 無料
AWS マネージドキー テーブルごとに自動キー作成 無料
カスタマーマネージドキー(KMS) 顧客が作成・管理、監査ログ有 $1/月 + API 呼び出し

推奨:KMS カスタマーマネージドキー

# KMS キー作成
aws kms create-key --description "DynamoDB encryption key"

# DynamoDB テーブルで KMS キー指定
aws dynamodb create-table \
  --table-name Orders \
  --key-schema AttributeName=order_id,KeyType=HASH \
  --sse-specification Enabled=true,SSEType=KMS,KMSMasterKeyId=arn:aws:kms:...

転送時暗号化(Encryption in Transit)

  • ✅ HTTPS/TLS 1.2 以上は必須
  • ✅ VPC Endpoint 経由でプライベートアクセス(InternetGateway 不要)

VPC Endpoint 構成例:

アプリケーション(EC2 / Lambda)
  │(プライベート)
  ▼
[VPC Endpoint]
  │(AWS 内部ネットワーク)
  ▼
DynamoDB

IAM アクセス制御

細粒度権限:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:GetItem",
        "dynamodb:Query"
      ],
      "Resource": "arn:aws:dynamodb:ap-northeast-1:123456789:table/Orders",
      "Condition": {
        "StringEquals": {
          "aws:PrincipalOrgID": "o-1234567890"
        }
      }
    }
  ]
}

操作単位の制御:

  • dynamodb:GetItem - 単一アイテム読み取り
  • dynamodb:Query - 範囲検索
  • dynamodb:Scan - テーブル全読み(制限推奨)
  • dynamodb:PutItem - 書き込み
  • dynamodb:UpdateItem - 更新
  • dynamodb:DeleteItem - 削除

リソースベースポリシー(2024-2025 新機能)

IAM ロール不要でテーブルへの直接制御:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789:role/AppRole"
      },
      "Action": "dynamodb:GetItem",
      "Resource": "arn:aws:dynamodb:ap-northeast-1:123456789:table/Orders"
    }
  ]
}

パフォーマンスチューニング

ホットパーティション対策

❌ 問題パターン:

  • PK: status (“active” のみ)
  • → 全リクエストが 1 パーティションに集約
  • → 3,000 RCU / 1,000 WCU 上限に即座に抵触

✅ Write Sharding 対策:

# PK にランダムサフィックスを追加
import random

user_id = "user_123"
shard_id = random.randint(0, 99)
pk = f"{user_id}#{shard_id:02d}"

# → user_123#00, user_123#01, ... user_123#99
# → 100 パーティションに分散 → 秒間 100 万リクエスト対応可能

Adaptive Capacity

DynamoDB が自動的にホットパーティションに一時的に追加容量を割り当て(最大 4 時間)。

  • ✅ プロビジョンドモード + AutoScaling の場合のみ有効
  • ✅ スケーリング時間を稼ぐ緊急対策(根本解決ではない)

Scan vs Query

操作 用途 コスト効率
GetItem PK + SK で単一アイテム取得 最安
Query PK で複数アイテム取得(SK 範囲指定可)
Scan テーブル全体読み取り 高(避けるべき)

Scan 回避パターン:

# ❌ 悪い例
response = dynamodb.scan(
    TableName='Orders',
    FilterExpression='#status = :status',
    ExpressionAttributeNames={'#status': 'status'},
    ExpressionAttributeValues={':status': 'pending'}
)

# ✅ 良い例:GSI で Query に変更
response = dynamodb.query(
    TableName='Orders',
    IndexName='status-created_at-index',
    KeyConditionExpression='#status = :status',
    ExpressionAttributeNames={'#status': 'status'},
    ExpressionAttributeValues={':status': 'pending'}
)

バッチ操作

# ネットワークラウンドトリップ削減
response = dynamodb.batch_get_item(
    RequestItems={
        'Orders': {
            'Keys': [
                {'order_id': {'S': 'order_1'}},
                {'order_id': {'S': 'order_2'}},
                # ... 最大 100 件
            ]
        }
    }
)

コスト最適化

初心者向けメモ: DynamoDB のコストは「読み取り」「書き込み」「ストレージ」「通信」の 4 要素で構成。各要素を最適化するチェックリストを整備。

コスト構成

月額 DynamoDB 料金
├─ 読み取り容量料金(RCU):30-40%
├─ 書き込み容量料金(WCU):30-40%
├─ ストレージ料金:5-10%
├─ データ転送料金:5-10%
└─ その他(Streams / Backups):5-10%

最適化施策

1. キャパシティモード最適化

施策 削減率
オンデマンド → プロビジョンド(安定負荷) -40-70%
プロビジョンド + 予約割引(1 年) -30-40%
プロビジョンド + 予約割引(3 年) -50-60%

2. TTL 活用

  • TTL で期限切れレコード自動削除
  • → 削除に WCU 不要、ストレージ自動削減
  • → 月 $500 削減(例:セッションデータ 100GB)

3. テーブルクラス最適化

クラス ストレージ料金 読み書き料金 向き
Standard $0.25/GB 標準料金 ホットデータ
Standard-IA $0.10/GB(60% 削減) 1.25 倍 コールドデータ(アクセス低頻度)

4. GSI 最適化

未使用 GSI は月 $0.25/GB のストレージ課金
→ 不要 GSI は即座削除

例:500GB テーブル × 3 未使用 GSI
  = 500GB × 3 × $0.25 = $375 / 月 削減可能

5. 圧縮・属性削減

# ❌ 冗長なデータ保存
item = {
    'order_id': '123',
    'user_full_name': 'John Michael Smith',  # 25 バイト
    'user_email': 'john.michael.smith@example.com',  # 35 バイト
    'long_description': '...' * 10000  # 大容量テキスト
}

# ✅ 最適化
item = {
    'order_id': '123',
    'user_id': '456',  # ID 参照に変更
    # 説明文は S3 に保存、URL のみ参照
    'description_url': 's3://bucket/orders/123/desc.txt'
}

月額削減シミュレーション

現在の構成:
├─ オンデマンドモード(100 万 RRU / 日)
├─ RCU 料金:$0.25/100 万 = $75 / 日 = $2,250 / 月
├─ GSI 3 個(各 500 GB ストレージ):$375 / 月
└─ 合計:$2,625 / 月

最適化後:
├─ プロビジョンド 400 RCU(1 年予約):$36 / 月
├─ GSI を 1 個に削減:$125 / 月
├─ TTL で古いデータ削除 → ストレージ 60% 削減
└─ 合計:$200 / 月

削減額:$2,625 - $200 = $2,425 / 月(92% 削減!)

他の類似ツールとの比較

初心者向けメモ: NoSQL DB は多種多様。DynamoDB との違いを理解して選択基準を明確にします。

主要 NoSQL DB 比較表

項目 DynamoDB Cassandra MongoDB Cosmos DB Firestore Aurora DSQL(新)
管理形式 マネージド セルフホスト マネージド マネージド マネージド マネージド
レイテンシー 1-2ms 5-10ms 5-20ms 10-20ms 5-100ms 1-5ms(関連クエリ)
スケール 無制限(パーティション分散) 無制限(クラスタリング) 制限あり 無制限 制限あり 無制限
JOIN ❌ 不可 ❌ 不可 ⚠️ 限定的 ⚠️ 限定的 ❌ 不可 ✅ 可能
ACID トランザクション ✅ 複数アイテム
スキーマレス ⚠️(スキーマ型も)
グローバル分散 ✅ マルチリージョン ✅ マルチノード ⚠️ ⚠️(開発中)
運用負荷 最小 高い 低い 低い 最小 低い
コスト(初期)
学習曲線 急(設計困難) 緩い 緩い 緩い

選択フロー

graph TD
    Q1{複雑な<br/>JOIN 必要?}
    
    Q1 -->|YES| Aurora["Aurora(RDS)<br/>✅ ACID<br/>✅ JOIN"]
    Q1 -->|NO| Q2{スケール<br/>100万req/s?}
    
    Q2 -->|YES| Q3{運用<br/>自社担当可?}
    Q2 -->|NO| MongoDB["MongoDB<br/>✅ スキーマレス<br/>✅ 小規模"]
    
    Q3 -->|YES| Cassandra["Cassandra<br/>✅ 大規模<br/>❌ 運用負荷高"]
    Q3 -->|NO| DynamoDB["DynamoDB<br/>✅ マネージド<br/>✅ スケール"]
    
    Q1 -->|MAYBE| DSQL["Aurora DSQL<br/>✅ 関連クエリ<br/>✅ 新型DB"]

クライアント・エコシステム

AWS SDK

言語 SDK 名 評価
Python Boto3 ★★★★★(最も利用)
JavaScript/Node.js AWS SDK for JS ★★★★★
Java AWS SDK for Java ★★★★★
Go AWS SDK for Go ★★★★
C#/.NET AWS SDK for .NET ★★★★

ORM・ドライバ

ツール 用途 評価
DynamoDB DocumentClient 高レベル API ★★★★
PynamoDB Python ORM ★★★★
dynamoose Node.js ORM ★★★
PartiQL SQL ライク構文 ★★★(標準化進行中)

開発補助ツール

ツール 用途 特徴
NoSQL Workbench GUI 設計・テスト テーブル設計可視化
DynamoDB Local ローカル開発 Docker コンテナ
AWS SAM IaC / デプロイ CloudFormation 上位互換
Terraform インフラストラクチャコード マルチクラウド対応
Serverless Framework Lambda + DynamoDB IaC + デプロイ統合

ベストプラクティス

テーブル設計

設計チェックリスト

  • [ ] アクセスパターンを 3 つ以上洗い出した
  • [ ] ホットパーティション対策を実装した(キー cardinality 検証)
  • [ ] GSI は最大 3-4 個に絞った
  • [ ] TTL で古いデータ自動削除を設定
  • [ ] ネストは 2 層以下に抑えた
  • [ ] 400 KB アイテムサイズ上限を考慮

パフォーマンス

パフォーマンスチェックリスト

  • [ ] Scan は使わない(Query + GSI に変更)
  • [ ] バッチ操作で HTTP ラウンドトリップを削減
  • [ ] DAX キャッシュで読み取り集約化(必要な場合)
  • [ ] CloudWatch メトリクスで ConsumedCapacity 監視
  • [ ] アダプティブキャパシティでホットパーティションを検出

セキュリティ

セキュリティチェックリスト

  • [ ] KMS カスタマーマネージドキーで暗号化
  • [ ] VPC Endpoint でプライベートアクセス
  • [ ] IAM ロールで最小権限設定
  • [ ] CloudTrail で API 呼び出しログ
  • [ ] ポイントインタイムリカバリ有効化

コスト最適化

コスト最適化チェックリスト

  • [ ] 定常負荷はプロビジョンドモード + 予約割引検討
  • [ ] オンデマンドはスパイクワークロードのみ
  • [ ] TTL で不要データ自動削除
  • [ ] 未使用 GSI は削除
  • [ ] Standard-IA でコールドデータ移行(月 1 回以下アクセス)
  • [ ] AWS Cost Explorer で月間費用を監視

トラブルシューティング

症状 原因 解決策
スロットリングエラー(Throttling) 容量超過 キャパシティ増加、キー分散化、Write Sharding
遅いQuery インデックス未使用 Explain + Query Plan で索引選択を確認、GSI 追加
高額請求 想定外のキャパシティ使用 CloudWatch Metrics で消費量監視、Scan 回避
トランザクション失敗 条件不一致 ConditionExpression ログ出力、条件式見直し
古いデータ読み取り 弱整合性読み取り ConsistentRead=true に変更(RCU 2 倍消費)

2025-2026 最新動向

1. DynamoDB v2 API(プレビュー)

改善点:

  • パフォーマンス向上(特に大規模スキャン)
  • 新データ型対応(JSON / Decimal 精度向上)
  • ステートフルアプリケーション対応

2. Vector Search(プレビュー)

ベクトル埋め込みを直接保存・検索可能:

# 生成 AI 統合
item = {
    'product_id': '123',
    'description': 'Ultra-lightweight running shoes',
    'embedding': [0.1, 0.2, 0.3, ...]  # 1536 次元
}

# 類似商品検索
results = dynamodb.search_by_vector(
    embedding=query_embedding,
    top_k=10
)

用途:

  • 推奨エンジン(Bedrock + Embedding)
  • 意味検索(Semantic Search)

3. Aurora DSQL 登場(2024-2025)

DynamoDB に JOIN 機能を追加したような新 DB:

選択基準:
├─ JSON + スケール → DynamoDB
├─ JSON + JOIN が必要 → Aurora DSQL(新)
└─ リレーショナル + スケール → Aurora PostgreSQL + read replicas

4. リソースベースポリシー

IAM ロール不要で直接テーブル制御(セキュリティ向上)

5. Zero-ETL Redshift / OpenSearch

DynamoDB → Redshift / OpenSearch へのノーコード同期


学習リソース

公式ドキュメント

オンラインコース

  • AWS Skill Builder:DynamoDB Deep Dive
  • Linux Academy:DynamoDB for Developers
  • Udemy:DynamoDB Complete Guide

設計パターン

コミュニティ

  • AWS Forums(DynamoDB タグ)
  • AWS re:Post
  • Stack Overflow([amazon-dynamodb] タグ)

実装例・活用シーン

例 1:ユーザー認証・セッション管理

import boto3
from datetime import datetime, timedelta
import json

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Sessions')

def create_session(user_id, jwt_token):
    expires_at = int((datetime.now() + timedelta(hours=24)).timestamp())
    
    table.put_item(
        Item={
            'session_id': f"sess_{user_id}_{int(datetime.now().timestamp())}",
            'user_id': user_id,
            'jwt_token': jwt_token,
            'created_at': int(datetime.now().timestamp()),
            'expires_at': expires_at  # TTL で自動削除
        }
    )

def validate_session(session_id):
    response = table.get_item(Key={'session_id': session_id})
    if 'Item' in response:
        return response['Item']['user_id']
    return None

例 2:ゲームランキング

def update_player_score(player_id, game_id, score):
    # Global Secondary Index を使用
    table.update_item(
        Key={'player_id': player_id, 'game_id': game_id},
        UpdateExpression='SET #score = :score, updated_at = :now',
        ExpressionAttributeNames={'#score': 'score'},
        ExpressionAttributeValues={
            ':score': score,
            ':now': int(datetime.now().timestamp())
        }
    )

def get_top_players(game_id, limit=10):
    # GSI で game_id + score でクエリ
    response = table.query(
        IndexName='game_id-score-index',
        KeyConditionExpression='game_id = :game_id',
        ExpressionAttributeValues={':game_id': game_id},
        ScanIndexForward=False,  # 降順(スコア高い順)
        Limit=limit
    )
    return response['Items']

導入ロードマップ

フェーズ 1:学習・設計(2 週間)

Day 1-3:DynamoDB 概念理解
  ├─ テーブル、パーティション、インデックス
  ├─ アクセスパターン分析
  └─ キー設計ワークショップ

Day 4-7:プロトタイプ実装
  ├─ DynamoDB Local で開発環境構築
  ├─ 簡単なテーブル作成・CRUD
  └─ パフォーマンステスト

Day 8-14:設計レビュー・本設計
  ├─ AWS Well-Architected Review
  ├─ セキュリティ・コスト最適化検討
  └─ 本番環境設計書作成

フェーズ 2:開発・テスト(4 週間)

Week 1-2:コア機能実装
  ├─ SDK 統合
  ├─ エラーハンドリング
  └─ 単体テスト

Week 3:統合テスト・パフォーマンステスト
  ├─ 大規模データロード
  ├─ 負荷テスト(k6)
  └─ レイテンシー・スループット検証

Week 4:本番環境準備
  ├─ CloudFormation / Terraform 自動化
  ├─ バックアップ・復旧テスト
  └─ 運用手順書作成

フェーズ 3:本番稼働・最適化(継続)

Week 1:カナリア導入(5% トラフィック)
Week 2:段階的拡大(25%)
Week 3:50% 移行
Week 4:100% 移行完了

その後:
├─ CloudWatch 監視
├─ コスト最適化(月 1 回)
├─ キャパシティプランニング(四半期 1 回)
└─ セキュリティレビュー(半年 1 回)

実装チェックリスト

設計フェーズ

  • [ ] アクセスパターンを最低 5 個以上洗い出した
  • [ ] 各アクセスパターンに対するキー設計を検証
  • [ ] ホットパーティション対策を実装
  • [ ] GSI/LSI の個数と用途を確定
  • [ ] TTL の必要性を検討
  • [ ] 容量予測(読み取り/書き込み)を実施
  • [ ] コスト見積り(オンデマンド vs プロビジョンド)
  • [ ] セキュリティ要件を確認(KMS、VPC Endpoint)
  • [ ] バックアップ・復旧計画を策定
  • [ ] グローバルテーブル要否を判定

実装フェーズ

  • [ ] DynamoDB Local で開発環境構築
  • [ ] SDK(Boto3 / JavaScript 等)を選定
  • [ ] CRUD 操作を実装・テスト
  • [ ] エラーハンドリング(スロットリング、条件失敗)を実装
  • [ ] ロギング・監視(CloudWatch)を設定
  • [ ] 単体テスト・統合テストを作成
  • [ ] 負荷テスト(k6)を実施
  • [ ] パフォーマンスプロファイリング
  • [ ] セキュリティスキャン(IAM ポリシー検証)

運用フェーズ

  • [ ] CloudWatch ダッシュボードを作成
  • [ ] アラート設定(ConsumedCapacity、Throttling)
  • [ ] 定期バックアップを検証
  • [ ] ポイントインタイムリカバリをテスト
  • [ ] コスト分析レポートを月次作成
  • [ ] キャパシティプランニング(容量予測)を実施
  • [ ] セキュリティレビューを実施
  • [ ] ドキュメント更新

まとめ

DynamoDB は 「フルマネージド・スケーラブル・ミリ秒レイテンシー」 を実現する NoSQL DB です。以下の用途で最適:

DynamoDB を選ぶべき場合:

  • 秒間数万~数百万リクエストの大規模トラフィック
  • スキーマ変更が頻繁(スキーマレス設計)
  • グローバルサービス(複数リージョンで読み書き)
  • 運用管理を最小化したい
  • コスト対効果を重視

DynamoDB を避けるべき場合:

  • 複雑な JOIN が必須(→ Aurora / RDS)
  • 関連データの複合クエリが多い(→ RDS)
  • トランザクション ACID が強く必須(→ Aurora DSQL / RDS)
  • データウェアハウス用途(→ Redshift)

キー設計が 90% を占める ため、十分なアクセスパターン分析と反復的な設計見直しが成功のポイント。AWS Well-Architected Framework / Single Table Design パターンの学習をお勧めします。


参考文献


最終更新:2026-04-26