+ 作るログイン
1 / 19
AWS でサービスを作る ― 知識ゼロから、構成を自分で考えられるまで / 全32章

AWS 23:DynamoDB ― キーで引く、増え方に強いデータベース

発行
アニメモ公式
版
第2版
改訂
コマ
全19

Lambda が一斉に増えると、RDS の接続と書き込みが1台に集まって苦しくなります。キーを渡せばすぐに中身が返る DynamoDB の考え方、RDB との違い、パーティションキーとソートキー、Query と Scan、アクセスのしかたから設計する方法、GSI と整合性、オンデマンドの料金、フォトログのいいねを例にした設計と、RDS との使い分けを説明します。

いいねが一斉に押されると、RDS が苦しい

第22章で、フォトログの一部を Lambda に任せるようになりました。「いいね」の API も API Gateway + Lambda で作ったとします。

人気の投稿が話題になると、何千人もが一斉にいいねを押します。Lambda は、来た数だけすぐに増えます。ここで困ったことが起きます。

困りごと何が起きているか
接続数があふれる数百の Lambda の環境が、それぞれ RDS(第13章)に接続しようとする。RDS Proxy(第22章)で束ねても限りはある
書き込みは主の1台だけRDS の Multi-AZ の待機系は、ふだんは読み書きしない。リードレプリカも読むだけ。書き込みは主の1台に集まる
大きくするのが大変もっと大きなインスタンスにするには、切り替えの作業と短い停止が要る

一方で、いいねの読み書きをよく見ると、ある特徴があります。

処理聞き方
いいねを押す「投稿 p9 に、利用者 u2 のいいねを記録する」
いいね済みか調べる「投稿 p9 に、利用者 u2 のいいねはあるか」
数を出す「投稿 p9 のいいねの数は」

聞き方の形がいつも同じで、1回に扱うのは1件か数件です。複雑な集計や、いくつもの表をつなぐような処理はしていません。

こういう「形の決まった、とても多い読み書き」に向いた、別の種類のデータベースがあります。この章では Amazon DynamoDB を学びます。

※2026年9月時点の情報です。画面・料金・細部は変わることがあります。

  • AWS でサービスを作る 23 ― DynamoDB
  • 1 / 19
  • いいねが一斉に押されると、RDS が苦しい
  • 電気
  • 電気
  • NG
  • 接続数があふれる
  • 電気
  • 電気
  • 注意
  • データベース
  • NG
  • 書き込みは主の1台だけ
  • 電気
  • 電気
  • RDS
  • NG
  • 大きくするには止めて入れ替え
  • 接続の上限・書き込みの限界
  • 電気
  • 電気
  • しかも、いいねの読み書きは 形がいつも同じ
  • Lambda(数百)
  • ひらめき
  • Lambda が数百に増え、それぞれが RDS に「いいね」を書きに来る。接続も書き込みも1台に集まる。

一言でいうと:番号札で開ける、巨大なロッカー

第13章の RDS のようなRDB(リレーショナルデータベース=表の形でデータを持ち、SQL で問い合わせるデータベース)と比べてみます。

たとえ得意なこと苦手なこと
RDB図書館の司書「2026年の猫の写真で、いいねが多い順」のような、どんな聞き方にも答える司書(書き込みを受ける主の DB)は1人。混むと列ができる
DynamoDB番号札のロッカー番号札(キー)を持って来れば、何百万個あっても一瞬で開く。ロッカーは自動で増える番号札なしで「海の写真はどれ?」と探すこと

DynamoDB は、AWS が用意するキーバリュー型(キーを渡すと値が返る)のNoSQL データベース(SQL の表の形にこだわらないデータベースの総称)です。

いちばん大きな特徴は、データが何件になっても、キーで引く速さがほとんど変わらないことです。1,000件のときも10億件のときも、同じように速く返ります。そのために、置き場所を自動で分け、読み書きを多くの機械に散らしています。

もう1つの特徴は、サーバーレス(第22章)であることです。インスタンスの大きさも台数も選びません。接続も張らず、Lambda と同じように1回ずつ呼ぶだけです。

  • AWS でサービスを作る 23 ― DynamoDB
  • 2 / 19
  • 一言でいうと:番号札で開ける、巨大なロッカー
  • 検索
  • RDB(第13章)=図書館の司書
  • 鍵
  • DynamoDB = 番号札のロッカー
  • 「2026年の猫の写真で、いいねが多い順」
  • 番号札(キー)を持って来れば、
  • のような、どんな聞き方にも答えてくれる。
  • 何百万個あっても一瞬で開く。
  • ただし、司書は1人(主の DB)。
  • ロッカーは自動で増える。
  • 混むと列ができる
  • 番号札なしで探すのは苦手
  • 得意:SQL・集計・結合
  • 得意:キーで引く・自動で増える
  • ひらめき
  • キーを渡すとすぐ中身が返るデータベース。どれだけ大きくなっても速さが変わらない。

