テクニカルインストラクターと学ぶ Amazon DynamoDB のセカンダリインデックス
Author : 杉本 圭太
テクニカルインストラクターの杉本圭太です !
最近読んで面白かった漫画は「ふつうの軽音部」です。
今回は「パーティションキーとソートキーの役割と共に Amazon DynamoDB のプライマリキーについて学ぼう」では紹介しきれなかった、Amazon DynamoDB のセカンダリインデックスについてポイントを絞って説明していきます !
DynamoDB 特有の仕組みでありトレーニングでもよく質問を受ける箇所ですので、理解してもらいやすいように喩え話や具体例、私なりの解釈でドキュメントの記載内容を表現した図を交えています。
ちなみに リレーショナルデータベース (RDB) に慣れている方は「インデックス」と聞くとクエリのパフォーマンスチューニングのためなどに使うものを想像されるかもしれませんが、DynamoDB のセカンダリインデックスと RDB のインデックスは別物だと考えていただいた方が良いです。
セカンダリインデックスを説明するため、この記事ではこちらの Comic テーブルを例に使用します。
DynamoDB を初めて聞くという方は、高速で柔軟な NoSQL データベースサービス。Amazon DynamoDB をグラレコで解説 に目を通して概要を把握いただくのもおすすめです !
1. DynamoDB のセカンダリインデックスとは
セカンダリインデックスの役割を端的に言うと、プライマリキー以外の属性を条件にして項目を取得できる仕組みです。セカンダリインデックスはテーブルごとに作成するリソースで、1 つのテーブルに複数作成できます。
例えばセカンダリインデックスを作成していない Comic テーブルでは、検索条件に Title や Volume の値しか使えません。しかしセカンダリインデックスを追加することで、Author や Date の値などを検索条件にできるようになります。
プライマリキー以外の属性を条件に項目が取得できる役割は同じなのですが、作成できるセカンダリインデックスは 2 種類あります。
- グローバルセカンダリインデックス
- 1 つのテーブルに 20 個まで (デフォルトクォータ)
- いつでも作成、削除できる
- ローカルセカンダリインデックス
- 1 つのテーブルに 5 個まで
- テーブル作成時のみ作成でき、削除はできない
ここで挙げた以外の違いは、この後のセカンダリインデックスの機能と共に紹介していきます。
2. セカンダリインデックスの作成
グローバルセカンダリインデックス、ローカルセカンダリインデックス のどちらを作成する場合でも、共通して設定が必要なパラメーターがあります。
- IndexName (インデックス名) : テーブル内でインデックスを識別する名前
- KeySchema (キースキーマ) : どの属性をパーティションキーやソートキーにするか (プライマリキーの定義に似ている)
- Projection (射影) : どの属性をセカンダリインデックスの領域にコピーするか
2-1. KeySchema (キースキーマ)
セカンダリインデックスのキースキーマで定義したパーティションキーやソートキーは、プライマリキーで Query を使う時と同じような使い方ができます。つまりセカンダリインデックスを 1 つ追加すると、Query の条件式で使えるパターンが 1 つ増やせると考えるとわかりやすいかもしれません。
しかしセカンダリインデックスとプライマリキーでは異なる特徴もあります。
- セカンダリインデックスに指定する属性は、テーブル内の全ての項目に存在する必要はない
- セカンダリインデックスには、テーブルの中の項目を一意に特定する役割はない
例としている Comic テーブル内の項目には Price という属性は存在しませんが、セカンダリインデックスのキースキーマに Price を含めても良いです。そして“Author”: “Bob” の項目が複数存在しますが、セカンダリインデックスのキーを Author のみにしても問題ありません。
また、作成するセカンダリインデックスの種類によってキースキーマに定義できるキーが異なります。
- グローバルセカンダリインデックスのキースキーマ
- パーティションキーとソートキーは自由に選択できる
- ソートキーはなくても良い
- ローカルセカンダリインデックスのキースキーマ
- パーティションキーにはプライマリキーと同じものを選択し、ソートキーのみ自由に選択できる
- ソートキーは必須
ここまでの内容を整理して、Comic テーブルのセカンダリインデックスで定義可能なキースキーマの例を表にしてみました。
グローバルセカンダリ インデックス |
ローカルセカンダリ インデックス |
|
パーティションキー : Title ソートキー : Date |
o | o |
パーティションキー : Author ソートキー : Date |
o | x |
パーティションキー : Date ソートキー : なし |
o | x |
セカンダリインデックスを作成する場合は、テーブルからどのような条件で項目を取得したいかを意識して設計しましょう !
2-2. Projection (射影)
セカンダリインデックスを作成すると、テーブルにある項目を基にセカンダリインデックス用のデータがコピーされます。この時、どの属性をインデックス用のデータにコピーするかを Projection (射影) としてセカンダリインデックスの作成時に定義します。ただしプライマリキーとそのセカンダリインデックスに含まれる属性は自動でインデックスのデータとしてコピーされます。
セカンダリインデックスごとに射影で定義された属性がテーブルの項目からコピーされるため、テーブルは「ベーステーブル」とも呼ばれます。
コピーされたデータの持ち方は、セカンダリインデックスの種類によって異なります。
- グローバルセカンダリインデックス
- ベーステーブルとは別のパーティションが用意され、セカンダリインデックスのパーティションキーによって分散して配置される
- ローカルセカンダリインデックス
- ベーステーブルのパーティションと同じパーティションにセカンダリインデックスのデータも配置される
- 同じパーティションキーを持つ項目の合計サイズ (インデックス用のデータを含む) は最大で 10 GB まで
パーティションキー: Author、ソートキー: Date でグローバルセカンダリインデックスを作成した場合、Author の値でパーティションが分けられて、Date の値によってソートされていることを表現するとこんな感じでしょうか。
この図ではグローバルセカンダリインデックスが AuthorAndDate の 1 つだけですが、複数のグローバルセカンダリインデックスを作成すると、ベーステーブルとは別のパーティションがその分用意されます。そのためセカンダリインデックスを多く作成すると、DynamoDB テーブルの保存データ量は増える点は注意しましょう。
3. セカンダリインデックスを使った項目の取得
セカンダリインデックスを作成すると、そのインデックスに対して Query と Scan が使えます。どちらもインデックス名を指定する以外はプライマリキーでの使い方と同じです。ただしテーブルの中から一意の項目を取得する GetItem は、セカンダリインデックスでは使えません。
項目の取得でできることも、セカンダリインデックスの種類によって異なります。
- グローバルセカンダリインデックスを使った読み取り
- 結果整合性のみ
- 射影された属性のみ取得
- 消費するスループットはセカンダリインデックスごとに独立した設定を持つ
- ローカルセカンダリインデックスを使った読み取り
- 強い整合性、結果整合性のどちらも使える
- 指定すれば射影されてない属性も取得はできる (これは fetch と呼ばれていてレイテンシーやスループットはより増える)
- 消費するスループットはベーステーブルに設定したもの
4. セカンダリインデックスのベストプラクティス
この記事ではセカンダリインデックスの役割や仕組みについてポイントを絞ってお伝えしましたが、 セカンダリインデックスのベストプラクティス も読んでみてください。
例えば、スパースなインデックス と呼ばれる特性を使う例などが載っています。これはセカンダリインデックスではキースキーマに定義された属性がない項目はインデックスの領域にコピーされない仕様をうまく利用して、インデックスのデータ量を抑えたり、効率的に必要な項目を取得できるようにする方法です。
Comic テーブルの例でセール中の項目を効率的に取得したい場合、パーティションキー : Sale、ソートキー : Author のようなセカンダリインデックスを用意しておくとします。ここでセール中の項目だけ “Sale”: “Y” の属性をつけておけば、セカンダリインデックス (Sale-AuthorSparse) を指定して Query をすることで、セール中の項目全て、もしくはセール中かつ Author の名前を絞った読み取りが効率的にできます。
このような DynamoDB を有効活用する方法が他にも記載されていますので、設計時の参考にしてみてください !
5. おわりに
ここまで DynamoDB のセカンダリインデックスがどのような機能で、どんな仕組みかを端的にお伝えしました。
ではセカンダリインデックスがどんな時に役立つのかと注意点を最後に確認しておきましょう !
役立つ場面
- DynamoDB でプライマリキー以外を使用した検索の検索や絞り込みをしたい場合、必要に応じてセカンダリインデックスを追加することで対応できる
- グローバル瀬カンダリインデックスと、ローカルセカンダリインデックスのそれぞれの特徴を把握して適切な方を使用しましょう ! 詳細な比較表は ドキュメント にも記載されています。
注意点
- セカンダリインデックスの追加により、スループットやストレージ容量も追加されるので必要のあるものだけを作成する
- 射影やスパースなインデックスをうまく使うことで、追加されるデータ量を最適化できることもお忘れなく !
- セカンダリインデックスが大量に必要になるような状況であれば、DynamoDB 以外のデータベースを検討しても良いかもしれません。
このようにテクニカルインストラクターは、自学だけではつまずきやすい部分などを含め、みなさんにより AWS を理解してもらいやすくなる工夫を日々行いながら クラスルームトレーニング を提供しております !
質問もリアルタイムでできるため分からない部分はとことんお付き合いしますし、ほとんどのコースには演習の時間も多くあるため学んだ内容を AWS 環境で実践できます !
AWS のトレーニングについてもっと知りたい方は、以下の連載記事も参考にどうぞ。
これまで自分で勉強してきたけど AWS を体系的に学ぶことでもっと詳しくなって業務で活用したい ! という方はぜひ AWS のトレーニングを受講してみてください !
筆者プロフィール
杉本 圭太
アマゾン ウェブ サービス ジャパン合同会社
トレーニングサービス本部 テクニカルインストラクター
テクニカルインストラクターとして、知識をつけることが目的ではなく実際に業務で活用できる力を得ることを目指したトレーニングを提供しています。自分自身が新しいことを知るのが好きなので、「AWS を知るのは面白い ! もっと学んでみよう !」と多くの方に感じてもらえる工夫を常に考えながら活動しています。
AWS を無料でお試しいただけます