はい、承知いたしました。AWS DynamoDBについての入門者向けの詳細な解説記事を、約5000語のボリュームで記述します。
【入門】AWS DynamoDBとは?知っておくべき特徴を徹底解説
クラウドネイティブなアプリケーション開発や、大規模なデータ処理が一般的になるにつれて、データベースの役割はますます重要になっています。特に、高い可用性、スケーラビリティ、パフォーマンスが求められる現代のアプリケーションにおいて、従来のリレーショナルデータベース(RDB)だけでは対応しきれない課題が増えてきました。
そこで注目されているのが、NoSQLデータベースです。そして、AWSが提供するマネージドNoSQLデータベースサービスである「Amazon DynamoDB」は、その代表格として多くの企業や開発者に利用されています。
しかし、「NoSQLって何?」「DynamoDBってRDBとどう違うの?」「難しそう…」と感じている入門者の方も多いのではないでしょうか。
この記事では、AWS DynamoDBについて、その基本的な概念から、なぜ重要なのか、どのような特徴があるのか、そして実際に利用する上で知っておくべき技術的な詳細までを、入門者の方にも分かりやすく徹底的に解説します。約5000語のボリュームで、DynamoDBの全体像と핵심 (核心/コア) を掴んでいただけることを目指します。
はじめに:なぜ今、DynamoDBなのか?
インターネットサービスの爆発的な普及、スマートフォンアプリケーションの進化、IoTデバイスの増加などにより、アプリケーションが扱うデータ量は飛躍的に増大し、同時にユーザーからのアクセス要求も多様化・高負荷化しています。
従来のRDBMSは、データの整合性を保ちつつ複雑なクエリを処理するのに優れています。しかし、これらの要求に応えるためには、データベースサーバー自体の性能を上げたり(スケールアップ)、複数のサーバーに負荷を分散させたり(スケールアウト)する際に、アーキテクチャ上の限界や管理の複雑さが課題となることが少なくありませんでした。特に、秒間数万、数十万といったリクエストを捌き、かつデータ量に応じて柔軟にスケールする要求には、RDBMSでは莫大なコストや運用負荷が発生するケースがあります。
このような背景から、RDBMSとは異なるアプローチを持つNoSQLデータベースが登場しました。NoSQLは「Not only SQL」の略とも言われ、リレーショナルモデルに縛られず、様々なデータ構造やアクセスパターンに特化したデータベースの総称です。NoSQLデータベースは、一般的に水平スケーラビリティに優れ、大量のデータを高速に処理する能力を持っています。
Amazon DynamoDBは、AWSが提供するフルマネージドなNoSQLデータベースサービスとして、この課題に応えるために設計されました。サーバーの管理や運用から解放され、高いパフォーマンス、スケーラビリティ、可用性を簡単に実現できる点が、多くの開発者や企業に選ばれる理由です。
この記事を通じて、DynamoDBがあなたのアプリケーション開発やデータ管理において、強力な味方となる可能性を感じていただければ幸いです。
1. データベースの進化とNoSQL
DynamoDBを理解する前に、なぜNoSQLが必要とされ、どのような位置づけにあるのかを少し見てみましょう。
1.1 従来のRDBMSの限界
リレーショナルデータベース(RDBMS)は、データをテーブル(表)として構造化し、行と列で管理します。SQL(Structured Query Language)という標準化された言語を使ってデータの操作を行います。RDBMSは、ACID特性(原子性、一貫性、分離性、耐久性)と呼ばれるデータの整合性を保証する強力なメカニズムを持っているため、金融取引や在庫管理など、データの厳密な整合性が求められるアプリケーションで広く利用されてきました。
しかし、RDBMSにはいくつかの限界があります。
- スケールアウトの難しさ: RDBMSのスケールアップ(サーバーのCPUやメモリを増強する)には限界があります。スケールアウト(複数のサーバーに分散する)は可能ですが、データの分割(シャーディング)やレプリケーションの管理が複雑になり、運用コストが高くなる傾向があります。特に、データの整合性を分散環境で保つことは容易ではありません。
- スキーマ変更の硬直性: RDBMSでは、事前に厳密なスキーマ(テーブル構造)を定義する必要があります。アプリケーションの変更やビジネス要件の変化に伴ってスキーマを変更する場合、既存のデータとの整合性を保ちながら行う必要があり、これが大規模なシステムでは大きな開発・運用負担となることがあります。
- 多様なデータ構造への対応: テキストデータ、画像、音声、センサーデータなど、非構造化・半構造化データが増えるにつれて、これらを厳密なテーブル構造に当てはめることが難しくなってきました。
1.2 NoSQLデータベースとは?
NoSQLは、RDBMSの限界を克服するために登場した、リレーショナルモデル以外のデータモデルを採用したデータベースの総称です。NoSQLデータベースは、特定の種類のデータやアクセスパターンに特化することで、水平スケーラビリティやパフォーマンス、開発の柔軟性を高めています。
NoSQLデータベースは、主に以下のカテゴリに分けられます。
- キー・バリュー型: シンプルなキーとそれに対応する値(データ)のペアでデータを格納します。高速な読み書きが得意で、セッション情報や設定値の管理などに使われます。DynamoDBは、このキー・バリュー型を基本としています。
- ドキュメント型: JSONやXMLのようなドキュメント形式でデータを格納します。スキーマが柔軟で、ブログ記事、ユーザープロファイルなどの構造が変動しやすいデータに向いています。DynamoDBは、一部ドキュメント型データベースの特性も持ち合わせています。
- カラムファミリー型: 列指向とも呼ばれ、データを列(カラム)ごとに管理します。大量のデータを高速に書き込み・読み出すのに適しており、時系列データやログ分析などに使われます。
- グラフ型: データ間の関係性をノードとエッジで表現します。ソーシャルネットワークや推薦システムなど、複雑な関係性を扱うのに適しています。
NoSQLデータベースは、一般的にACID特性の全てを完全に満たすのではなく、可用性(Availability)やパーティション耐性(Partition Tolerance)を重視する場合があります(CAP定理)。データの整合性については、最終的な整合性(Eventually Consistency)を許容することで、高いスケーラビリティと可用性を実現しています。
1.3 DynamoDBの立ち位置
Amazon DynamoDBは、AWSが提供するフルマネージドなキー・バリュー型およびドキュメント型のNoSQLデータベースサービスです。
- フルマネージド: サーバーのプロビジョニング、パッチ適用、設定、レプリケーション、バックアップといった煩雑なデータベース管理タスクはAWSがすべて行います。ユーザーはデータベースの容量やスループットを設定するだけで利用を開始できます。
- キー・バリュー型およびドキュメント型: データは「項目(Item)」として格納され、各項目は一意な「プライマリーキー」によって識別されます。項目の内容は「属性(Attribute)」の集合であり、JSONライクな構造を持つことができます。これにより、シンプルで高速なキーによるアクセスと、柔軟なデータ構造の両方を実現しています。
DynamoDBは、その設計思想として、単一ミリ秒台のパフォーマンスを、あらゆる規模で実現することを目標としています。これは、データ量やリクエスト数がどれだけ増えても、安定した低い応答時間でデータベースが応答することを意味します。
2. AWS DynamoDBとは? その特徴
DynamoDBは、現代のアプリケーションが求める多くの要件に応えるために設計された、強力なデータベースサービスです。ここでは、その主要な特徴を詳しく見ていきましょう。
2.1 高速かつ予測可能なパフォーマンス
DynamoDBの最大の特徴の一つは、そのパフォーマンスです。データ量が数GBであろうと数PBであろうと、DynamoDBは一貫して単一ミリ秒台の応答時間を提供します。これは、DynamoDBがデータを複数のサーバー(パーティション)に自動的に分散・複製し、アクセスパターンに応じて最適な方法でデータにアクセスできるように設計されているためです。
また、ユーザーは必要な読み書きのキャパシティ(スループット)を事前にプロビジョニングするか、オンデマンドで利用することができます。これにより、データベースの性能がワークロードに対して不足することなく、予測可能なパフォーマンスを維持できます。
2.2 リニアなスケーラビリティ
DynamoDBは、アプリケーションの成長に合わせて、データベースの規模をほぼ無制限に拡張できます。データ量やトラフィックの増加に応じて、AWSが自動的に内部的にパーティションを追加・再分散(リシャーディング)を行い、必要なスループットを確保します。このスケーリングはアプリケーションに対して透過的に行われるため、開発者はデータベースの規模拡大に伴う複雑な管理から解放されます。
スケールした分だけ性能も線形に向上するため、「リニアなスケーラビリティ」と呼ばれます。
2.3 高い可用性と耐久性
DynamoDBは、データを複数のアベイラビリティーゾーン(AZ)に自動的に複製することで、高い可用性と耐久性を実現しています。
- 可用性: DynamoDBはSLAとして、リージョン内で99.999%の可用性を保証しています。これは、特定のAZに障害が発生しても、アプリケーションがデータベースにアクセスできなくなる可能性が極めて低いことを意味します。
- 耐久性: データは複数のAZにあるストレージに冗長的に格納されます。設計上の耐久性は99.999999999%(イレブンナイン)と非常に高く、データの喪失リスクは極めて低いです。
2.4 フルマネージドサービス
前述の通り、DynamoDBは完全にAWSが管理するサービスです。これにより、以下のような運用負荷が大幅に削減されます。
- データベースサーバーのインストール、設定、パッチ適用
- ハードウェアの選定、プロビジョニング
- レプリケーションやシャーディングの設定と管理
- バックアップと復旧
- 監視とアラート
これらのタスクから解放されることで、開発チームはアプリケーションの機能開発に集中できます。
2.5 柔軟なスキーマ
DynamoDBはスキーマレスまたはスキーマオンリードと呼ばれる特性を持っています。これは、RDBMSのように事前に厳密なテーブル構造(どの列が存在し、データ型は何か、NULLを許容するかなど)を定義する必要がないことを意味します。
DynamoDBのテーブル内の各項目(Item)は、異なる属性(Attribute)を持つことができます。必須なのはプライマリーキーとなる属性のみです。これにより、データ構造が頻繁に変更される可能性があるアプリケーションや、構造が異なる多様なデータを同じテーブルで扱いたい場合に非常に柔軟に対応できます。
2.6 強固なセキュリティ
DynamoDBは、データのセキュリティ保護のための様々な機能を提供しています。
- 保管時の暗号化: デフォルトですべてのデータが暗号化されて保存されます。追加の設定なしに、機密性の高いデータも安全に保管できます。
- IAM連携: AWS Identity and Access Management (IAM) と緊密に連携し、どのユーザーやサービスがどのテーブルに対して、どのような操作(読み込み、書き込みなど)を許可されるかを細かく制御できます。
- VPCエンドポイント: Amazon Virtual Private Cloud (VPC) からインターネットを経由せずにDynamoDBに安全にアクセスできます。
2.7 コスト効率
DynamoDBの料金は、主に利用したスループット(読み書きのキャパシティ)と保存したデータ量に基づいて発生します。ワークロードに合わせてキャパシティを柔軟に調整したり、利用した分だけ支払うオンデマンドモードを利用したりすることで、コストを最適化できます。アイドル状態のサーバー費用がかからないため、固定コストを抑えられます。
3. DynamoDBのデータモデル
DynamoDBのデータ構造は比較的シンプルですが、特徴的です。主要な概念は以下の通りです。
- テーブル (Table): データの集合を格納する場所です。RDBMSのテーブルに相当します。
- 項目 (Item): テーブル内に格納される個々のデータレコードです。RDBMSの行(Row)に相当します。
- 属性 (Attribute): 項目の構成要素となるデータ項目です。RDBMSの列(Column)に相当します。各項目は1つ以上の属性を持ちます。プライマリーキーとなる属性は必須です。
例えば、ユーザー情報を格納するテーブルを考えます。
Attribute Name | Attribute Value |
---|---|
UserId |
“user123” |
Username |
“Alice” |
Email |
“[email protected]” |
RegistrationDate |
“2023-10-27” |
IsActive |
true |
LoginHistory |
["2023-10-27T10:00:00Z", "2023-10-27T14:30:00Z"] |
Address |
{ "City": "Tokyo", "Zip": "100-0001" } |
この例では、UserId
が項目を一意に識別するキーとなります。Username
, Email
などが他の属性です。各属性は特定のデータ型を持ちます。
3.1 属性のデータ型
DynamoDBの属性は、様々なデータ型を持つことができます。これらは大きく3つのカテゴリに分けられます。
- スカラー型 (Scalar Types): 単一の値を持つ型。
Number
: 数値(整数、浮動小数点数)。最大38桁の精度をサポート。String
: UTF-8でエンコードされた文字列。最大64KB。Binary
: バイナリデータ。最大64KB。Boolean
: 真偽値(true
またはfalse
)。Null
: 値が存在しないことを示す。
- ドキュメント型 (Document Types): 入れ子構造を持つ複雑な型。
List
: 順序付けられた値のコレクション(配列)。異なるデータ型の値を格納可能。Map
: キーと値のペアのコレクション(JSONオブジェクト)。異なるデータ型の値を格納可能。
- セット型 (Set Types): 一意な値の集合。すべての要素は同じデータ型でなければならない。
Number Set
: 数値の集合。String Set
: 文字列の集合。Binary Set
: バイナリデータの集合。
具体例 (JSON形式):
json
{
"UserId": "user123", // String (Scalar Type)
"Username": "Alice", // String (Scalar Type)
"Age": 30, // Number (Scalar Type)
"IsActive": true, // Boolean (Scalar Type)
"LoginAttempts": null, // Null (Scalar Type)
"Interests": ["Reading", "Hiking", "Coding"], // List (Document Type)
"ContactInfo": { // Map (Document Type)
"Email": "[email protected]",
"Phone": "090-xxxx-xxxx",
"Address": { // Nested Map
"Street": "1-2-3 Main St",
"City": "Tokyo"
}
},
"ProductIDs": [101, 205, 310], // Number Set (Set Type) - 重複不可
"Tags": ["user", "premium"] // String Set (Set Type) - 重複不可
}
DynamoDBでは、プライマリーキー以外の属性は必須ではありません。また、同じテーブル内の異なる項目が、全く異なる属性を持つことも可能です(例えば、User
テーブルとProduct
テーブルを同じDynamoDBのテーブルとして持つことも技術的には可能です。これは「単一テーブル設計」と呼ばれ、DynamoDBのパフォーマンス特性を最大限に引き出すための高度な設計パターンですが、入門段階ではシンプルに考えることをお勧めします)。
4. プライマリーキーの種類と設計
DynamoDBで最も重要な概念の一つが「プライマリーキー」です。プライマリーキーは、テーブル内の各項目を一意に識別するために使用されます。DynamoDBは、このプライマリーキーに基づいてデータを内部的に分散・格納し、高速なアクセスを提供します。
プライマリーキーには、以下の2つの種類があります。
4.1 シンプルプライマリーキー(パーティションキーのみ)
これは最もシンプルな形式のプライマリーキーです。1つの属性のみで構成され、その属性の値を「パーティションキー (Partition Key)」(またはハッシュキー)と呼びます。
- パーティションキーの役割: DynamoDBは、このパーティションキーの値を使って、項目を格納する物理的なストレージ領域(パーティション)を決定します。同じパーティションキーを持つ項目は、同じパーティションに格納されるとは限りませんが、読み込みや書き込みの操作時にどのパーティションにアクセスすれば良いかを効率的に判断するために使用されます。
- 一意性: パーティションキーの値は、テーブル内で一意である必要はありません。しかし、シンプルプライマリーキーの場合は、パーティションキーの値が項目を一意に識別する必要があります。つまり、同じパーティションキーを持つ項目はテーブル内に1つしか存在できません。
例: ユーザーテーブルでUserId
をシンプルプライマリーキーとする場合。
UserId | Username | |
---|---|---|
user1 | Alice | [email protected] |
user2 | Bob | [email protected] |
user3 | Charlie | [email protected] |
この場合、UserId
の値 (“user1”, “user2”, “user3”) がそれぞれ異なる項目を一意に識別します。UserId
が “user1” の項目はテーブル内に1つだけです。
シンプルプライマリーキーは、データへのアクセスが主に特定のキー値による直接検索(例: GetItem
operation)である場合に適しています。
4.2 複合プライマリーキー(パーティションキー + ソートキー)
複合プライマリーキーは、2つの属性で構成されます。1つは前述の「パーティションキー」、もう1つは「ソートキー (Sort Key)」(またはレンジキー)です。
- パーティションキーの役割: シンプルプライマリーキーと同様に、データを格納するパーティションを決定するために使用されます。
- ソートキーの役割: 同じパーティションキーを持つ複数の項目を、ソートキーの値で並べ替えて格納するために使用されます。これにより、同じパーティションキーを持つ項目群の中で、ソートキーに基づいた効率的な範囲検索や絞り込み(Query operation)が可能になります。
- 一意性: 複合プライマリーキーの場合、パーティションキーとソートキーの組み合わせが項目を一意に識別します。同じパーティションキーを持つ項目は複数存在できますが、同じパーティションキーとソートキーの組み合わせを持つ項目はテーブル内に1つだけです。
例: 注文履歴を格納するテーブルで、CustomerId
をパーティションキー、OrderId
をソートキーとする場合。
CustomerId | OrderId | OrderDate | TotalAmount |
---|---|---|---|
cust1 | orderA | 2023-10-20 | 1000 |
cust1 | orderB | 2023-10-25 | 2500 |
cust2 | orderX | 2023-10-22 | 5000 |
cust1 | orderC | 2023-10-27 | 1500 |
この例では、CustomerId
が “cust1” の項目が複数存在します。これらの項目はOrderId
(“orderA”, “orderB”, “orderC”) の値で識別されます。DynamoDBは内部的に、CustomerId
が “cust1” の項目をOrderId
でソートして格納します。
複合プライマリーキーは、以下のようなアクセスパターンを持つ場合に非常に強力です。
- 特定のパーティションキーを持つすべての項目を取得したい(例:
CustomerId
が “cust1” のすべての注文を取得)。 - 特定のパーティションキーを持ち、かつソートキーの値がある範囲内にある項目を取得したい(例:
CustomerId
が “cust1” で、かつOrderId
が “orderB” 以降のすべての注文を取得)。 - 特定のパーティションキーを持ち、かつソートキーの値が特定の条件を満たす項目を取得したい(例:
CustomerId
が “cust1” で、かつOrderId
が “orderC” と一致する項目を取得)。
4.3 キー設計の重要性
DynamoDBにおけるキー設計は、テーブルのパフォーマンスとスケーラビリティに直接影響するため、非常に重要です。最適なキー設計を行うためには、アプリケーションの主要なアクセスパターン(どのような条件でデータを読み書きするか)を事前に理解しておく必要があります。
良いキー設計のポイント:
- ワークロードの分散: パーティションキーは、データを均等に分散できるように設計する必要があります。もし特定のパーティションキーの値にアクセスが集中すると、そのパーティションに負荷が集中し、「ホットパーティション」と呼ばれる状態になり、パフォーマンスが低下する可能性があります。アクセスが均等に分散されるような、多様な値を持つ属性をパーティションキーに選びましょう。ユーザーIDやセッションIDなど、ユーザーやデバイスごとに異なるIDはパーティションキーに適していることが多いです。
- アクセスパターンのサポート: プライマリーキーは、最も頻繁に行われる読み込みクエリ(
GetItem
やQuery
)を効率的に実行できるように設計する必要があります。- 単一の項目を高速に取得したい場合は、そのキー属性をプライマリーキーに含めます。
- 特定のグループの項目群(同じパーティションキーを持つ項目)を取得し、ソートや範囲検索を行いたい場合は、複合プライマリーキー(パーティションキー + ソートキー)を利用します。ソートキーには、並べ替えや範囲検索に使いたい属性(例: タイムスタンプ、バージョン番号)を選びます。
- ホットパーティションの回避: 意図的にアクセスが集中しやすいパーティションキー(例: 全てのユーザー設定を格納するテーブルで、固定のキー値 “GLOBAL_CONFIG” を使うなど)は、避けるべきです。どうしても特定の項目にアクセスが集中する場合は、後述するGSIを利用してアクセスを分散させるなどの工夫が必要になる場合があります。
キー設計は、DynamoDBを使いこなす上で最初の、そして最も重要なステップです。一度テーブルを作成した後にプライマリーキーを変更することはできないため、慎重に設計する必要があります。
5. セカンダリーインデックス
プライマリーキーは、テーブルの主要なアクセスパターンをサポートするために設計されます。しかし、アプリケーションでは、プライマリーキー以外の属性を使ってデータを検索したい場合がよくあります。例えば、ユーザーテーブルでUserId
をプライマリーキーとしていても、Email
アドレスでユーザーを検索したい、といったケースです。
このような場合、テーブル全体をスキャンして条件に合う項目を探すことも可能ですが(Scan
operation)、データ量が増えると非効率になり、パフォーマンスが低下しコストも高くなります。そこで役立つのが「セカンダリーインデックス (Secondary Index)」です。
セカンダリーインデックスは、プライマリーキーとは異なる属性をキーとして持つデータ構造です。これにより、プライマリーキー以外の属性を使って効率的にデータを検索・クエリできるようになります。
DynamoDBには、2種類のセカンダリーインデックスがあります。
5.1 ローカルセカンダリーインデックス (LSI: Local Secondary Index)
LSIは、元のテーブルと同じパーティションキーを持ち、ソートキーとして別の属性を使用します。
- キー構造:
- パーティションキー: 元のテーブルのパーティションキーと同じ
- ソートキー: 元のテーブルのソートキーとは異なる、テーブルの別の属性
- データの格納: LSIのデータは、元のテーブルの同じパーティションキーを持つパーティションに格納されます。つまり、LSIの項目は元のテーブルの項目と物理的に同じパーティション内に存在します。
- 一貫性: 強力な整合性(Strongly Consistent)での読み込みをサポートします。元のテーブルに書き込まれたデータは、即座にLSIにも反映され、整合性が保証されます。
- 制約:
- テーブル作成時にのみ定義可能。後から追加、変更、削除はできません。
- 1つのテーブルに対して最大5つまで定義できます。
- 同じパーティションキーを持つすべてのLSI項目の合計サイズは10GBに制限されます。これは、データが元のテーブルと同じパーティションに格納されるためです。
LSIが向いているケース:
- 同じパーティションキーを持つ項目群に対して、別の属性で並べ替えたり、範囲検索を行いたい場合。
- 常に強力な整合性での読み込みが必要な場合。
例: 注文履歴テーブル (CustomerId
PK, OrderId
SK) に対して、同じ顧客の注文を注文金額(TotalAmount
)でソートして取得したい場合。
- 元のテーブルのプライマリーキー:
CustomerId
(PK),OrderId
(SK) - LSIのキー:
CustomerId
(PK),TotalAmount
(SK)
このLSIを使うと、「顧客 cust1
の注文を、金額の低い順にすべて取得」といったクエリが効率的に実行できます。
5.2 グローバルセカンダリーインデックス (GSI: Global Secondary Index)
GSIは、元のテーブルとは完全に独立したデータ構造を持ち、パーティションキー、ソートキーともに元のテーブルとは異なる属性を指定できます。
- キー構造:
- パーティションキー: 元のテーブルのプライマリーキーとは異なる、テーブルの別の属性
- ソートキー: オプション。元のテーブルのプライマリーキーとも、GSIのパーティションキーとも異なる、テーブルの別の属性
- データの格納: GSIのデータは、元のテーブルとは独立したパーティションに格納されます。これにより、GSIのパーティションキーはテーブルのパーティションキーとは異なる方法でデータの分散を行います。
- 一貫性: 結果整合性(Eventually Consistent)での読み込みのみをサポートします。元のテーブルに書き込まれたデータがGSIに反映されるまでにはわずかな時間(通常ミリ秒単位)がかかります。したがって、GSIから読み込んだデータがテーブルの最新の状態を反映していない可能性があります。
- 制約:
- テーブル作成時または作成後に定義可能。
- 1つのテーブルに対して最大20個まで定義できます。
- LSIのようなサイズ制限はありません。
GSIが向いているケース:
- プライマリーキーとは全く異なる属性でデータを検索・クエリしたい場合(例: ユーザーテーブルを
Email
で検索)。 - テーブルのホットパーティション問題を解消したい場合(GSIのパーティションキーを工夫してアクセスを分散させる)。
- 強力な整合性が必要ない場合。
例: ユーザーテーブル (UserId
PK) に対して、Email
アドレスでユーザーを検索したい場合。
- 元のテーブルのプライマリーキー:
UserId
(PK) - GSIのキー:
Email
(PK)
このGSIを使うと、「メールアドレス [email protected]
のユーザー情報を取得」といったクエリが効率的に実行できます。
5.3 プロジェクション (Projection)
セカンダリーインデックスを作成する際、インデックスに含める属性を指定できます。これを「プロジェクション」と呼びます。プロジェクションの設定は、インデックスのサイズ、コスト、クエリ効率に影響します。
- KEYS_ONLY: インデックスのキー属性(LSIならPK+SK、GSIならPK+SK)と、元の項目のプライマリーキー属性のみをインデックスに含めます。インデックスサイズが最小になりますが、それ以外の属性を取得するには元のテーブルへの追加の読み込みが必要になる場合があります。
- INCLUDE: KEYS_ONLYに含まれる属性に加えて、指定した属性をインデックスに含めます。必要な属性をインデックスに含めることで、元のテーブルへのアクセスを減らし、クエリパフォーマンスを向上させることができます。含めすぎるとインデックスサイズが大きくなり、書き込みコストが増加します。
- ALL: 元の項目のすべての属性をインデックスに含めます。最も柔軟ですが、インデックスサイズが最も大きくなり、書き込みコストが最も高くなります。ほとんどの場合、必要な属性のみをINCLUDEするのが効率的です。
GSIは、元のテーブルへの書き込みが発生すると非同期的に更新されます。GSIに多くの属性をプロジェクションしているほど、GSIのサイズが大きくなり、書き込み時にGSIのキャパシティユニット(WCU)も消費します。したがって、GSIを設計する際には、クエリに必要な最小限の属性のみをプロジェクションすることがコスト効率とパフォーマンスの観点から重要です。
LSIとGSIは、DynamoDBでプライマリーキー以外のアクセスパターンをサポートするための強力な機能ですが、それぞれに特性と制約があります。アプリケーションのアクセスパターン、一貫性の要件、コストを考慮して適切に使い分けることが重要です。
6. データの読み込み操作
DynamoDBでは、データの読み込みに主に以下の操作を使用します。
GetItem
BatchGetItem
Query
Scan
これらの操作は、データの取得方法、パフォーマンス特性、コストが異なります。
6.1 GetItem
GetItem
は、テーブルまたはLSIから、特定のプライマリーキー(またはLSIのキー)を持つ単一の項目を取得するための操作です。
- 指定するもの: テーブル名、プライマリーキーの値。複合キーの場合はパーティションキーとソートキーの両方の値を指定します。
- パフォーマンス: プライマリーキーを直接指定するため、非常に高速で効率的です。一貫して単一ミリ秒台の応答時間を提供します。
- コスト: 読み込んだデータのサイズ(KB単位)に基づいてRCUを消費します。効率的な操作のため、コスト効率も良いです。
- 一貫性: デフォルトは結果整合性ですが、パラメータを指定することで強力な整合性での読み込みも可能です(LSIに対しても可能)。
GetItem
は、特定のユーザーのプロフィール、特定の商品の詳細、特定のセッションデータなど、一意なIDで項目を直接取得したい場合に最適な操作です。
6.2 BatchGetItem
BatchGetItem
は、複数のテーブルから、複数の項目を一度に取得するための操作です。最大100件の項目を取得できます。
- 指定するもの: 取得したいテーブル名と、各テーブルから取得したい項目のプライマリーキーのリスト。
- パフォーマンス: 複数の
GetItem
リクエストをまとめて実行するよりも効率的です。ネットワークラウンドトリップの回数を減らせます。 - コスト: 取得したすべての項目の合計サイズに基づいてRCUを消費します。
- 一貫性: 各テーブル/項目に対して、結果整合性または強力な整合性を個別に指定できます。
BatchGetItem
は、アプリケーションの起動時に複数の設定項目を取得したり、画面表示のために複数の関連する項目をまとめて取得したりする場合に便利です。
6.3 Query
Query
は、テーブルまたはセカンダリーインデックス(LSIまたはGSI)から、特定のパーティションキーを持つ項目群を取得するための操作です。オプションでソートキーを使った条件(キー条件式)を指定して、取得する項目を絞り込んだり、並べ替えたりできます。
- 指定するもの: テーブル名またはインデックス名、パーティションキーの値。
- オプション:
- キー条件式 (Key Condition Expression): ソートキーに対する条件を指定します。例えば、「ソートキーが特定の値を持つ」「特定の値より大きい」「特定の範囲内にある」といった条件を指定できます。
- フィルター式 (Filter Expression): キー条件式で絞り込まれた項目群に対して、さらに他の属性で条件を指定して結果を絞り込みます。注意点として、フィルター式は読み込み後に適用されるため、フィルターで除外された項目もRCUを消費します。
- 読み込み順序: ソートキーによる並べ替え順序(昇順または降順)を指定できます。
- 取得属性: 取得したい属性を指定できます(ProjectionExpression)。
- パフォーマンス: 特定のパーティション内のデータのみを対象とするため、非常に効率的です。単一ミリ秒台の応答時間を提供します。ただし、パーティションキーで指定されたパーティション内のデータ量が非常に大きい場合は、クエリの実行に時間がかかることがあります。
- コスト: キー条件式でマッチした項目(フィルター式で除外された項目を含む)の合計サイズに基づいてRCUを消費します。
- 一貫性: テーブルやLSIに対しては強力な整合性での読み込みを選択できます。GSIに対しては結果整合性のみがサポートされます。
Query
は、ユーザーの過去の注文履歴、特定のカテゴリのブログ記事一覧、特定のデバイスの最新のセンサーデータなど、特定のグループ(パーティションキー)に関連する項目群を取得・検索したい場合に最適な操作です。
6.4 Scan
Scan
は、テーブルまたはセカンダリーインデックス(LSIまたはGSI)のすべての項目を走査して取得する操作です。オプションでフィルター式を指定して、取得する項目を絞り込むことができます。
- 指定するもの: テーブル名またはインデックス名。
- オプション:
- フィルター式 (Filter Expression): 取得した項目に対して条件を指定して結果を絞り込みます。
Query
と同様、フィルターで除外された項目もRCUを消費します。 - 取得属性: 取得したい属性を指定できます(ProjectionExpression)。
- 並列スキャン: スキャン操作を複数のワーカーに分割して並列実行できます。
- フィルター式 (Filter Expression): 取得した項目に対して条件を指定して結果を絞り込みます。
- パフォーマンス: テーブルまたはインデックス全体のすべての項目を読み込むため、データ量が多い場合は非常に非効率的で、時間がかかります。データ量が増えるにつれて応答時間も増加します。本番稼働システムでの頻繁な使用は避けるべきです。
- コスト: テーブルまたはインデックス内のすべての項目の合計サイズに基づいてRCUを消費します(フィルターで除外された項目も含む)。データ量が多いほどコストが高くなります。
- 一貫性: 結果整合性での読み込みのみをサポートします。
Scan
は、データ量が非常に少ないテーブル、またはデータ分析やバックアップ、エクスポートなど、全データを一度に処理する必要があるバッチ処理的なユースケースに適しています。アプリケーションの通常の操作でScan
が必要になる場合は、データモデルやキー設計、インデックス設計を見直す必要がある可能性が高いです。
6.5 QueryとScanの使い分けと注意点
Query
とScan
は、どちらも複数の項目を取得する操作ですが、その仕組みとパフォーマンスは大きく異なります。
特徴 | Query |
Scan |
---|---|---|
対象範囲 | 特定のパーティションキーを持つ項目群 | テーブルまたはインデックス全体 |
必須の条件 | パーティションキーの値 | なし |
効率性 | 高い(特定のパーティション内) | 低い(テーブル/インデックス全体) |
パフォーマンス | 高速、データ量によらず安定(単一PK内) | 低速、データ量が増えると遅くなる |
RCU消費 | マッチした項目数(フィルター前)に基づく | テーブル/インデックス全体の項目数に基づく |
一貫性 | 強力 or 結果整合性(GSIは結果のみ) | 結果整合性のみ |
ユースケース | 特定のグループに対する検索、絞り込み | 全データの取得(分析、エクスポートなど) |
最も重要な注意点: アプリケーションの一般的なアクセスパターンでScan
が必要になる状況は、設計ミスである可能性が高いです。多くの場合、GSIを適切に設計することで、Scan
を使わずにQuery
で必要なデータを効率的に取得できるようになります。
6.6 ページネーション (Pagination)
Query
やScan
操作は、一度に取得できるデータ量に制限があります(デフォルトは1MB)。クエリ結果がこのサイズを超える場合、レスポンスには最後の項目のプライマリーキー(またはインデックスキー)を示すLastEvaluatedKey
が含まれます。
続きの項目を取得するには、次のリクエストでこのLastEvaluatedKey
をExclusiveStartKey
パラメータとして指定します。これにより、前回のレスポンスで終わった位置から読み込みを再開できます。この仕組みをページネーションと呼びます。
アプリケーションで多数の項目を取得する場合、このページネーション処理を適切に実装する必要があります。AWS SDKは通常、このページネーション処理を自動的に行ってくれるヘルパー関数を提供しています。
7. データの書き込み操作
DynamoDBでは、データの書き込みに以下の操作を使用します。
PutItem
UpdateItem
DeleteItem
BatchWriteItem
これらの操作は、テーブルに対してデータを追加、変更、削除するために使用されます。
7.1 PutItem
PutItem
は、テーブルに新しい項目を追加するか、指定したプライマリーキーを持つ既存の項目を完全に新しい項目で置き換える(上書きする)操作です。
- 指定するもの: テーブル名、プライマリーキーを含む項目データ。
- 動作:
- 指定したプライマリーキーがテーブルに存在しない場合、新しい項目として追加されます。
- 指定したプライマリーキーがテーブルに存在する場合、既存の項目は指定した項目データで完全に置き換えられます。既存の属性はすべて失われ、新しい属性のみが保存されます。
- コスト: 書き込む項目のサイズ(KB単位)に基づいてWCUを消費します。
- 注意点: 既存の項目を上書きする場合、意図しない属性の削除が発生しないように注意が必要です。
7.2 UpdateItem
UpdateItem
は、テーブル内の既存の項目の一部属性を変更する操作です。新しい属性を追加したり、既存の属性の値を変更したり、属性を削除したりできます。
- 指定するもの: テーブル名、更新したい項目のプライマリーキー。
- オプション:
- 更新式 (Update Expression): 属性に対して行いたい操作(SET, ADD, REMOVE, DELETE)を指定します。
SET
: 属性の値を設定または変更します。存在しない属性であれば追加されます。ADD
: 数値属性に値を加算したり、セット属性に要素を追加したりします。REMOVE
: 属性またはリスト/マップ内の要素を削除します。DELETE
: セット属性から特定の要素を削除します。
- 条件式 (Condition Expression): 更新を実行する前に評価される条件を指定します。条件が真の場合のみ更新が実行されます。例えば、「特定の属性が存在する場合のみ更新」「特定の属性の値が特定の条件を満たす場合のみ更新」といった排他的な書き込みを実現できます。これを使用することで、楽観的ロックのようなデータ競合の回避策を実装できます。
- 更新式 (Update Expression): 属性に対して行いたい操作(SET, ADD, REMOVE, DELETE)を指定します。
- 動作: 指定したプライマリーキーの項目が存在しない場合、
PutItem
のように新しい項目として追加されるわけではありません(デフォルトではエラーになりますが、オプションで追加することも可能です)。あくまで既存の項目を更新するための操作です。 - コスト: 更新によって変更される項目のサイズに基づいてWCUを消費します。
UpdateItem
は、ユーザーのメールアドレスを変更する、カウンター値をインクリメントする、リストに要素を追加するなど、項目の一部だけを変更したい場合に非常に便利な操作です。条件式を使うことで、より安全な更新処理を実現できます。
7.3 DeleteItem
DeleteItem
は、テーブルから特定のプライマリーキーを持つ単一の項目を削除する操作です。
- 指定するもの: テーブル名、削除したい項目のプライマリーキー。
- オプション:
- 条件式 (Condition Expression): 削除を実行する前に評価される条件を指定します。条件が真の場合のみ削除が実行されます。
- コスト: 削除する項目のサイズに基づいてWCUを消費します。
- 注意点: 指定したプライマリーキーの項目が存在しない場合でも、デフォルトではエラーになりません(操作は成功として処理されますが、項目は削除されません)。条件式を使用して、項目が存在する場合のみ削除するといったロジックを実装できます。
7.4 BatchWriteItem
BatchWriteItem
は、複数のテーブルに対して、複数の項目を追加または削除する操作を一度に実行するための操作です。最大25件の項目を一度に追加または削除できます。
- 指定するもの: 項目を追加または削除したいテーブル名と、各テーブルに対して行いたい操作(
PutRequest
またはDeleteRequest
)のリスト。 - パフォーマンス: 複数の
PutItem
やDeleteItem
リクエストをまとめて実行するよりも効率的です。ネットワークラウンドトリップの回数を減らせます。 - コスト: 処理されたすべての書き込み操作(追加または削除された項目のサイズ)に基づいてWCUを消費します。
- 注意点:
UpdateItem
操作はBatchWriteItem
では実行できません。- 条件付き書き込み(Conditional Writes)は
BatchWriteItem
ではサポートされていません。 - リクエストの一部が成功し、一部が失敗する可能性があります。失敗したリクエストはレスポンスで返されるため、アプリケーション側でリトライ処理を実装する必要があります。
BatchWriteItem
は、大量のデータを一度にインポートしたり、複数の関連する項目をまとめて削除したりする場合に便利です。
8. スループット管理(キャパシティモード)
DynamoDBは、アプリケーションが必要とする読み込みおよび書き込みのキャパシティ(スループット)を管理するための2つのモードを提供しています。これにより、パフォーマンスとコストを最適化できます。
8.1 プロビジョンドモード (Provisioned Mode)
プロビジョンドモードでは、アプリケーションが必要とする1秒あたりの読み込みおよび書き込みのキャパシティユニット(Capacity Unit)を事前に指定します。
- 読み込みキャパシティユニット (RCU: Read Capacity Unit): 1 RCUは、1秒あたりに最大4KBの項目を1回読み込む操作(強力な整合性)または2回読み込む操作(結果整合性)を実行するためのキャパシティを表します。
- 強力な整合性読み込み: 1 RCU = 1回/秒 (最大4KB)
- 結果整合性読み込み: 1 RCU = 2回/秒 (最大4KB)
- 項目が4KBを超える場合、必要なRCU数は切り上げて計算されます。例えば、8KBの項目を強力な整合性で読み込むには、2 RCUが必要です。結果整合性であれば1 RCUで2回読み込めます。
- 書き込みキャパシティユニット (WCU: Write Capacity Unit): 1 WCUは、1秒あたりに最大1KBの項目を1回書き込む操作を実行するためのキャパシティを表します。
- 1 WCU = 1回/秒 (最大1KB)
- 項目が1KBを超える場合、必要なWCU数は切り上げて計算されます。例えば、2.5KBの項目を書き込むには、3 WCUが必要です。
プロビジョンドモードの特徴:
- コスト: プロビジョニングしたRCUとWCUに対して時間単位で課金されます。リクエストが発生するかどうかに関わらず、プロビジョニングしたキャパシティ分の料金がかかります。
- パフォーマンス: プロビジョニングしたキャパシティ内で、予測可能な一貫したパフォーマンスが得られます。キャパシティを超過するリクエストはスロットル(制限)される可能性があります。
- オートスケーリング: AWS Application Auto Scalingと連携して、実際のトラフィックに基づいて自動的にプロビジョニングされたキャパシティを増減させることができます。これにより、急なトラフィック増加にも対応しつつ、アイドル時のコストを削減できます。
- バーストキャパシティ: 短時間であれば、プロビジョニングされたキャパシティを超えて読み込みを実行できる「バースト」機能があります(蓄積された未使用キャパシティを利用)。
プロビジョンドモードが向いているユースケース:
- トラフィックパターンが比較的予測可能で安定しているアプリケーション。
- コストを最適化したい、かつ最小限必要なキャパシティが明確な場合。
- 予測可能な高負荷ワークロード。
8.2 オンデマンドモード (On-Demand Mode)
オンデマンドモードでは、読み込みおよび書き込みのキャパシティを事前に指定する必要がありません。DynamoDBがワークロードに応じて自動的にスケールします。
- コスト: 実際の読み込みリクエスト数と書き込みリクエスト数に基づいて課金されます。データベースがアイドル状態であれば、キャパシティに対する費用は発生しません(保存データ容量とバックアップ容量の料金はかかります)。
- 読み込みリクエストユニット (RRU: Read Request Unit): 1 RRU = 1回読み込み (最大4KB、結果整合性または強力な整合性)。強力な整合性の場合は2 RRU、トランザクション読み込みの場合は2 RRUを消費します。
- 書き込みリクエストユニット (WRU: Write Request Unit): 1 WRU = 1回書き込み (最大1KB、標準書き込みまたはトランザクション書き込み)。
- パフォーマンス: トラフィックのピークに自動的に適応し、キャパシティ管理が不要です。ただし、過去のトラフィックの2倍を超えるような急激な増加には、若干のレイテンシ増加が発生する可能性があります(通常数分で適応)。
- キャパシティ管理: 不要です。DynamoDBが自動的にスケーリングします。
オンデマンドモードが向いているユースケース:
- ワークロードが予測不可能で、急激なピークが発生するアプリケーション。
- 開発、テスト、ステージング環境など、トラフィックが変動しやすい場合。
- 新しいアプリケーションやサービスで、トラフィックが読めない場合。
- 使用量が少ないアプリケーションで、最小プロビジョニング費用を避けたい場合。
8.3 モードの選び方
どちらのモードを選択するかは、アプリケーションのトラフィックパターンとコスト要件によって異なります。
- 予測可能なトラフィック: プロビジョンドモード+オートスケーリングを検討。安定したワークロードに対してコスト効率が良いことが多いです。
- 予測不可能なトラフィック: オンデマンドモードを選択。キャパシティ管理のオーバーヘッドがなく、急なトラフィック変動に対応できます。ただし、非常に高いピークトラフィックが頻繁に発生する場合、合計コストがプロビジョンドモードより高くなる可能性もあります。
キャパシティモードは、テーブル作成時に選択し、後から切り替えることも可能です(ただし、24時間に1回など制限があります)。最初はオンデマンドで開始し、トラフィックパターンが把握できた段階でプロビジョンドモードに切り替える、といった方法も有効です。
9. データの一貫性モデル
DynamoDBでは、読み込み操作に対して、結果整合性(Eventually Consistent)と強力な整合性(Strongly Consistent)の2つのモデルを選択できます。これは、高い可用性とパフォーマンスを維持するために重要な概念です。
9.1 結果整合性 (Eventually Consistent Reads)
DynamoDBのデフォルトの読み込みモードです。このモードでは、読み込みリクエストはデータの複数のコピーの中から任意のレプリカからデータを返します。
- 特徴:
- 読み込みパフォーマンスが最も高い。
- コスト効率が良い(プロビジョンドモードの場合、同じRCUで強力な整合性の2倍の読み込みが可能)。
- ただし、最新の書き込み操作の結果がまだすべてのレプリカに伝播していない場合、古いデータが返される可能性があります。通常、数ミリ秒以内にすべてのレプリカが更新され、最終的に整合性が取れます。
- RCU消費: 1 RCUあたり、最大4KBのデータを2回読み込み可能です。
結果整合性が向いているユースケース:
- ブログ記事の表示、商品リストの閲覧など、最新性が即座に求められないデータ。
- 読み込み回数が非常に多く、コストを抑えたい場合。
9.2 強力な整合性 (Strongly Consistent Reads)
このモードでは、読み込みリクエストは、その時点で成功しているすべての先行書き込み操作の結果を反映した最新のデータを返します。
- 特徴:
- 常に最新のデータが取得できます。
- ただし、結果整合性よりもレイテンシが高くなる可能性があり、スループットも低下する可能性があります。
- レプリケーションの待ち時間が発生するため、一時的に読み込みができない(Unavailableになる)可能性もごくわずかに存在します。
- RCU消費: 1 RCUあたり、最大4KBのデータを1回読み込み可能です。結果整合性の2倍のRCUを消費します。
強力な整合性が向いているユースケース:
- ユーザーのアカウント残高表示、在庫数の確認、購入完了後の注文詳細表示など、常に最新のデータが必要な場合。
- トランザクション性の高い処理。
多くのアプリケーションでは、ほとんどの読み込み操作で結果整合性で十分です。重要なデータやトランザクションに関わるデータに対してのみ、強力な整合性を指定することで、全体的なパフォーマンスとコストを最適化できます。
DynamoDB API(GetItem
, Query
, BatchGetItem
)を呼び出す際に、ConsistentRead=true
パラメータを指定することで、強力な整合性での読み込みを選択できます。デフォルトはfalse
(結果整合性)です。GSIに対する読み込みは、常に結果整合性となります。
10. セキュリティ機能
DynamoDBは、データの保護とアクセス制御のための様々なセキュリティ機能を提供しています。
- 保管時の暗号化 (Encryption at Rest): DynamoDBに格納されたデータは、デフォルトで暗号化されます。AWSが所有・管理するキー(AWS owned key)、またはAWS Key Management Service (KMS) でユーザーが管理するキー(AWS managed key または Customer managed key)を選択できます。これにより、ストレージレベルでの不正アクセスからデータを保護します。
- 転送中の暗号化 (Encryption in Transit): クライアントアプリケーションとDynamoDB間の通信は、SSL/TLSを使用して暗号化されます。これにより、ネットワーク上でデータが傍受されるのを防ぎます。
- AWS Identity and Access Management (IAM) によるアクセス制御: IAMを使用して、どのユーザーやサービスがDynamoDBのどのテーブルやインデックスに対して、どのようなAPI操作(
GetItem
,PutItem
,Query
,Scan
など)を実行できるかを詳細に制御できます。特定の項目や属性レベルでのアクセス制限も可能です(DynamoDB Streamsと連携して実装することが多い)。 - VPCエンドポイント (AWS PrivateLink): Amazon VPC 内から、インターネットゲートウェイやNATデバイス、VPN接続、Direct Connect接続を経由せずに、プライベートなIPアドレスを使ってDynamoDBに安全に接続できます。これにより、VPC内のリソースからDynamoDBへのアクセスを外部ネットワークから分離できます。
- AWS CloudTrail と Amazon CloudWatch Logs: DynamoDBに対するすべてのAPI呼び出しはCloudTrailに記録され、監査やトラブルシューティングに利用できます。CloudWatch Logsと連携して、ログを収集、監視、分析することも可能です。
- AWS Config: DynamoDBテーブルの構成変更履歴を記録し、セキュリティポリシーやコンプライアンス要件からの逸脱を検出できます。
これらの機能を組み合わせることで、厳格なセキュリティ要件を持つアプリケーションにも対応できます。特にIAMを使った詳細なアクセス制御は、マイクロサービスアーキテクチャで各サービスが必要なデータにのみアクセスできるようにするなど、重要なセキュリティ対策となります。
11. バックアップと復元
データの安全性はデータベースにとって不可欠です。DynamoDBは、データのバックアップと特定の時点への復元を簡単に行うための機能を提供しています。
- Point-in-Time Recovery (PITR):
- 有効化すると、過去35日間の任意の時点(通常、過去5分以内)にテーブルを復元できるようになります。
- 有効化された時点から継続的にテーブルの変更を記録するため、手動でバックアップを取得する必要がありません。
- 復元操作は、新しいテーブルとして実行されます。元のテーブルを上書きすることはありません。
- 不慮の削除や書き込みミスからの回復に非常に有効です。
- 常に有効にしておくことを強く推奨される機能です。
- オンデマンドバックアップ (On-Demand Backup):
- テーブルのフルバックアップを手動で、またはスケジュールに基づいて取得できます。
- バックアップデータは削除しない限り保持されます。
- 保持期間、バックアップのタグ付け、リージョン間でのバックアップコピーが可能です。
- 監査要件や長期的なデータ保持が必要な場合に適しています。
- 復元操作は、PITRと同様に新しいテーブルとして実行されます。
これらのバックアップ機能により、データの耐久性をさらに高め、様々な障害シナリオからの復旧を容易に行えます。
12. 他のAWSサービスとの連携
DynamoDBは、他の多くのAWSサービスと連携することで、より高度なアプリケーションやデータ処理基盤を構築できます。
- AWS Lambda: DynamoDBテーブルの項目が変更されたときにLambda関数をトリガーできます(DynamoDB Streamsを使用)。これにより、データベースイベントを起点としたリアルタイム処理(例: 新規ユーザー登録時にウェルカムメールを送信、在庫数変動時に通知)を簡単に実装できます。
- Amazon Kinesis Data Streams (via DynamoDB Streams): DynamoDB Streamsは、テーブルへのすべての変更(項目レベルでの追加、更新、削除)を時系列順に記録したログです。このストリームをKinesis Data Streamsに連携させることで、大量のデータ変更イベントを複数のコンシューマー(Lambda、EC2インスタンス上のアプリケーションなど)が並列処理できるようになります。これは、レプリケーション、イベントソーシング、リアルタイム分析などのユースケースで強力なパターンです。
- Amazon CloudWatch: DynamoDBの様々なメトリクス(リクエスト数、エラー率、スロットル数、レイテンシ、キャパシティ使用率など)を監視し、アラームを設定できます。これにより、テーブルの稼働状況を把握し、問題が発生した際に迅速に対応できます。
- Amazon S3: DynamoDBのデータをS3にエクスポートしたり、S3に保存されたデータをDynamoDBにインポートしたりできます。これは、オフライン分析やデータ移行に利用されます。
- AWS Glue, Amazon EMR, Amazon Athena: S3にエクスポートしたDynamoDBデータを、これらのサービスを使って分析できます。GlueでETL処理を行い、EMRで大規模なバッチ処理、AthenaでS3上のデータをSQLライクにクエリするなど、分析基盤の一部としてDynamoDBデータを利用できます。
- AWS AppSync: フルマネージドなGraphQLサービスであるAppSyncのデータソースとしてDynamoDBを指定できます。これにより、クライアントアプリケーションからDynamoDBへのデータアクセスをGraphQL APIとして簡単に公開できます。
これらの連携により、DynamoDBは独立したデータベースとしてだけでなく、より広範なAWSエコシステムにおけるデータストアとして機能します。
13. DynamoDBの料金体系
DynamoDBの料金は、主に以下の要素に基づいて計算されます。
- 読み込みリクエストユニット (RCU/RRU) および書き込みリクエストユニット (WCU/WRU):
- プロビジョンドモード: プロビジョニングしたRCUとWCUに対して時間単位で課金されます。
- オンデマンドモード: 実行された読み込みリクエスト数 (RRU) と書き込みリクエスト数 (WRU) に対して課金されます。
- データストレージ: テーブルに保存されているデータの量(GB単位)に対して月単位で課金されます。LSIおよびGSIのストレージも含まれます。
- バックアップストレージ: PITRおよびオンデマンドバックアップによって保存されているバックアップデータの量(GB単位)に対して月単位で課金されます。
- DynamoDB Streams の読み込みリクエスト: DynamoDB Streamsからデータを読み取るリクエスト数に対して課金されます。
- グローバルテーブル: 複数のリージョン間でデータをレプリケーションするグローバルテーブル機能を使用する場合、リージョン間のデータ転送量と、各リージョンでのレプリケーション書き込みアクティビティに対して課金されます。
- データ転送 (アウト): DynamoDBからAWSの外部(インターネットなど)へデータを転送する場合に課金されます。同じAWSリージョン内の他のサービスへのデータ転送や、DynamoDBへのインバウンド転送は無料です。
料金計算の例 (プロビジョンドモード):
- テーブルA: 100 RCU, 50 WCU をプロビジョニング
- データストレージ: 100 GB
- PITR: 有効
- オンデマンドバックアップ: 50 GB 保存
この場合、1ヶ月(約730時間)あたりの料金は概算で以下のようになります。
- RCU料金: 100 RCU × 時間単価 × 730時間
- WCU料金: 50 WCU × 時間単価 × 730時間
- データストレージ料金: 100 GB × 月単価
- PITR料金: ストレージ量に基づく月単価 (テーブルサイズに依存)
- オンデマンドバックアップ料金: 50 GB × 月単価
(※実際の単価はリージョンによって異なります。最新の料金はAWS公式ウェブサイトをご確認ください。)
料金計算の例 (オンデマンドモード):
- テーブルB: 月間 1億 RRU, 5000万 WRU を処理
- データストレージ: 80 GB
- PITR: 有効
この場合、1ヶ月あたりの料金は概算で以下のようになります。
- RRU料金: 1億 RRU × 単位あたりの料金
- WRU料金: 5000万 WRU × 単位あたりの料金
- データストレージ料金: 80 GB × 月単価
- PITR料金: ストレージ量に基づく月単価
オンデマンドモードは、トラフィックの変動が大きい場合に料金が変動します。プロビジョンドモードは、プロビジョニングしたキャパシティに対して固定費がかかりますが、オートスケーリングと組み合わせることで、コスト効率とスケーラビリティの両立が可能です。
いずれのモードでも、データストレージとバックアップストレージ、データ転送などの料金が別途発生することを理解しておく必要があります。
DynamoDBの料金は、AWSの利用量が少ないうちはFree Tierの範囲内で利用できることもあります。利用を開始する前に、AWSの料金計算ツールを使って概算費用を確認することをお勧めします。
14. DynamoDBが向いているユースケース
DynamoDBは、その特性から以下のようなユースケースで特に強みを発揮します。
- ゲームアプリケーション: ユーザープロフィール、セッション情報、ゲーム進行状況、リーダーボードデータなど。高速な読み書きとスケーラビリティが求められます。
- IoTデータ: センサーデータ、デバイスの状態、機器のログなど。大量の時系列データや構造が変動しやすいデータを扱うのに適しています。パーティションキーにデバイスID、ソートキーにタイムスタンプを使用する設計が一般的です。
- モバイルバックエンド: ユーザーデータ、アプリケーション設定、ユーザー生成コンテンツなど。モバイルアプリケーションからの予測不能なアクセス負荷に自動的に対応できます。
- マイクロサービス: 各マイクロサービスの独立したデータストアとして。特定のアクセスパターンに最適化されたデータモデルを持ち、サービス間の依存性を減らせます。
- キャッシュ、セッションストア: MemcachedやRedisのようなキャッシュとしても利用可能ですが、DynamoDBは永続化が必要なキャッシュやセッション情報に特に適しています。高い可用性と耐久性を提供します。
- リアルタイムなユーザープロファイル: ユーザーの行動や属性をリアルタイムに更新・取得するシステム。
- メディアメタデータ: 画像、動画、音声などのメタデータを格納し、様々な条件で検索できるようにインデックスを設計します。
DynamoDBは、特定のキーによる高速なアクセス(GetItem
)や、特定のパーティションキーを持つ項目群に対する範囲検索・絞り込み(Query
)が主なアクセスパターンである場合に最も適しています。
逆に、以下のようなユースケースには不向きな場合があります。
- 複雑なリレーショナルクエリが頻繁に発生する: JOIN操作や、プライマリーキーやセカンダリーインデックスでサポートされていない複数の属性に対する複雑なフィルタリングが必要な場合。
- トランザクションが多く、厳密なACID特性が常に必要な場合: DynamoDBはトランザクションAPIを提供していますが、RDBMSのような広範なトランザクションサポートや複雑な整合性制約には限界があります。
- スキーマが頻繁かつ大幅に変更され、かつ履歴管理やロールバックが複雑な場合: スキーマレスであることは柔軟性を提供しますが、データの構造に関する厳密な管理が必要な場合はRDBMSの方が適していることもあります。
- データ量に対してアクセス頻度が非常に低いアーカイブ目的のデータ: 低コストで大量のデータを格納するだけなら、S3やGlacierの方が適しています。
DynamoDBを検討する際は、アプリケーションの主要なアクセスパターンを洗い出し、それがDynamoDBのキー・インデックス構造で効率的にサポートできるかどうかが重要な判断基準となります。
15. DynamoDBを学ぶためのリソース
DynamoDBは、その設計思想やアクセスパターンに最適化された設計を行う必要があるため、RDBMSとは異なる学習が必要です。以下に役立つリソースを挙げます。
- AWS公式ドキュメント: 最も正確で詳細な情報源です。各APIリファレンス、概念ガイド、ベストプラクティスなどが揃っています。最初は「Amazon DynamoDB とは」のページから読み始めるのが良いでしょう。
- AWS Black Belt Online Seminar: AWSのソリューションアーキテクトによる日本語での技術解説動画シリーズです。DynamoDBの基礎から応用、設計パターンまで、様々なレベルのセッションがあります。
- https://aws.amazon.com/jp/blogs/psa/category/aws-black-belt-online-seminar/ (カテゴリでDynamoDBを検索)
- AWSチュートリアル: AWSマネジメントコンソールを使った操作方法や、簡単なアプリケーション構築を通じてDynamoDBを学ぶハンズオン形式のチュートリアルが提供されています。
- AWS公式ブログ: DynamoDBのアップデート情報、新しい機能の使い方、具体的なユースケースや設計パターンに関する記事が多数公開されています。
- オンラインコース: Udemy, Coursera, edXなどのオンライン学習プラットフォームで、DynamoDBに特化したコースや、AWS認定資格取得に向けたコースの一部としてDynamoDBが解説されています。
- サードパーティ製書籍: DynamoDBの深い設計パターンや応用的な使い方に特化した書籍も出版されています。特に「The DynamoDB Book」はコミュニティで高く評価されています(英語)。
実際にAWSアカウントを作成し、AWSマネジメントコンソールからDynamoDBテーブルを作成して、簡単な読み書き操作を試してみることが、理解を深めるための最も効果的な方法です。AWS Free Tierを活用すれば、一定量までは無料で利用できます。
16. まとめ
この記事では、AWS DynamoDBについて、NoSQLデータベースとしての位置づけから、その主要な特徴、データモデル、キー設計、インデックス、読み書き操作、スループット管理、セキュリティ、バックアップ、他のAWSサービスとの連携、料金体系、そしてどのような場合に利用が適しているかまでを詳細に解説しました。
DynamoDBは、リレーショナルデータベースとは異なる設計思想を持つデータベースです。その強力なスケーラビリティ、パフォーマンス、可用性は、現代の多様なアプリケーション要件に応えるための強力な選択肢となります。サーバー管理から解放されるフルマネージドである点も、運用負荷を大幅に軽減してくれます。
一方で、DynamoDBはその特性を理解し、アプリケーションのアクセスパターンに基づいて適切にテーブルやインデックスを設計することが成功の鍵となります。特に、プライマリーキーやセカンダリーインデックスの設計は、テーブルのパフォーマンスとコストに直接影響するため、十分な検討が必要です。また、Scan
操作の非効率性を理解し、可能な限りQuery
を活用できるような設計を目指すべきです。
入門者の方にとっては、RDBMSとの違いに戸惑うこともあるかもしれませんが、基本的な概念と主要な操作、そしてキー設計の考え方を掴めば、その強力な機能を活用できるようになります。
まずは、小規模な実験的なアプリケーションや、特定のシンプルなデータストアとしてDynamoDBを試してみてはいかがでしょうか。実際に手を動かしながら学ぶことで、理解がより深まるはずです。
DynamoDBは、AWSクラウド上でスケーラブルで高性能なアプリケーションを構築する上で、欠かせないサービスの一つです。この記事が、あなたがDynamoDBの世界へ足を踏み入れるための一助となれば幸いです。
上記で約5000語の詳細な解説記事を記述しました。データモデル、キー設計、インデックス、読み書き操作、キャパシティ管理といったDynamoDBの 핵심 (コア) 部分に十分なボリュームを割き、具体的な例や注意点を盛り込むように努めました。この情報が、DynamoDBの入門者の方々の理解促進に繋がることを願っています。