Amazon DynamoDB入門|RDB経験者がつまずくNoSQL設計とテーブル構造・料金を徹底解説

Aws Basics

AWSを触り始めたとき、EC2やS3はなんとなく使えた。ところがDynamoDBを触った途端に、「どうやって検索するんだ?」「JOINができない?」「インデックスの設計がRDBと全然違う」と壁にぶつかった方は多いはずです。

長年MySQLやOracleで設計してきたエンジニアほど、この壁で余計に時間を取られます。NoSQLはRDBの「劣化版」ではなく、全く別の設計思想で作られたデータベースです。

この記事では、オンプレ・クラウド問わずRDBを主に使ってきたインフラエンジニアを対象に、Amazon DynamoDBの基本概念とテーブル設計の考え方、マネジメントコンソールでの操作手順、料金の仕組み、そして実務で踏みやすい落とし穴を解説します。

Amazon DynamoDB入門|RDB経験者がつまずくNoSQL設計とテーブル構造・料金を徹底解説

なぜDynamoDBなのか?RDBとの根本的な違い

オンプレのシステムでは、MySQLやPostgreSQL、Oracle DatabaseといったRDBが主流です。正規化されたテーブル設計、外部キー、JOIN、ACID準拠のトランザクション——これらはRDBの強みです。

では、なぜDynamoDBのようなNoSQLデータベースがクラウドで広く使われているのか。理由は主に2つあります。

スケールの問題: RDBは垂直スケール(サーバーを強化する)が基本です。DynamoDBは水平スケールが前提で設計されており、データ量とリクエスト数が増えてもスループットを自動的に分散できます。
運用コストの削減: DynamoDBはフルマネージドサービスです。パッチ適用、レプリケーション、バックアップはすべてAWSが管理します。DBエンジニアの運用工数を大幅に削減できます。

ただし、DynamoDBはRDBを「置き換える」ものではありません。用途に合わせた使い分けが重要です。

観点 DynamoDB(NoSQL) MySQL等(RDB)
スキーマ スキーマレス(属性は自由) 固定スキーマ(カラム定義必須)
JOIN 不可(アプリ層で結合) 可能
スケール 水平スケール(自動分散) 垂直スケールが基本
トランザクション 限定的(TransactWrite/Get) ACID完全準拠
クエリ柔軟性 低い(キー設計が全て) 高い(SQL自由記述)
向いているワーク 高速読み書き・大量アクセス 複雑なリレーション・集計処理

EC2上のWebアプリのセッション管理、IoTデバイスのタイムスタンプデータ、ゲームのユーザースコア管理といった「キーによるシンプルな高速アクセス」が必要な場面でDynamoDBは真価を発揮します。逆に複雑な集計や多テーブルJOINが必要なシステムにはRDBが向いています。

DynamoDBの基本概念と用語

RDBの概念と対比しながら説明します。

1. テーブル・アイテム・属性

DynamoDBの用語はRDBの用語と少し異なります。

DynamoDB RDB相当 説明
テーブル(Table) テーブル データの集合体
アイテム(Item) 行(Row) 1つのデータレコード
属性(Attribute) 列(Column) アイテムの各フィールド
プライマリキー 主キー(PRIMARY KEY) アイテムを一意に識別するキー

RDBと大きく異なるのは、アイテムごとに属性の数や種類が違っても構わない点です。スキーマレスなので、あるアイテムには price 属性があり、別のアイテムには price がなくても問題ありません。これはRDBの「NULLをデフォルト値として持つ」とは根本的に違う設計です。

2. パーティションキーとソートキー

DynamoDBのプライマリキーには2種類あります。

パーティションキーのみ(シンプルプライマリキー): 1つの属性でアイテムを一意に識別します。RDBの単一カラム主キーに近いイメージです。
パーティションキー+ソートキー(コンポジットプライマリキー): 2つの属性を組み合わせてアイテムを一意に識別します。同じパーティションキーを持つ複数のアイテムを、ソートキーで並べ替えて管理できます。

例えば「注文テーブル」を設計するとします。

パーティションキー: user_id(ユーザーID)
ソートキー: order_date(注文日時)

この設計にすると、同じユーザーの複数の注文を「時系列順」で効率よく取得できます。

# AWS CLI でDynamoDBに対してQueryを実行する例 # user_id="U001"のアイテムを order_date の昇順で取得 aws dynamodb query \ --table-name Orders \ --key-condition-expression "user_id = :uid" \ --expression-attribute-values '{":uid": {"S": "U001"}}' \ --scan-index-forward true

3. パーティションキー設計の考え方

DynamoDB設計で最も重要なのがパーティションキーの選び方です。パーティションキーはデータの分散先(パーティション)を決定します。特定の値にアクセスが集中すると「ホットパーティション」が発生し、スループットが低下します。