RDB との違い:自由に聞けるか、決まった形で速いか

違いを表で並べます。

RDS(RDB)DynamoDB
データの形表と列を先に決める。全部の行が同じ列を持つ項目ごとに属性が違ってよい。決めるのはキーだけ
聞き方SQL で、条件・並べ替え・表どうしの結合を自由に組み合わせるキーで引く(GetItem・Query)のが基本
増え方主の1台を大きくする。読むだけならレプリカを足す自動でパーティションを分けて、横に増える
つなぎ方接続を張って使う。接続数に上限があるHTTPS で1回ずつ呼ぶ。接続という考え方が無い
サーバーインスタンスの種類と大きさを選ぶ選ばない
得意集計・複雑な検索・結合大量で単純な読み書き

どちらが優れているということはありません。聞き方の自由さと規模が変わっても変わらない速さを交換している、と考えるとわかりやすいです。

RDB は「後から何でも聞ける」代わりに、データが増えるほど、また同時の書き込みが増えるほど、主の1台が苦しくなります。DynamoDB は「聞き方を先に決める」代わりに、どれだけ増えても同じ速さを保てます。

この交換があるので、DynamoDB では設計のしかたが RDB と逆向きになります。これが後で出てくる「アクセスパターンから設計する」の話です。

  • AWS でサービスを作る 23 ― DynamoDB
  • 3 / 19
  • RDB との違い:自由に聞けるか、決まった形で速いか
  • RDS(RDB)
  • DynamoDB
  • データの形
  • 表と列を先に決める
  • 項目ごとに属性が違ってよい
  • 聞き方
  • SQL で自由に組み合わせる
  • キーで引く(Query・GetItem)
  • 増え方
  • 主の1台を大きくする
  • 自動で分けて横に増える
  • つなぎ方
  • 接続を張って使う
  • HTTPS で1回ずつ呼ぶ
  • サーバー
  • インスタンスの大きさを選ぶ
  • 選ばない(サーバーレス)
  • 得意
  • 集計・複雑な検索・結合
  • 大量で単純な読み書き
  • ひらめき
  • RDB は後から何でも聞ける。DynamoDB は聞き方を先に決める代わりに、規模が変わっても同じ速さ。

テーブル・項目・属性:行ごとに中身が違ってよい

DynamoDB の言葉を覚えましょう。

言葉意味RDB でいうと
テーブル項目を入れる入れ物表
項目(アイテム)データの1件。1つの項目は最大 400 KB行
属性項目が持つ値。title・likes など列
パーティションキー(PK)項目の置き場所を決めるキー。必須—
ソートキー(SK)同じ PK の中での並び順を決めるキー。任意—

