パーティションキーとソートキーの役割と共に Amazon DynamoDB のプライマリキーについて学ぼう

2024-04-02
デベロッパーのためのクラウド活用方法

Author : 杉本 圭太

テクニカルインストラクターの杉本圭太です !
最近読んで面白かった漫画は「君と宇宙を歩くために」です。

私が担当するトレーニングの中には Amazon DynamoDB について紹介するコースもあるのですが、リレーショナルデータベース (RDB) の知識がある方でも、DynamoDB 特有の用語や仕組みの理解に苦労される方は少なくないと感じます。その中でも DynamoDB のコアコンポーネントのページ に記載されている「プライマリキー」は、「パーティションキー」や「ソートキー」と併せて理解が必要なため、学び始めの方が混乱しやすい用語の 1 つです。

そこで今回は「Amazon DynamoDB がフルマネージドな NoSQL データベースであることくらいは聞いたことあるけど…」な方を対象に、私なりに描いた図や、トレーニング中に使用する例と比喩などを交えながら、DynamoDB のプライマリキーに焦点を当てた説明をしていきます。この記事を読んで、DynamoDB を使い始める第一歩目を踏み出してみましょう !

※ この記事で挙げるテーブル設計やプライマリキーの例は、あくまで用語を理解してもらうことを優先して用意した例であり、実際に DynamoDB を扱う場合に推奨する設計例として挙げているものではありません。

DynamoDB を初めて聞くという方は、高速で柔軟な NoSQL データベースサービス。Amazon DynamoDB をグラレコで解説 に目を通して概要を把握いただくのもおすすめです !


1. Amazon DynamoDB の基本となる構成要素

まずは DynamoDB の大まかな仕組みについて把握するため、押さえておきたい用語がこちらです。

  • テーブル
  • 項目 (Item)
  • 属性 (Attribute)
  • プライマリキー

1-1. テーブル

「テーブル」はデータの集まりです。DynamoDB を使用するためには、最初にテーブルを作成する必要があります。テーブル作成時にはテーブル名や使用するリージョン、後ほど紹介するプライマリキーなどを設定します。ストレージの容量やサーバー台数などは考慮しなくて良いです。

例えばとあるショッピングサイトを作る場合、商品データの管理用に Product テーブル、ユーザーのデータ管理用に User テーブルを作るなどが挙げられます。

1-2. 項目 (Item)

DynamoDB のテーブルに入れるデータを「項目 (Item)」と呼びます。テーブルを作った時点では項目はゼロですが、テーブルには複数の項目を追加していけます。

ショッピングサイトの例の場合、1 つの商品データを 1 つの項目として Product テーブルに保存するという使い方ができます。ユーザーのデータを商品とは別で扱いたい場合は User テーブルに項目を保存してます。

1-3. 属性 (Attribute)

DynamoDB の項目は、1 つ以上の「属性 (Attribute)」で構成されています。Product テーブルに入れる項目の属性の例としては、商品 ID (ProductID)、商品名 (Name)、商品分類 (Category) などです。

属性は「属性名と属性値 (と 属性値のデータ型)」で構成されていて、項目に複数の属性を含められます。商品データを表すそれぞれの項目で商品名 (Name) の値を別にすることで、どの商品のデータであるかが分かります。属性は項目ごとに追加できるため、同じテーブル内の全ての項目が同じ属性を持っている必要はありません。例えば Product テーブルの中で商品名が “Good bicycle” の項目にだけ、“Material” という属性を持たせても問題ありません。

1-4. プライマリキー

DynamoDB ではテーブル内のデータを扱うため、特定の 1 つの項目を識別する「プライマリキー」を使用しますテーブルの作成時には「キー名が xxx で、その値のデータ型が xxx の属性をプライマリキーにする」と決めておく必要があります。Product テーブルの例だと「キー名は ProductID で、値のデータ型は文字列 (String) 型になるものをプライマリキーにする」のような指定です。

そしてテーブルに項目を挿入 (PutItem) する場合は必ずプライマリキーを含めなければなりません。Product テーブルでプライマリキーを ProductID にした場合だと、項目には必ず ProductID を含めるということです。プライマリキーの値が同じであればテーブル内では同じ項目として扱われるため、Product テーブルに 3 つの項目を入れたい場合は 3 つの異なる ProductID の値が必要です。

また、項目の取得 (GetItem)、更新 (UpdateItem)、削除 (DeleteItem) などの操作をしたい場合も、プライマリキーを指定することで特定の項目を対象にできます。


2. Amazon DynamoDB のプライマリキーの設定方法は 2 種類ある

ここからがつまずきやすいポイントなのですが、DynamoDB ではテーブル作成時にプライマリキーの構成を以下のどちらにするか選択します。

  • 1 つのキー (パーティションキー) のみをプライマリキーにするテーブル
  • 2 つのキーの組み合わせ (パーティションキーとソートキー) をプライマリキーにするテーブル

