記事作成にあたって
最近DynamoDBを触るようになってRDBと設計思想が違うから、いまいち操作しにくい。それでも騙し騙し実装をしていたが、あれ?これってプライマリーキー検索以外の場合ってできないの?LSIやGSIってのを定義すれば検索できるけど、なんで検索キーを事前に登録しておかないといけないの?って感じたので、一旦立ち止まって、整理することにしました。
プライマリーキー
DynamoDBではプライマリーキーの指定方法は2通り。
- パーティションキー
- パーティションキー+ソートキー
パーティションキーって何?
DynamoDBは分散型DB。RDBのようにデータを一箇所に集約するのではなく、複数の場所にデータを格納する。そのため、どの場所にデータを格納するのかを決める必要がある。で、配置場所を決定するのにパーティションキーを使う。RDBを触り続けた人にはなんだこれってなるかも心ないですけど、分散時に利用するキーなのねってくらいの理解でいいと思います。
セカンダリインデックス
インデックスって聞くと、データ検索を効率的に検索するための目次のことね。って理解だと痛い目見ます。実際、この理解で結構苦しめられました。。。
RDBだとWhere句に検索条件を指定すれば、欲しいデータを絞りこむ事ができた。だけどDynamoDBだと、予め検索キーをしておかないと絞り込み検索できないのです。何もしないと、プライマリー検索しかできない。なので、セカンダリインデックスを作っておく必要があります。セカンダリインデックスって聞くと難しく聞こえるけど、イメージは新しいTBLを作ってそこから検索してね。って感じ。
LSI(ローカルセカンダリインデックス)
ローカルセカンダリインデックスは公式の見解では下記の通り。早い話がパーティションキーはそのままで、ソートキーで新しく検索するイメージ。
ローカルセカンダリインデックスは特定のパーティションキー値の代替ソートキーを維持します。またローカルセカンダリインデックスには、ベーステーブルの一部またはすべての属性のコピーが含まれます。テーブルを作成する際に、ローカルセカンダリインデックスに射影する属性を指定します。ローカルセカンダリインデックスのデータは、ベーステーブルと同じパーティションキーと、異なるソートキーで構成されます。これにより、この異なるディメンションにわたってデータ項目に効率的にアクセスできます。クエリまたはスキャンの柔軟性を向上させるために、テーブルごとに最大 5 つのローカルセカンダリインデックスを作成できます。
LSIの具体例
ThreadテーブルからLastPostIndexを作って検索する。その際に、元々パーティションキーであったForumNameカラムはそのままで、ソートキーのLastPostDateTimeは新たに定義しなおす。
GSI(グローバルセカンダリインデックス)
グローバルセカンダリインデックスは公式の見解では下記の通り。早い話が、パーティションキーもソートキーも新たに定義し直して、新規のテーブルを作るイメージ。
すべてのグローバルセカンダリインデックスには、パーティションキーが必要で、オプションのソートキーを指定できます。インデックスキースキーマは、テーブルスキーマとは異なるものにすることができます。シンプルなプライマリキー (パーティションキー) を持つテーブルを作成し、複合プライマリキー (パーティションキーおよびソートキー) を使用してグローバルセカンダリインデックスを作成できます。またはその逆もあります。インデックスキー属性は、ベーステーブルからの任意の最上位 String、Number、または Binary 属性で構成できます。その他のスカラー型、ドキュメント型、およびセット型は許可されません。
GSIの具体例
GameScoresテーブルからGameTitleIndexテーブルを作成する。その際にパーティションキーもソートキーも新しく作る必要がある。