はじめに
分散データベースにおいて(キーを用いた)レンジスキャンを効果的に行うためには、論理的に関連性のあるキーを設計するのみではなく、あらかじめそのレンジに含まれるデータが、同じ、あるいは近い場所(ノード、リージョン、パーティション)に存在する様に、(物理)設計を行う必要があります。
例えば、MongoDBでは、シャーディングの方法として、ハッシュとレンジを要件に応じ、選択することになります(この選択が物理配置に影響します)。
HBaseでは、データはRowKeyで(物理的に)ソートされます。
Couchbaseにおける検索
Couchbaseは、N1QLというSQLをJSONのために拡張したクエリ言語で、検索を行うことができます。
その際、重要なことは、Couchbaseの中心的なアーキテクチャーはKVS(キーバリューストア)であり、そのレベルでは、バリューとしてJSONデータを格納しているのに過ぎないため、検索を行うための前提として、インデックスの定義・構築が行われている必要があります。
そもそも、スキーマレスなデータストアに対して、どうやって検索が可能なのか?全件サーチするのでなければ、という視点からは、これはむしろ納得できるものとして受け止められるかと思います。
ただし、ここで留意が必要なのは、KVSのキーを使った検索(つまりキーを特定したアクセスではなく、ある範囲のキーを指定してデータを一度に取得するという要件)であっても、事前にインデックスの作成が欠かせない、というところです。
このことをよりよく理解するために、以下の二つの背景を押させておくことが重要です。
- Couchbaseにおいては、クエリおよびインデックスサービスは、(KVSである)データサービスとは、アーキテクチャー上完全に独立している(利用する要件がない場合は、クラスターとして無効にすることで、そのために潜在的にリソースが消費されることはない)。
- データサービスのキーのシャーディング方法は、ハッシュが用いられており、ユーザによって、アクセスパターンに応じて、変更する余地を残していない。(Couchbaseは、メモリファーストアーキテクチャーと、クラスターマップを用いたクライアントからのノードへの直接のアクセスによって、固まった場所にあるデータをチャンクで取り出すことによって実現される効率に勝る、高いパフォーマンスを実現している)
Couchbaseにおけるレンジスキャン実現方法
インデックスの作成
CREATE INDEX range_index on MyFirstBucket(META().id) using GSI;
ここで、META().id
が、KVSのキー(ドキュメントID)に対応します。
MyFirstBucket
は、インデックスを作りたいバケット(いわゆるデータベースに相当)です。
BucketName(FieldName)
の形になっており、JSONの属性を指定する場合は、バケット名の後のカッコ内に直接指定しますが、ドキュメントID指定のためにMETA().id
という特殊なキーワードを用いています。
利用例
下記の様な、キーにレンジを指定した検索が可能になります。
SELECT * from MyFirstBucket where Meta().id BETWEEN 'ABC:001' AND 'ABC:999';
また、下記の様な、キーの一部を指定した曖昧検索も可能になります。
SELECT * from MyFirstBucket where Meta().id LIKE 'ABC:%';
最後に
タイトルに包含されるテーマの広さに比して、言葉足らずの感は否めませんが、後半の具体的な方法についての紹介のみでも、それなりの意義を持つと期待して、本記事は以上とします。