前回の続きでDynamoDBについて。
DynamoDBはKVSですが、完全なKVSよりも柔軟性があります。
まず、テーブルに絶対必要なのはKeyです。Keyは文字通り、それ(ら)によって一意になります。
Keyには2種類あり、Hash のみ OR Hash + Rangeで構成されます。
Hashのみの場合は、一般的なKVSと同じく、Hashのみで一意になります。つまり、Keyを条件にクエリを投げて返ってくるレコードは常に1レコードです。
Hash + Range の場合は、Hash と Range両方で一意になります。また、Hashのみ、Rangeのみでクエリを投げることは出来ず、結果的にKeyを条件にクエリを投げて返ってくるレコードは常に1レコードとなります。
RDBの常識でKVSを見ると、あれも出来ない、これも出来ないとなり、使いにくいと感じると思います。
「そもそもDynamoはKVSと付いているのにKeyとValueだけでないのはどういうこと?」
「Keyでしか検索出来ないならば、Value部分にJSONを打ち込めばそもそもスキーマレスだよね?」
と思われがちですが、DynamoDBはKey以外の項目にも検索をかけることが出来ます。それがセカンダリインデックスです。
このセカンダリインデックスにも2種類あります。グローバルセカンダリインデックスとローカルセカンダリインデックスです。
使いどころがわかりやすい、グローバルセカンダリインデックスについて簡単に言うと、Keyと同じように、Hash のみ OR Hash + Range でつけるインデックスです。インデックスなので、もちろん重複を許します。また、インデックスを指定しても、スキーマレスはそのまま変わらず、Null可です。使い方としては単純に、Keyとは関係のない項目で絞り込みを行いたいときは、グローバルセカンダリインデックスを付けましょう、となります。残念ながら、Rangeのみのインデックスは付けられないですが、これにより、一回の問い合わせから、複数レコードの取得が可能です。
もう一つのローカルセカンダリインデックスですが、マネージメントコンソールで操作するとすぐに分かるのですが、Hash + RangeでKeyを指定した場合のみ作製可能です。Keyで指定しているHashと対に指定しているRangeがありますが、そのうちRangeの部分だけKeyで指定したものと異なるものを使う事ができます。つまり、検索条件としては、Keyで指定した Hash + ローカルセカンダリインデックスで検索できます。もちろん一意に必ずなるとは限らないので、複数レコード取得が可能となります。
まとめます。
1. Keyの種類は Hash のみ or Hash + Range。どちらを選んでも、インデックスを付けなければKey以外で検索は不可能
2. Key以外の項目で検索したい場合は、インデックスを付ける必要がある。また、インデックスの作製はテーブル作成時のみ可能で、今のところ後付できない
3. インデックスをつけても、スキーマレスであることに変わりはない、インデックスはNull可
4. グローバルセカンダリインデックスは、Keyと関係ない項目で絞り込みたいときに使い、複数レコード取得可能
5. ローカルセカンダリインデックスは、KeyのHash部分とRangeで指定したインデックスで検索
6. Rangeのみのインデックスを作製することは不可能で、Range以外のインデックス項目は eq でしか比較できない
ローカルセカンダリインデックスはまだ上手い使い方が思いつかないです。少しずつ実践的なことを紹介したいと思います。