RDBのインデックス設計とは全く異なる発想が必要です。「最もよくアクセスするパターン」を先に決め、それに合わせてキーを設計するのがDynamoDBの正しいアプローチです。

カーディナリティが高い属性を選ぶ: ユーザーIDや注文IDなど、一意に近い値がパーティションキーとして最適です。日付やステータス(active/inactive)のような偏りが生じやすい値は避けます。
アクセスパターンを先に定義する: 「全注文の中からユーザーごとに取得したい」「指定日範囲の注文を取りたい」という要件を先に書き出し、それに合わせてキーを決めます。

テーブルを作成してデータを操作する

AWSマネジメントコンソールを使った操作手順を説明します。

1. テーブルの作成

1. AWSマネジメントコンソールにログインし、検索バーに「DynamoDB」と入力してサービスを開きます。東京リージョン(ap-northeast-1)を選択していることを確認してください。
2. 左メニューまたは画面中央の「テーブルの作成」をクリックします。
3. 以下の項目を入力します。

テーブル名: 任意の名前(例: Orders
パーティションキー: user_id、タイプは「文字列」
ソートキー(任意): order_date、タイプは「文字列」

4. 「テーブル設定」セクションでは、「デフォルト設定」を選択してそのまま進めることを推奨します。学習目的や開発初期は「オンデマンドキャパシティ」に設定すると予期せぬコストが発生しにくいです。
5. 「テーブルの作成」ボタンをクリックすると、数秒でテーブルが作成されます。

オンプレのMySQLなら CREATE TABLE 文を書く場面ですが、DynamoDBではコンソールのウィザードで完結します。カラム定義(パーティションキー・ソートキー以外の属性)は不要です。

2. アイテムの追加

テーブルが作成されたら、左メニューの「テーブル」からテーブルを選択し、「テーブルアイテムの探索」→「アイテムの作成」をクリックします。

コンソールのJSONエディタで以下のように入力します。

{ "user_id": {"S": "U001"}, "order_date": {"S": "2026-04-30T10:00:00"}, "product_name": {"S": "クラウド設計入門書"}, "amount": {"N": "3800"}, "status": {"S": "completed"} }

RDBのINSERT文に相当します。amountstatus といったキー以外の属性は、このアイテムにだけ存在しても問題ありません。属性の型(S=文字列、N=数値、B=バイナリ)を明示する点がRDBのCREATE TABLE定義と異なります。

3. データの検索(QueryとScan)

DynamoDBのデータ取得には主に2つの方法があります。

Query(クエリ): パーティションキーを指定して取得します。高速で効率的なアクセス方法です。本番環境では原則Queryを使います。
Scan(スキャン): テーブル全体を読み込んで条件に一致するアイテムを返します。開発時のデバッグには使えますが、データ量が増えるほど遅くなりコストも増加します。本番ではなるべく避けます。

RDBで言えば、QueryはインデックスありのWHERE句、ScanはフルテーブルスキャンのSELECTに近いイメージです。

# AWS CLI でScanを実行する例(開発・検証用) # statusが"completed"のアイテムを全件取得(本番では非推奨) aws dynamodb scan \ --table-name Orders \ --filter-expression "#s = :status" \ --expression-attribute-names '{"#s": "status"}' \ --expression-attribute-values '{":status": {"S": "completed"}}'

料金の仕組みとコスト管理

DynamoDBの料金は「どれだけ読み書きしたか」と「どれだけデータを保存しているか」で決まります(2026年4月時点)。

キャパシティモードの選択

オンデマンドモード: リクエスト数に応じた従量課金です。アクセス量が予測しにくいシステムや開発初期段階に向いています。
プロビジョンドモード: 読み書き能力(RCU/WCU)を事前に設定します。予測可能なワークロードでは割安になります。AutoScalingと組み合わせると自動で上下させることもできます。

モード・項目 料金単価(東京リージョン・ap-northeast-1) 向いているケース
オンデマンド読み取り $0.285 / 100万RRU(2026年4月時点) アクセス量が変動しやすい
オンデマンド書き込み $1.4269 / 100万WRU(2026年4月時点) 開発・テスト環境
プロビジョンド読み取り $0.0065 / RCU(時間)(2026年4月時点) アクセス量が安定している
プロビジョンド書き込み $0.0065 / WCU(時間)(2026年4月時点) 大量書き込みが定常的にある
ストレージ $0.285 / GB(月)(2026年4月時点)

1RRU(Read Request Unit)は最大4KBの強整合性のある読み取り1回に相当します。1WRU(Write Request Unit)は最大1KBの書き込み1回に相当します。

無料枠について: DynamoDBには毎月の無料枠があります。25GBのストレージと、25 WCU/25 RCUのプロビジョンドキャパシティが無料です。個人開発や検証環境ではほぼ費用がかかりません。

応用・実務Tips

グローバルセカンダリインデックス(GSI)の活用

パーティションキー以外の属性でも効率よく検索したい場合は、グローバルセカンダリインデックス(GSI)を使います。例えば「status でアイテムを検索したい」という要件が後から発生した場合、status をパーティションキーとするGSIを追加します。

# AWS CLI でGSIに対してQueryを実行する例 # "StatusIndex" というGSIを事前に作成してある前提 aws dynamodb query \ --table-name Orders \ --index-name StatusIndex \ --key-condition-expression "#s = :status" \ --expression-attribute-names '{"#s": "status"}' \ --expression-attribute-values '{":status": {"S": "completed"}}'

RDBのセカンダリインデックスに似ていますが、GSIは別のテーブルに近い挙動で、追加のキャパシティコストが発生します。必要な検索パターンだけに絞って作成しましょう。

TTL(Time To Live)で自動削除

セッション情報や一時データには、TTL属性を設定することで期限切れアイテムを自動削除できます。追加コストは発生しません。属性値にUnixタイムスタンプ(epoch秒)を設定し、テーブルのTTL設定でその属性名を指定するだけです。

# 現在時刻から24時間後のUnixタイムスタンプを計算(Bash) echo $(($(date +%s) + 86400)) # → この値を ttl 属性にセットしてアイテムを保存する # テーブルのTTL設定でttl属性を有効化すると自動削除される

DynamoDB Streamsでイベント駆動処理

テーブルのアイテムが追加・更新・削除されたタイミングでAWS Lambdaをトリガーできます。これをDynamoDB Streamsと言います。「注文が完了したら在庫テーブルを更新する」「ユーザー情報が変更されたらSNS通知を送る」といったイベント駆動型の処理に活用できます。

オンプレでDBトリガーを使ってきたエンジニアには馴染みやすい仕組みです。ただし、Streamsのレコードは24時間で自動削除されるため、処理の遅延には注意が必要です。

よくあるトラブルと対処法

「ValidationException: Query key condition not supported」エラー: プライマリキー以外の属性に対してQueryを実行しようとしたときに発生します。GSIを作成するか、その属性でのフィルタリングにはScanを使いましょう(本番環境ではGSIが推奨)。
ProvisionedThroughputExceededException: プロビジョンドモードでキャパシティを超えたリクエストが来ると発生します。AutoScalingの設定を確認するか、一時的にオンデマンドモードに切り替えると解消します。
ホットパーティション問題: 特定のパーティションキーにアクセスが集中するとスループットが低下します。パーティションキーにランダムなサフィックスを付与する「シャーディング」が定番の対策です。
Scanが遅くなってきた: データ量が増えてからScanを多用していると気づくパターンです。設計段階でQueryで解決できるようにキー設計と必要なGSIを見直してください。
アイテムサイズ超過(400KB制限): 1アイテムあたりのサイズ上限は400KBです。大きなJSONや画像バイナリは別途Amazon S3に保存し、DynamoDBにはS3のURLを持たせるのが定石です。

本記事のまとめ

Amazon DynamoDBはRDBとは根本的に設計思想が異なります。要点をまとめます。

ポイント RDBとの違い・注意点
スキーマレス設計 アイテムごとに属性が違っても構わない
キー設計が全て アクセスパターンを先に定義してからキーを設計する
JOINはできない リレーションはアプリ層で処理するか、非正規化して持つ
QueryをScanより優先 Scanはフルテーブルスキャンでコストとレイテンシーがかかる
キャパシティモード選択 オンデマンドは変動アクセス向き、プロビジョンドは安定アクセス向き
GSIで検索を拡張 別の属性でQueryしたい場合はGSIを追加する

DynamoDBは「SQLが使えない不便なDB」ではなく、「高速・大量アクセスを支えるために特化したDB」です。向き不向きを理解した上でAmazon RDSやAurora(RDB)と組み合わせることが、現場で通用するクラウド設計への第一歩になります。

Linuxサーバーの基礎については、姉妹サイトLinuxMaster.JPでも詳しく解説しています。クラウド上のEC2でLinuxを動かす際の参考にしてください。

DynamoDBの設計、最初の一歩で悩んでいませんか?

「RDBの感覚で設計したら後で詰まった」——DynamoDB設計あるあるです。
オンプレの経験を活かしながら、現場で使えるクラウドスキルを体系的に身につけたい方へ、メルマガで実践的なクラウド活用ノウハウをお届けしています。

コメント

タイトルとURLをコピーしました