>100 Views
January 31, 26
スライド概要
DynamoDBの入門から一歩踏み込んだ複合ソートキーやGSI、排他制御での利用について発表しました。
SFとコンピュータが好き
2026-01-28 AWSランチセッション 第14回 実務で役立つDynamoDBの使い方 ― インデックスと排他制御 ― 山崎 拓也
山崎 拓也 所属: SIer 仕事: • AWS案件のアプリやインフラのリード • 社内AWSサポート 好き: 低レイヤ、SF、AWS AWS関連: • 2024~2025 Japan AWS Top Engineer • 2022~2025 Japan All AWS Certifications Engineer
今日話さないこと • DynamoDB Transactions • DynamoDB Streams • DynamoDB Accelerator (DAX) • DynamoDB Global Tables
DynamoDBはデータをPartitionKeyで分散し、SortKeyでソートする Partitions and data distribution in DynamoDB:https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.Partitions.html
クエリに強く、スキャンに弱い • クエリはPKの指定が必須。必要なパーティションだけを読む • スキャンは全てのパーティションを読むため効率が悪い
クエリに強く、スキャンに弱い • クエリはPKの指定が必須。必要なパーティションだけを読む • スキャンは全てのパーティションを読むため効率が悪い
クエリに強く、スキャンに弱い • クエリはPKの指定が必須。必要なパーティションだけを読む • スキャンは全てのパーティションを読むため効率が悪い
フィルターは効率が悪いのでクエリにはPKとSKを使う • filter-expressionはサーバー側で結果から不要なアイテムを捨てる動作 • 不要なアイテムも読むので遅い • 料金も余計にかかる
設計時にクエリの仕方を考慮すると強みを活かせる • 主にユーザー別にクエリする場合、PKはuserId • 日付の範囲で絞りたい場合、SKはeventDate userId (PK) eventDate (SK) eventType Dog 2021-05-03 login Cat 2023-10-03 view Dog 2022-03-25 login Dog 2025-01-28 view Cat 2022-04-02 logout
PKとSKを使ったクエリ例 • ユーザーID「Dog」の、2022~2026年のイベントを取得する userId = Dog eventDate BETWEEN 2022 AND 2026 userId (PK) eventDate (SK) eventType Dog 2021-05-03 login Cat 2023-10-03 view Dog 2022-03-25 login Dog 2025-01-28 view Cat 2022-04-02 logout • Dogの2020~2023年のloginイベントだけを取得したい・・・
複合SKを使うと、より柔軟にクエリできる • [eventType]#[eventDate] のように、複数の情報からひとつのSKを作る userId (PK) eventDate (SK) eventType Dog login#2021-05-03 login Cat view#2023-10-03 view Dog login#2022-03-25 login Dog view#2025-01-28 view Cat logout#2022-04-02 logout
複合SKのクエリ例 userId (PK) • Dogのviewイベントを取得する userId = Dog begins_with(eventDate, view#) eventDate (SK) Dog login#2021-05-03 login Cat view#2023-10-03 view Dog login#2022-03-25 login Dog view#2025-01-28 view Cat logout#2022-04-02 logout • Dogの2020~2023年のloginイベントを取得する userId = Dog eventDate BETWEEN login#2020 AND login#2023 userId (PK) eventType eventDate (SK) eventType Dog login#2021-05-03 login Cat view#2023-10-03 view Dog login#2022-03-25 login Dog view#2025-01-28 view Cat logout#2022-04-02 logout
範囲を絞っていくような複合SKにもできる • [country]#[region]#[state]#[county]#[city]#[neighborhood] 国 begins_with(sk, country#) 地域 begins_with(sk, country#region#) 州 begins_with(sk, country#region#state#) 群 begins_with(sk, country#region#state#county#) 市 begins_with(sk, country#region#state#county#city#) 地区 country#region#state#county#city#neighborhood • しかしPKは依然として完全一致が必要・・・ Best practices for using sort keys to organize data in DynamoDB: https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-sort-keys.html
PK以外でクエリしたい場合はGlobal Secondary Index (GSI) • GSIはRDBのインデックスと異なり、自動同期される別テーブル • コストを抑えるには必要な項目のみをプロジェクションする userId (PK), eventDate (SK) eventType (PK), eventDate (SK)
GSIのクエリ例 • ベーステーブルでは特定イベントをクエリできない (PKがユーザーIDのため) • GSIで2020~2023年のloginイベントをクエリする eventType = login eventDate BETWEEN 2020 AND 2023 eventType (PK) eventDate (SK) userId login 2021-05-03 Dog view 2023-10-03 Cat login 2022-03-25 Dog view 2025-01-28 Dog logout 2022-04-02 Cat
GSIでは4つの項目までSKを設定できる • ベーステーブルの複合SKと仕組みは変わらないのでクエリの柔軟性は 変わらない
DynamoDBを排他制御のロックとして使うこともできる • ロック取得: 条件付き書き込みでアイテム作成 • attribute_not_exists(resourceId) OR expiresAt < :now • DynamoDBの書き込みは強整合性 • ロック解放: アイテム削除 • 削除失敗に備えて有効期限を示す項目も作る • 使用されていないitemを掃除するためにTTLも併用する • TTL削除は最大48時間かかるためロックの有効期限には使えない resourceId (PK) expiresAt (TTL) ownerId item-100 1769547943 Dog item-200 1769893543 Cat
DynamoDBを排他制御のロックとして使うこともできる(図) ❷ ❶ ❶ ❷ ❷ ❸ resourceId (PK) ほね expiresAt 1769547943 ownerId resourceId (PK) Dog ほね expiresAt 1769893543 ownerId Cat
まとめ • DynamoDBは設計時にクエリの仕方を考慮すると強みを活かせる • 排他制御の選択肢としてDynamoDBもあり
ご清聴ありがとうございました。