新しく「パーティションキー」と「ソートキー」という用語が出てきましたが、混乱しないようにしましょう !
これらの用語の意味と関係性を理解するために、本 (Book) を管理するテーブルの例や、喩え話を出しながら説明していきます。

2-1. 1 つのキー (パーティションキー) のみをプライマリキーにする

本を管理するシステムを構築するためにデータベースを DynamoDB を選択し、Book テーブルを作ると考えましょう。この後の説明にも繋げるため、ここではプライマリキーを本のタイトル (Title) にしてみます。

φ(•ᴗ•๑) 用語の確認 !!

  • DynamoDB では 1 つのキーのみをテーブルのプライマリキーにする場合、そのキーをパーティションキーと呼ぶ
テーブル名 プライマリキー
Book パーティションキー: Title、ソートキー: なし

つまり Book テーブルの例の場合「パーティションキーである Title が、テーブルのプライマリキーである」とも言えます。この場合のテーブルには、プライマリキーにソートキーという用語は出てきません。

そしてパーティションキーは、DynamoDB の仕組みとしてデータの保管に関わる役割を持っています。

φ(•ᴗ•๑) パーティションキーの役割を確認 !!

  • DynamoDB のテーブルはデータを複数のパーティション (物理的なストレージ) を使って保存しており、パーティションキーの値から計算したハッシュ値によって保存先のパーティションを分散 して配置する
  • 「パーティションの数をどれくらいにするか」「どの項目をどのパーティションに保存するか」は DynamoDB が自動で調整してくれるため、ユーザーは複雑な管理を意識しなくて良い
  • データが複数のパーティションに分散されるため、テーブルに保存できるデータ量やスループットを上げたい場合は、パーティションを増やすスケールアウトで対応できる仕組みになっている

データベースの運用経験が少ない方向けに DynamoDB の特徴を説明するため、実際に書庫で多くの本を管理する場面に喩えるならこんな感じでしょうか。

  • 大量の本を管理する時、1 つの大きな本棚で頑張るのではなく複数の本棚に分けて本を管理できる
  • 本棚の大きさ、本棚の数を何個用意するか、どの本棚にどの本を配置するかは本棚の管理者が必要に応じて行ってくれるため、本の所有者は面倒な本棚の管理を考えなくても良い
  • 書庫に保管する本の数が増えても後から本棚を増やせば対応できるため、1 つの本棚しか使えない場合と比べて、本棚の大きさに限界があるという制限を受けない

ちなみにパーティションのデータはそれぞれ、複数のアベイラビリティゾーン (AZ) で冗長化されています。

ではこの Book テーブルで多くの本を管理するデータベースが実現できたでしょうか ?

この構成で十分な要件もあるかもしれませんが、Title というパーティションキーのみをプライマリキーにした場合、もし同じタイトルの本が複数あった場合はどうなるでしょう ?

今回の Book テーブルの設計だと、作者が違うけどタイトルは同じ本や、複数の巻があるような本はそれぞれ別のデータとして扱えません。プライマリキーの Title の値が同じなら、同じ項目になってしまうからです。
※ 本に BookID を付与してそれをプライマリキーにするなどの方法で対応することもできますが、今回は次のソートキーの説明に繋げるため考えないことにします。

また、パーティションキーのみがプライマリキーのテーブルでは、データの取得方法は 2 つしかありません。

  • GetItem でパーティションキーの値を指定して 1 つの項目を取得
  • Scan でテーブルの全ての項目を読み込む

書庫から本を取り出そうとする場合で喩えるなら、1 度の出入りでは特定の 1 冊を取り出すか、全ての本を持ってこようとするかしかできないような状態です。
※ 今回の記事では紹介しませんが セカンダリインデックス をテーブルに設定すれば、他の条件でデータが取得可能です。

2-2. 2 つのキーの組み合わせ (パーティションキーとソートキー) をプライマリキーにする

漫画のような同じタイトルで複数の巻を持つことが多い本を管理するシステムを構築するため、先ほどの Book テーブルのことは一度忘れて別途 Comic テーブルを作るとします。DynamoDB では 2 つのキーの組み合わせをプライマリキーにできるため、Comic テーブルのプライマリキーは本のタイトル (Title) と、巻数 (Volume) の組み合わせにしようと考えました。
※ この場合は Title と Volume が同じで作者が異なるようなデータは管理できない点はご注意ください。

φ(•ᴗ•๑) 用語の確認 !!

  • DynamoDB では 2 つのキーの組み合わせでプライマリキーを構成する場合、1 つをパーティションキー、もう 1 つをソートキーとして設定する
  • パーティションキーとソートキーの組み合わせのプライマリキーは「複合プライマリキー」と呼ぶこともある

この後ソートキーの仕組みを比喩を交えて説明するため、今回は Title をパーティションキー、Volume をソートキーにしてみます。

テーブル名 プライマリキー
Comic パーティションキー: Title、ソートキー: Volume

