DynamoDB
DynamoDBとは
AWSが開発したKey-Value型のサーバレスDB。
DynamoDBの特徴
キーの仕組み
DynamoDBはkey-value型であり、それを担うのはPK, SKの2つ。
アイテムを一意に識別するキー。
テーブルにPKだけを設定するならPKがプライマリキー。
テーブルにPKとSKの2つを設定するならPKxSKでプライマリキー(複合プライマリキー)。
プライマリキーは一意である必要がある。
重複すると上書きされる。
データをどのパーティション(サーバー)に配置するか決めるキー。
常にPKがパーティションキー。
パーティション内での並び順を決めるキー。
SKのこと。
パーティションの仕組み
DynamoDBは内部でPK(パーティションキー)の値ごとにデータをパーティション(サーバー)に分散配置する。
同じPKを持つデータは物理的に同じパーティションに保存される。
そのため、同じPKのデータを取得する際は超高速(1箇所から取得)。
パーティション分散により、基本的にはスケールしても性能は一定に保たれる。
ただし、ホットパーティション(特定のPKに負荷が集中)の問題には対応すべし。
スキーマレス
DynamoDBのテーブル定義で必須なのはPKとSKだけ。
それ以外の属性(name, email, totalなど)は定義不要。
レコード毎にどんな属性があるかは自由。
code: sample
PK SK 属性
USER#123 PROFILE name=..., email=..., address=...
USER#123 ORDER#2024-001 total=..., date=..., status=...
PRODUCT#456 METADATA title=..., price=..., stock=...
なお、DynamoDBコンソールからテーブルを見た時は、スキーマがあるように見えるが、
内部にある全レコードの属性を全て表示しているに過ぎない。
実際のレコード毎の属性はバラバラである可能性あり。
データ検索の基本
DynamoDBはkey-valueなので、データ検索する際は基本的にkeyを使って検索する。
つまり、プライマリキー(PKかPK+SK)で検索するということ。
なお、SKを設定している場合、PKだけでも検索可能。その際は、複数レコードが引っかかる。
GSI (Global Secondary Index)
それ以外の検索方法(ex: 属性値で検索したい)が欲しい場合は、GSIを使う。
GSI = グローバルセカンダリインデックス
1つのテーブルに対してGSIは複数作れる。
GSIは、別角度からkey検索を行えるようにするもの。
GSIにもPKとSKを設定可能。これが検索用のkeyになる。
これらは、GSI-PK, GSI-SKと表現される。
なお、GSIにおいて、GSI-PKもしくはGSI-PKxGSI-SKは、ユニークである必要はない。
重複した場合、検索時に複数のアイテムが返ってくる。
一意性が必要なのは本体のプライマリキー(PKxSK)だけ。
GSIが作られた際、内部では本体とは別のデータ保存層が作られる。
本体のインデックスではなく、データのコピーが別の並び順で保存されるイメージ。
そのため:
ストレージコストが増える(データが複製されるから)
書き込みコストが増える(GSI分も書き込むから)
データ書き込みは本体からしかできない(GSIは読み取り専用)。
本体のプライマリキー(PKxSK)を指定して書き込む。
本体にデータが書き込まれたら、各GSIに「結果整合性」(通常~1秒以内)で自動同期される。
GSI-PKに指定した属性を持たないアイテムは、そのGSIには現れない。
例:emailをGSI-PKにした場合、email属性を持たない注文データはそのGSIに出てこない。
Inputログ
hr.icon
1. アクセスパターンをベースにしてデータモデリングを行う必要がある。RDSのように正規化を行うという手順は踏まない
2. 各パーティションにデータが分散するキー設計。ホットパーティションを発生させない
3. 基本的に複数データの読み込みや検索はGSIで表現する。GSIで対応しきれないケースは別テーブルに専用のデータを作るのもあり
なるほど?
「アクセスパターン」という言葉がどうやら重要そうだな。
q.icon RDSに比べて何が良かったのか
q.icon 他のNoSQLと比べて何がいいのか
q.icon DynamoDBの歴史は?
アクセスパターンに基づいてデータモデリングを行なうことが重要になります。具体的な手順としては以下のとおりです。
1.icon 必要なデータのエンティティとリレーションシップをまとめる
2.icon データのアクセスパターンをまとめる
3.icon テーブル設計
q.icon DynamoDBにおいて、プライマリキー、パーティションキー、ソートキーの関係と役割がわからない
q.icon GSI, LSIの関係と役割がわからない
なぜNoSQLなのか
言葉を選ばずに説明するとスキーマレスであるということです
なるほどonigiri.w2.icon
「スキーマレス」。つまり、スキーマの柔軟性は、NoSQLを見る上で重要かもな。確かに。
同じテーブルに入れるデータでも、持ってる属性が異なるデータを一緒に入れたいとかあるんかな。
ChatGPTに聞いた
スキーマレスは「柔軟性のため」というより、**「複数の種類のデータを戦略的に配置するため」**の機能なのです。
とのことです。なるほど
LLMに作ってもらったロードマップ
hr.icon
DynamoDB学習ロードマップ(改訂版)
フェーズ1: 思想と設計哲学 ✅完了
DynamoDBの根本思想(スケーラビリティと予測可能性)
アクセスパターン駆動設計
RDBとの哲学的な違い
NoSQLの中でのDynamoDBの位置づけ
フェーズ2: 基本構造 ✅完了
PKとSKの仕組み(物理的な配置)
スキーマレスの真の意味
Single Table Designの考え方
同じテーブルに異なるデータを入れる理由
テーブル定義とは何か
フェーズ3: 検索の拡張(GSI) ✅完了
GSI(Global Secondary Index)の役割
GSIと本体テーブルの違い
PKとSKのユニーク性
GSIの自動同期と結果整合性
書き込みは常に本体経由
フェーズ3.5: 検索の拡張(LSI) 🔲未着手
LSI(Local Secondary Index)とは
GSIとLSIの違い
なぜLSIは「テーブル作成時のみ」設定可能なのか
LSIの使いどころと制約
GSIとLSIの使い分け
フェーズ4: クエリ操作の基本 🔲未着手
Query vs Scan(なぜScanは避けるべきか)
Queryの条件式
フィルター式との違い
ページネーション(LastEvaluatedKey)
Getとの使い分け
フェーズ5: 容量とスループット 🔲未着手
RCU/WCU(読み書きキャパシティユニット)の概念
オンデマンドモードとプロビジョニングモード
なぜ「予測可能なパフォーマンス」が実現できるのか
コストモデルの考え方
パーティションとスループットの関係
フェーズ6: 制限事項と注意点 🔲未着手
アイテムサイズ制限(400KB)
パーティションのホットスポット問題
クエリ結果のサイズ制限(1MB)
GSI/LSIの制約
トランザクションの制約
フェーズ7: 設計パターン 🔲未着手
1対多の関係の表現方法
多対多の関係の表現方法
時系列データの扱い方
複合的なアクセスパターンへの対応
GSIとLSIを組み合わせた設計
フェーズ8: 実践的なトピック 🔲未着手
条件付き書き込み(楽観的ロック)
トランザクション
Streams(変更データキャプチャ)
TTL(Time To Live)による自動削除
バックアップとリストア
フェーズ9: アンチパターンとベストプラクティス 🔲未着手
やってはいけない設計
Scanを使わざるを得ない場合の対処
コスト最適化のポイント
監視とメトリクス
マイグレーション戦略