図の左は、photolog-posts テーブルに入っている投稿の項目です。青い文字が PK(USER#u1 のように「誰の投稿か」)、緑の文字が SK(投稿した日時)、黒い文字が title 属性です。

RDB と大きく違うのは、キー以外の属性を先に決めなくてよいことです。ある投稿は title と likes を持ち、別の投稿は title と place を持つ、ということができます。テーブルを作るときに決めるのは、PK と SK の名前と型だけです。

PK や SK の値に USER# のような印を付けているのは、後で同じテーブルに別の種類の項目(いいねなど)を入れたときに、何のキーかを見分けやすくするための、よく使われる工夫です。

  • AWS でサービスを作る 23 ― DynamoDB
  • 4 / 19
  • テーブル・項目・属性:行ごとに中身が違ってよい
  • テーブル photolog-posts
  • PK
  • SK
  • title
  • テーブル
  • 項目を入れる入れ物。photolog-posts
  • USER#u1
  • 2026-09-01
  • 夕焼け
  • 項目
  • 1行。投稿1件。最大 400 KB
  • USER#u1
  • 2026-09-03
  • 猫
  • 属性
  • 項目が持つ値。title・likes など
  • USER#u2
  • 2026-09-02
  • 海
  • PK
  • パーティションキー(必須)
  • USER#u3
  • 2026-09-02
  • ラーメン
  • SK
  • ソートキー(あってもなくてもよい)
  • USER#u2
  • 2026-09-05
  • 山
  • キー以外の属性は、項目ごとに違ってよい
  • ひらめき
  • テーブルには「項目」が入り、項目は「属性」を持つ。決めておくのはキーの属性だけ。

パーティションキー:どのロッカーの棚に入れるかを決める

DynamoDB は、データをパーティションという単位に分けて、たくさんの機械に置いています。どのパーティションに置くかを決めるのがパーティションキー(PK)です。

仕組みは次のとおりです。

順番起きること
1項目の PK の値(USER#u1 など)を、決まった計算(ハッシュ関数)にかける
2計算の結果で、置くパーティションが決まる
3同じ PK の値は、必ず同じパーティションに入る

図では、USER#u2 の投稿がパーティション A、USER#u3 が B、USER#u1 が C に入っています。前の図で表に並んでいた同じ項目が、それぞれの棚に移りました。

大事なのは、PK の値がばらけていることです。利用者が何万人もいて、PK が USER#… のように人ごとに違えば、読み書きはたくさんのパーティションに散らばり、全体として大量の読み書きをこなせます。

逆に、全部の項目の PK が同じ値だと、全部が1つのパーティションに集まり、そこだけが混みます(ホットパーティション)。1つのパーティションが受けられる読み書きの量には上限があるので、これは避けます。

パーティションの数は、データや読み書きが増えると DynamoDB が自動で増やします。あなたが台数を決めることはありません。

  • AWS でサービスを作る 23 ― DynamoDB
  • 5 / 19
  • パーティションキー:どのロッカーの棚に入れるかを決める
  • PK の値を計算にかけて、置くパーティションを決める(同じ値は必ず同じ場所)
  • パーティション A
  • パーティション B
  • パーティション C
  • USER#u2
  • 2026-09-02
  • 海
  • USER#u3
  • 2026-09-02
  • ラーメン
  • USER#u1
  • 2026-09-01
  • 夕焼け
  • USER#u2
  • 2026-09-05
  • 山
  • USER#u1
  • 2026-09-03
  • 猫
  • データや読み書きが増えると、DynamoDB が自動でパーティションを分けて増やす。あなたは台数を決めない
  • ひらめき
  • PK の値から置き場所(パーティション)が決まる。値がばらけていれば、読み書きが棚全体に散らばる。

ソートキー:同じ PK の中で、並んで入る

ソートキー(SK)を使うと、同じ PK の項目を、SK の順に並べて持てます。

図のパーティション C には、USER#u1 の投稿が3件、SK(日時)の順に並んでいます。新しく 2026-09-07 の「花」を投稿すると、一番後ろに並びます。

使い方できること
並びSK の順(昇順・降順)で取り出せる。「新しい順に20件」
範囲SK の範囲で絞れる。「9月1日以降」「2026-09 で始まる」
主キーPK と SK の組で、項目がただ1つに決まる

PK だけのテーブル(SK なし)もあります。その場合は PK だけで項目が1つに決まり、「キーを渡して1件取る」だけの使い方になります。

SK に日時を入れておくと、「ある人の投稿を新しい順に」「この期間のもの」という、よくある聞き方を1回の読み取りでこなせます。SK をどう作るかは、DynamoDB の設計でいちばん頭を使うところです。

  • AWS でサービスを作る 23 ― DynamoDB
  • 6 / 19
  • ソートキー:同じ PK の中で、並んで入る
  • PK の値を計算にかけて、置くパーティションを決める(同じ値は必ず同じ場所)
  • パーティション A
  • パーティション B
  • パーティション C
  • USER#u2
  • 2026-09-02
  • 海
  • USER#u3
  • 2026-09-02
  • ラーメン
  • USER#u1
  • 2026-09-01
  • 夕焼け
  • USER#u2
  • 2026-09-05
  • 山
  • USER#u1
  • 2026-09-03
  • 猫
  • USER#u1
  • 2026-09-07
  • 花
  • PK+SK の組が、項目を1つに決める主キー。SK には日時を入れると「期間で絞る」「新しい順」ができる
  • ひらめき
  • 同じ PK の項目は、SK の順に並んで同じ場所に入る。「この人の投稿を新しい順に」が一度で取れる。

Query:キーで引くから、どれだけ大きくても速い

DynamoDB の読み方には、主に3つあります。

読み方何を渡すか読む範囲
GetItemPK と SK(主キー全部)ぴったり1件
QueryPK と、SK の条件(任意)1つの PK の中の、条件に合う範囲
Scan何も渡さない(条件を付けても、読んだ後に絞るだけ)テーブル全部

図の上の命令は「PK が USER#u1 で、SK が 2026-09-01 以降」という Query です。DynamoDB は PK からパーティション C を計算で見つけ、そこに並んでいる u1 の投稿だけを読みます。黄色くなった3件です。

ここが DynamoDB の速さの秘密です。Query が読むのは、その PK の分だけです。テーブル全体の投稿が100件でも1億件でも、u1 の投稿が3件なら3件しか読みません。だから、規模が大きくなっても速さが変わりません。

料金も、読んだ量に対してかかります。必要なものだけを読む Query は、速いだけでなく安くもあります。1回の Query で返せるのは 1 MB までで、それを超えると続きを取るための印が返り、次のまとまりを取りに行きます。

  • AWS でサービスを作る 23 ― DynamoDB
  • 7 / 19
  • Query:キーで引くから、どれだけ大きくても速い
  • Query PK = "USER#u1" AND SK >= "2026-09-01"
  • パーティション A
  • パーティション B
  • パーティション C
  • USER#u2
  • 2026-09-02
  • 海
  • USER#u3
  • 2026-09-02
  • ラーメン
  • USER#u1
  • 2026-09-01
  • 夕焼け
  • USER#u2
  • 2026-09-05
  • 山
  • USER#u1
  • 2026-09-03
  • 猫
  • USER#u1
  • 2026-09-07
  • 花
  • 読むのはパーティション C の3件だけ。投稿が100万件になっても、u1 の分しか読まない
  • ひらめき
  • Query は「PK がこれで、SK がこの範囲」を1つの場所から読む。テーブル全体の大きさには関係しない。

Scan:全部の項目を読むので、大きくなると遅く高い

Scan は、テーブルの全パーティションの全項目を、端から順に読みます。

図の命令は「title に『海』を含むもの」を探す Scan です。条件に合うのは1件だけですが、DynamoDB は6件すべてを読んでから、条件に合うものだけを返します。赤くなっているのが、読まれた項目です。

QueryScan
読む範囲1つの PK の中テーブル全部
件数が増えると変わらない比例して遅くなる
料金読んだ分(少ない)全部読んだ分(多い)

Scan は、データの移行や、ときどきの点検のような場面では使います。でも、利用者のリクエストのたびに Scan する作りにしてはいけません。今は6件でも、投稿が100万件になれば、1回の表示のために100万件を読むことになり、遅く、高くなります。

「title で探したい」のように、キーではない属性で探す必要が出てきたら、それは設計を見直す合図です。キーの形を変えるか、次に出てくる GSI を作るか、全文検索は OpenSearch のような検索専用のサービスに任せます。

  • AWS でサービスを作る 23 ― DynamoDB
  • 8 / 19
  • Scan:全部の項目を読むので、大きくなると遅く高い
  • Scan (条件:title に「海」を含む)
  • パーティション A
  • パーティション B
  • パーティション C
  • USER#u2
  • 2026-09-02
  • 海
  • USER#u3
  • 2026-09-02
  • ラーメン
  • USER#u1
  • 2026-09-01
  • 夕焼け
  • USER#u2
  • 2026-09-05
  • 山
  • USER#u1
  • 2026-09-03
  • 猫
  • USER#u1
  • 2026-09-07
  • 花
  • 条件に合うのは1件でも、6件すべてを読んで料金を払う。100万件なら100万件を読む
  • ひらめき
  • Scan は全パーティションの全項目を読んでから絞る。読んだ分だけ料金もかかる。日常の処理で使わない。

設計は「どう読むか」の一覧から始める

ここまでで、DynamoDB は「キーで引く」ときに速く、それ以外は苦手だとわかりました。すると設計の順番が RDB と逆になります。

設計の順番
RDBデータの形(表と列)を先に決める → 聞き方は後から SQL で考える
DynamoDB聞き方(アクセスパターン)を先に全部書き出す → それぞれがキーで引けるように、キーの形を決める

図は、フォトログの聞き方の一覧です。

聞き方どう引くか
ある人の投稿を新しい順にQuery:PK=USER#u1、SK の降順
投稿1件を開くGetItem:PK と SK を指定
投稿のいいねの数投稿の項目に likes 属性を持たせておく
この人がいいね済みかGetItem:PK=POST#p9、SK=USER#u2
全体の新着(タイムライン)本体のキーでは引けない → GSI を作る

「いいねの数」は、いいねの記録を毎回数えるのではなく、数そのものを属性として持っておきます。RDB なら数えればよいところですが、DynamoDB では読むときに楽になるよう、書くときに手間をかけるのが基本の考え方です。

一覧に無い聞き方が後から出てくると、GSI を足したり、データを作り直したりすることになります。だからこそ、最初に聞き方を書き出すことが大事です。

  • AWS でサービスを作る 23 ― DynamoDB
  • 9 / 19
  • 設計は「どう読むか」の一覧から始める
  • フォトログの聞き方(アクセスパターン)
  • ある人の投稿を新しい順に
  • Query PK=USER#u1
  • 投稿1件を開く
  • GetItem PK+SK
  • 投稿のいいねの数
  • 項目の likes 属性
  • この人がいいね済みか
  • GetItem PK=POST#p9, SK=USER#u2
  • 全体の新着(タイムライン)
  • GSI(次に説明)
  • 聞き方ごとに「どのキーで引くか」が決まってから、テーブルとキーの形を決める
  • 一覧に無い聞き方は、後から足すのが大変(GSI を足すか、データを作り直す)
  • ひらめき
  • RDB は「データの形」から設計する。DynamoDB は「どんな聞き方をするか」を先に全部書き出す。

GSI:別のキーで引くための「もう1つの並び」

本体のテーブルは、PK=USER#… で並んでいるので「ある人の投稿」は得意ですが、「全員の投稿を新しい順に」は引けません。こういうときに使うのが GSI(グローバルセカンダリインデックス)です。

GSI は、同じ項目を別のキーで並べ直した写しです。

本体GSI
PKUSER#u1 など(誰の投稿か)FEED など(全体の新着の印)
SK日時日時
得意な聞き方ある人の投稿全体の新着

本体に項目を書くと、DynamoDB が自動で GSI にも写します。アプリは GSI を指定して Query するだけです。

GSI の注意点です。

注意内容
少し遅れる本体に書いてから GSI に写るまで、わずかに遅れる(結果整合性)。GSI の読み取りは強い整合性を選べない
料金が増える書き込みは GSI の分も数えられ、保存量も GSI の分だけ増える
数に上限1つのテーブルに作れる GSI の数には上限がある(既定で20)
偏り図のように全部を FEED 1つの値に集めると、そこだけが混む。実際は FEED#2026-09-29 のように日付で分けることが多い

RDB の「インデックス」に似ていますが、DynamoDB ではあらかじめ作った GSI の並びでしか引けない点が違います。これもアクセスパターンから設計する理由の1つです。

  • AWS でサービスを作る 23 ― DynamoDB
  • 10 / 19
  • GSI:別のキーで引くための「もう1つの並び」
  • 本体:PK=USER#… SK=日時
  • GSI:PK=FEED SK=日時
  • USER#u1 ・ 2026-09-01 ・ 夕焼け
  • FEED ・ 2026-09-03 ・ 猫
  • USER#u2 ・ 2026-09-02 ・ 海
  • 自動で写す
  • FEED ・ 2026-09-02 ・ 海
  • USER#u1 ・ 2026-09-03 ・ 猫
  • FEED ・ 2026-09-01 ・ 夕焼け
  • 「ある人の投稿」に強い
  • 「全体の新着」に強い
  • GSI への反映は少し遅れる(結果整合性)。書き込みは GSI の分も数えられ、保存量も増える
  • 1つの値(FEED)に集中させると、そこだけが混む。実際は日付などで分けることが多い
  • ひらめき
  • PK 以外で引きたいときは、グローバルセカンダリインデックス(GSI)を作る。書くと自動で写される。

読み取りの2つのモード:結果整合性と強い整合性

DynamoDB は、1つのリージョンの中の複数の AZ(第2章)に、データの写しを自動で持っています。1つの AZ が止まってもデータは失われず、読み書きも続けられます。

写しがあるので、書いた直後に読むと、まだ反映中の写しから古い値が返ることがあるという性質があります。図の3つ目の写しは、まだ likes = 10 のままです。

読み取りのモード内容使いどころ
結果整合性(既定)ほとんどの場合は最新。書いた直後だけ、まれに少し古いいいねの数の表示、一覧
強い整合性必ず最新の値。読み取りの単位を2倍使う書いた直後に必ず確かめたいもの

いいねの数が一瞬だけ1つ少なく見えても、困る利用者はいません。多くの場面は既定の読み取りで十分です。

もう1つ、トランザクションという機能もあります。「いいねの記録を書く」と「投稿の likes を1つ増やす」のように、複数の項目への書き込みを全部成功するか、全部しないかのどちらかにできます。途中で失敗して「記録はあるのに数が増えていない」を防げます。

  • AWS でサービスを作る 23 ― DynamoDB
  • 11 / 19
  • 読み取りの2つのモード:結果整合性と強い整合性
  • データベース
  • 写し 1
  • 結果整合性
  • 既定。安い。まれに古い
  • 11
  • アップロード
  • 書き込み
  • likes = 11
  • データベース
  • 写し 2
  • 強い整合性
  • 必ず最新。読み取り単位を2倍使う
  • 11
  • トランザクション
  • 複数の項目をまとめて全部か無しか
  • データベース
  • 写し 3
  • まだ 10(反映中)
  • データは1つのリージョンの複数の AZ に写して持つ。GSI の読み取りは結果整合性だけ
  • ひらめき
  • 既定の読み取りは、書いた直後だと少し古い値が返ることがある。必要な所だけ「強い整合性」で読む。

料金とモード:オンデマンドから始める

DynamoDB は、インスタンスの時間ではなく、読み書きの量と保存量に対して払います。読み書きの量の数え方には2つのモードがあります。

モード払い方向くとき
オンデマンド読み書きしたリクエストの分だけ払う。準備なしで増減に合わせる量がわからない、波がある、始めたばかり。まずはこれ
プロビジョンド1秒あたりに読み書きできる量を先に決めて、その分を時間で払う。自動調整も可量が安定していて予測できる

2024年11月にオンデマンドの単価が大きく下がり、AWS は多くの場合にオンデマンドを勧めています。迷ったらオンデマンドで始め、量が安定してから比べるのがよいでしょう。

課金されるものを並べます。

何に数え方
読み書き読んだ量・書いた量。大きな項目は、1回でも何単位分にもなる。強い整合性の読み取りやトランザクションは多めに数えられる
保存量GB・月。GSI の分も含む
オプションPITR のバックアップ、Streams の読み取り、他のリージョンへの写し(グローバルテーブル)、データの書き出し

プロビジョンドのモードには、期限なしで毎月使える無料枠があります(オンデマンドには適用されない)。細かい単価と無料枠の条件は、料金ページと Pricing Calculator(第4章)で確認しましょう。

  • AWS でサービスを作る 23 ― DynamoDB
  • 12 / 19
  • 料金とモード:オンデマンドから始める
  • 電気
  • オンデマンド
  • 設定
  • プロビジョンド
  • 読み書きした回数だけ払う。準備なしで増減
  • 1秒あたりの量を先に決める。自動調整も可
  • 読み書き
  • 読んだ・書いた量(大きな項目は何単位分にもなる)
  • 保存量
  • GB・月。GSI の分も含む
  • オプション
  • バックアップ(PITR)・Streams の読み取り・リージョン間の写し
  • 無料枠
  • プロビジョンドには期限なしの無料枠がある(条件は公式の料金表で)
  • ひらめき
  • 払うのは「読み書きの量」と「保存量」。台数も大きさも選ばない。迷ったらオンデマンドで始める。

便利な機能:TTL・Streams・PITR・グローバルテーブル

DynamoDB には、周りの仕事を減らす機能がそろっています。

機能何をするかフォトログの例
TTL(有効期限)項目に「この日時を過ぎたら消してよい」という属性を持たせると、期限切れの項目を自動で消す。消すのに料金はかからない。期限ちょうどではなく、少し後で消える24時間で消える「ストーリー」、ログインの一時的な記録
DynamoDB Streams項目の追加・変更・削除を、順に流す。Lambda(第22章)で受け取れるいいねが増えたら、投稿者に通知する
PITR(ポイントインタイム復旧)1〜35日前までの、好きな秒の状態に戻せる誤って消したデータを戻す
グローバルテーブル複数のリージョンに同じテーブルを持ち、どこからでも書ける世界中に利用者が広がったとき(第29章)

とくに PITR と 削除保護(テーブルを誤って消せないようにする設定)は、本番のテーブルでは必ずオンにしておきましょう。DynamoDB は AZ の故障には強いですが、人の誤操作やプログラムの間違いで消したデータは、バックアップが無いと戻せません。

Streams は、第24章で学ぶ「イベントで仕事をつなぐ」考え方の入口でもあります。

  • AWS でサービスを作る 23 ― DynamoDB
  • 13 / 19
  • 便利な機能:TTL・Streams・PITR・グローバルテーブル
  • 時計
  • TTL(有効期限)
  • 電気
  • DynamoDB Streams
  • 期限の過ぎた項目を自動で消す。消すのに料金はかからない
  • 項目の変更を順に流す。Lambda で受けて通知・集計
  • 更新
  • PITR(ポイントインタイム復旧)
  • インターネット
  • グローバルテーブル
  • 1〜35日前までの好きな秒に戻せる
  • 複数のリージョンに同じテーブルを持つ(第29章)
  • 本番のテーブルでは PITR と削除保護をオンにしておく
  • ひらめき
  • TTL で自動削除、Streams で変更を Lambda へ、PITR で誤操作から戻す。

作り方:テーブルを作り、SDK で読み書きする

コンソールで作る場合は、次の手順です。

手順すること
1テーブル名(photolog-posts)を決める
2パーティションキー(PK・文字列)とソートキー(SK・文字列)を決める
3容量のモードを選ぶ(オンデマンド)
4作った後で、PITR と削除保護をオンにする

列の一覧を作る手順はありません。キー以外の属性は、書き込むときに自由に入れられます。

図の左は AWS CDK で同じことを書いた例、右はアプリ(Node.js の AWS SDK)から Query する例です。

右のコードの行意味
KeyConditionExpression「PK が :u と等しい」という条件
ExpressionAttributeValues:u に USER#u1 を入れる
ScanIndexForward: falseSK の降順(新しい順)。名前に Scan と付いているが Scan ではない
Limit: 2020件まで

RDS と違い、接続を張りません。1回ごとに HTTPS でリクエストを送り、許可は IAM(第3章)で決めます。Lambda の実行ロール(第22章)に「このテーブルに Query と PutItem をしてよい」と書けば、パスワードも要りません。Lambda が何百に増えても、接続数の問題は起きません。

  • AWS でサービスを作る 23 ― DynamoDB
  • 14 / 19
  • 作り方:テーブルを作り、SDK で読み書きする
  • 作る(CDK)
  • 読み書きする(アプリ)
  • new dynamodb.TableV2(this, "Posts", {
  • // ある人の投稿を新しい順に20件
  • partitionKey: { name: "PK", type: AttributeType.STRING },
  • await ddb.send(new QueryCommand({
  • sortKey: { name: "SK", type: AttributeType.STRING },
  • TableName: "photolog-posts",
  • billing: Billing.onDemand(),
  • KeyConditionExpression: "PK = :u",
  • pointInTimeRecovery: true,
  • ExpressionAttributeValues: { ":u": "USER#u1" },
  • });
  • ScanIndexForward: false, Limit: 20,
  • }));
  • 接続は張らない。1回ごとに HTTPS で呼び、IAM(第3章)で許可する。Lambda(第22章)と相性がよい
  • ひらめき
  • 作るときに決めるのは、テーブル名・PK・SK・モードだけ。列の一覧は要らない。

フォトログでは:いいねと投稿の一覧を DynamoDB に

フォトログでは、次のように使い分けます。

データ置き場所理由
いいねの記録DynamoDB photolog-likes大量・形が決まっている・急に増える
投稿と、いいねの数DynamoDB photolog-posts「ある人の投稿」「新着」の聞き方が決まっている
利用者の情報・支払いRDS項目が多く、後から聞き方が増える。厳密さが大事
管理者向けの集計RDS や分析用の仕組み自由な集計は RDB の得意分野

いいねの関数は、次の2つの書き込みをします。

書き込み工夫
いいねの記録を書く(PK=POST#p9、SK=USER#u2)「まだこのキーが無ければ書く」という条件付き書き込みにする。同じ人が2回押しても、2回目は断られる
投稿の likes を1つ増やす「読んで、1足して、書く」ではなく、「1 足す」(ADD)という更新を頼む。同時に何人が押しても数が合う

2つをトランザクションでまとめれば、「記録はあるのに数が増えていない」も防げます。

「読んで足して書く」をしてはいけない理由は、2人が同時に「10」を読み、2人とも「11」を書くと、2回押されたのに1しか増えないからです。DynamoDB に計算を任せれば、この問題は起きません。

  • AWS でサービスを作る 23 ― DynamoDB
  • 15 / 19
  • フォトログでは:いいねと投稿の一覧を DynamoDB に
  • photolog-likes(いいね済みの記録)
  • PK=POST#p9 SK=USER#u2
  • リンク
  • 電気
  • 同じ人の2回目は「条件付き書き込み」で断る
  • API Gateway
  • いいね関数
  • photolog-posts(投稿)
  • likes 属性を「1 足す」(ADD)で更新
  • RDS(第13章)には
  • 読んで・足して・書く、をしない
  • 利用者・支払い・集計を残す
  • ひらめき
  • いいねのように「形が決まっていて量が多い」ものは DynamoDB、利用者の情報や集計は RDS。混ぜて使う。

RDS と比べる:いつ DynamoDB を選ぶか

判断の問いにまとめます。

問いDynamoDBRDS
聞き方は決まっているか少なく、決まっている後から増える・変わる
量と増え方は急に大量に来る・どこまでも増える主の1台で足りる
集計や結合は要るかほとんど要らない多い
誰から呼ぶかLambda からたくさん常駐のサーバーやタスクから
チームの知識キー設計を学ぶ気があるSQL に慣れている

1つのサービスで両方を使うのはふつうです。フォトログのように、大量で形の決まったもの(いいね・投稿の一覧)は DynamoDB に、関係が複雑で聞き方が変わるもの(利用者・支払い・集計)は RDS に置きます。

迷ったときは、RDS で始めるのが無難です。聞き方が固まっていない作りたてのサービスでは、SQL の自由さが役に立ちます。そのうえで、特定の処理だけが一気に増えて苦しくなったら、その部分を DynamoDB に移す、という進め方がよく取られます。

なお、「サーバーレスで SQL を使いたい」なら、Aurora Serverless(第13章の Aurora の使い方の1つ)という選択肢もあります。

  • AWS でサービスを作る 23 ― DynamoDB
  • 16 / 19
  • RDS と比べる:いつ DynamoDB を選ぶか
  • DynamoDB を選ぶ
  • RDS を選ぶ
  • OK
  • 聞き方が少なく、決まっている
  • OK
  • 聞き方が後から増える・変わる
  • OK
  • 急に大量に来る・どこまでも増える
  • OK
  • 集計・並べ替え・複数の表の結合
  • OK
  • Lambda からたくさん呼ぶ
  • OK
  • SQL を知っている人が多い
  • OK
  • サーバーの世話をしたくない
  • OK
  • お金の記録など厳密な整合性
  • ひらめき
  • 聞き方が決まっていて量が多い・急に増えるなら DynamoDB。聞き方が変わる・集計が多いなら RDS。

よくある落とし穴

DynamoDB の事故の多くは、RDB と同じつもりで使うことから起きます。

落とし穴何が起きるか防ぎ方
RDB と同じ表の分け方で作る1つの画面を出すのに、何回も読みに行く聞き方の一覧から設計し直す
日常の処理で Scan する件数に比例して遅く、高くなるQuery で引けるキーにするか GSI を作る
PK の値が偏る1つのパーティションだけが混み、断られる(スロットリング)値がばらける PK にする。人気の1件に集まるなら分ける工夫をする
読んでから足して書く同時に押されると数が合わないADD の更新や条件付き書き込みを使う
大きなデータを項目に入れる1項目 400 KB の上限に当たる。読み書きの料金も増える写真は S3(第15章)に置き、項目には場所(キー)だけを入れる
PITR をオフのまま誤って消したデータが戻せない本番は PITR と削除保護をオン
GSI を作りすぎる書き込みと保存の料金が GSI の数だけ増える聞き方の一覧で本当に要るものだけ

どれも「作る前に聞き方を書き出す」を守れば、多くを避けられます。

  • AWS でサービスを作る 23 ― DynamoDB
  • 17 / 19
  • よくある落とし穴
  • NG
  • RDB と同じ表の分け方で作る → 聞くたびに何回も読む。聞き方から設計し直す
  • NG
  • 日常の処理で Scan する → 件数に比例して遅く高くなる。Query で引けるキーにする
  • NG
  • PK の値が偏る(全部 "FEED" など)→ 1つのパーティションだけが混む
  • NG
  • 読んでから足して書く → 同時に押されると数が合わない。ADD や条件付き書き込みで
  • NG
  • 大きな写真を項目に入れる → 400 KB の上限。写真は S3、項目には場所だけ
  • NG
  • PITR をオフのまま → 誤って消すと戻せない
  • ひらめき
  • RDB と同じつもりで作らない。Scan をしない。1つのキーに集めない。最初に聞き方を書き出す。

片付け:テーブルを消す前に、削除保護と写しを確かめる

練習で作ったテーブルは、次の順で消します。

順番すること注意
1削除保護をオフにするオンのままだと消せない(それが目的の設定)
2Streams につないだ Lambda を外すつないだまま消すと、失敗が記録され続ける
3テーブルを削除中の項目も GSI も一緒に消える。元には戻せない
4残したバックアップを確かめて消す削除のときに最後のバックアップを作る選択肢がある。作った場合は、それも保存料がかかる

オンデマンドのテーブルは、読み書きしなければ保存量の分しかかかりません。とはいえ、使わないテーブルは消しておきましょう。

本番では逆に、削除保護はオンのままにしておきます。テーブルを消す操作は、IaC(第18章)で差分を見て、意図したものかを確かめてから行います。コンソールで手で消すのは、事故のもとです。

  • AWS でサービスを作る 23 ― DynamoDB
  • 18 / 19
  • 片付け:テーブルを消す前に、削除保護と写しを確かめる
  • 盾
  • 削除保護をオフにする
  • 注意
  • 本番では逆に
  • 電気
  • Streams につないだ Lambda を外す
  • 削除保護はオンのまま。
  • 消す操作は IaC(第18章)で
  • データベース
  • テーブルを削除(GSI も一緒に消える)
  • 差分を見てから行う
  • 更新
  • 残したバックアップを確かめて消す
  • ひらめき
  • テーブルを消すと中身も GSI も消える。バックアップは別に残るので、要らなければそれも消す。

まとめ:聞き方を先に決めれば、どこまでも同じ速さ

この章で学んだことをまとめます。

項目内容
DynamoDBキーで引く、サーバーレスのデータベース。規模が変わっても速さが変わらない
PK・SKPK で置き場所(パーティション)、SK で並び。PK+SK で項目がただ1つに決まる
Query と ScanQuery はキーで必要な範囲だけ読む。Scan は全部読む(日常の処理では使わない)
設計聞き方(アクセスパターン)を先に全部書き出し、キーの形を決める
GSI別のキーでの並び。自動で写るが、少し遅れる
料金読み書きの量 + 保存量。まずはオンデマンド
いつ選ぶか形が決まっていて量が多い・急に増える。RDS と混ぜて使う

いいねは、何千人が一斉に押しても受け止められるようになりました。でも、新しい要望が出てきます。

「いいねされたら、投稿者に通知を送りたい」「いいねの数を集計して、おすすめを更新したい」「人気の投稿を運営者に知らせたい」。これを全部、いいねの API の中でやると、どうなるでしょうか。利用者はいいねを押してから、通知の送信や集計が終わるまで待たされます。しかも、通知のサービスが一瞬止まっていたら、いいね自体が失敗してしまいます。

次の第24章では、仕事を「後回し」にして利用者を待たせず、失敗しても確実にやり直せるようにする SQS・SNS・EventBridge を学びます。

  • AWS でサービスを作る 23 ― DynamoDB
  • 19 / 19
  • まとめ:聞き方を先に決めれば、どこまでも同じ速さ
  • DynamoDB
  • キーで引く、サーバーレスのデータベース。規模が変わっても速い
  • PK・SK
  • PK で置き場所、SK で並び。PK+SK で項目が1つに決まる
  • Query と Scan
  • Query はキーで引く。Scan は全部読む(日常では使わない)
  • 設計
  • 聞き方(アクセスパターン)を先に全部書き出す
  • GSI
  • 別のキーでの並び。少し遅れて写る
  • 料金
  • 読み書きの量 + 保存量。まずオンデマンド
  • 通知
  • 次の困りごと:いいねのたびに通知や集計までその場でやると、利用者を待たせる
  • ひらめき
  • いいねの後に、通知・集計・おすすめ更新…とやることが増えると、利用者を待たせる。 → 第24章。

0 件のコメント

読み込み中…

権利侵害・不適切な内容の連絡: [email protected]