複合プライマリキーの Comic テーブルの場合、以下の 3 つの項目はパーティションキーの Title が同じでも、異なる項目として扱います。この 3 つの項目は、先ほどの Book テーブルでは Title の値が同じため 1 つのテーブルで別項目として扱えませんでした。

{“Title”: “AWS Quest”, “Volume”, 1, “ReleaseDate”: “2024-01-01”, ...}
{“Title”: “AWS Quest”, “Volume”, 2, “ReleaseDate”: “2024-03-01”, ...}
{“Title”: “AWS Quest”, “Volume”, 3, “ReleaseDate”: “2024-04-01”, ...}

先ほどパーティションキーの役割で説明したのと同じで、複合プライマリキーでもパーティションキーの値は保存先のパーティションを分散するために使われます。ここで知っておきたいのが、複合プライマリキーのソートキーの役割です。

φ(•ᴗ•๑) ソートキーの役割を確認 !!

こちらも実際に書庫で多くの本を管理する場面に喩えるならこんな感じでしょうか。

  • 大きな書庫の中でも、同じタイトルの本は同じ本棚か近くで順番に並べられている
  • 同じタイトルの本であれば、巻数の範囲を指定して 1 度にまとめて持って来れる

複合プライマリキーの場合のデータ取得方法を整理します。パーティションキーのみがプライマリキーのテーブルと比べて、ソートキーの範囲を指定したデータ取得 (Query) が増えました !

  • GetItem でパーティションキーとソートキーの値を指定して 1 つの項目だけを取得
  • Scan でテーブルの全ての項目を読み込む
  • Query でパーティションキーの値のみを指定して、特定のパーティションキーの値を持つ項目を全て取得
  • Query でパーティションキーの値を指定したうえで、ソートキーに「等しい、以上、以下、より大きい、より小さい、特定の値の間」などの 条件を指定して 該当する項目を 1 つ以上取得

※ 今回の記事では紹介しませんが セカンダリインデックス をテーブルに設定すれば、他の条件でデータが取得可能です。

同じパーティションキーの項目はソートキー順に並べて近くに保存されているため、ソートキーの範囲を指定した上で効率良くまとめて項目を取得できます。喩えるなら、本棚に巻数の順番に並べて漫画が保管されているため、1 度の出入りで効率よく必要な本を取り出せるといったところでしょうか。

  • AWS Quest という漫画の全巻を本棚から持ってくる (Query でパーティションキーの値を AWS Quest に指定)
  • AWS Quest という漫画の 10 巻以下を本棚から持ってくる (Query でパーティションキーの値を AWS Quest に指定、ソートキーを 10 以下で指定)
  • AWS Quest という漫画の 15 巻から 20 巻までを本棚から持ってくる (Query でパーティションキーの値を AWS Quest に指定、ソートキーを 15 以上 20 以下で指定)

ただしこの Comic テーブルでは、同じタイトルで作者が異なる漫画の 1 巻が複数あれば別データとして扱えません。皆さんがテーブル設計をする場合は、データを一意にできるプライマリキーにするようご注意ください。


3. おわりに

今回はプライマリキーの構成要素と、パーティションキーやソートキーの役割について説明しました。冒頭でも述べた通り今回のテーブル設計はあくまでパーティションキーやソートキーの説明をするための例ですので、実際には データモデリングのドキュメント も参考にしてみてください。
さらに DynamoDB を使いこなすためには、セカンダリインデックス結果整合性キャパシティユニットや、オンデマンドモードとプロビジョンモード などの理解が必要ですので、こちらも学習していただくのをおすすめします !

このようにテクニカルインストラクターは、自学だけではつまずきやすい部分などを含め、みなさんにより AWS を理解してもらいやすくなる工夫を日々行いながら クラスルームトレーニング を提供しております !
質問もリアルタイムでできるため分からない部分はとことんお付き合いしますし、ほとんどのコースには演習の時間も多くあるため学んだ内容を AWS 環境で実践できます !

AWS のトレーニングについてもっと知りたい方は、以下の連載記事も参考にどうぞ。


これまで自分で勉強してきたけど AWS を体系的に学ぶことでもっと詳しくなって業務で活用したい ! という方はぜひ AWS のトレーニングを受講してみてください !


builders.flash メールメンバーへ登録することで
AWS のベストプラクティスを毎月無料でお試しいただけます

筆者プロフィール

杉本 圭太
アマゾン ウェブ サービス ジャパン合同会社
トレーニングサービス本部 テクニカルインストラクター

テクニカルインストラクターとして、知識をつけることが目的ではなく実際に業務で活用できる力を得ることを目指したトレーニングを提供しています。自分自身が新しいことを知るのが好きなので、「AWS を知るのは面白い ! もっと学んでみよう !」と多くの方に感じてもらえる工夫を常に考えながら活動しています。

AWS を無料でお試しいただけます

AWS 無料利用枠の詳細はこちら ≫
5 ステップでアカウント作成できます
無料サインアップ ≫
ご不明な点がおありですか?
日本担当チームへ相談する