KVS(キーバリューストア)の特徴を利用する
|Google App Engine(以後GAE)はデータストアという一種のデータベースを用いて、データの保存(永続化)を行います。
本サイトでも下記リンクでその方法について解説しています。
このデータストアは特徴として、RDB(リレーショナルデータベース)ではなくKVS(キーバリューストア)というデータ管理方式をとっています。
リレーショナルデータベース(RDB)は、データベースの各テーブルに役割を持たせてテーブル間に関係性を与えることで、一つのデータを役割毎に複数のテーブルに分割して管理します。
キーバリューストア(KVS)は、こちらもデータの管理方式の一つで、名前からイメージできるように「キー」と「値」という関係でデータが保存されます。KVSでもテーブルに似た概念(カインドという)は存在し、GAEのデータストアでも、JDO(JDOをGAEのデータストアに保存/取得する)を用いることでRDBライクにデータを扱うことができます。
今回は、このKVSにデータを保存する際の特徴について、RDBとの違いを交えながら解説したいと思います。
それでは続きをどうぞ
RDBおよびKVSへのデータ保存
RDBでは、あらかじめ各テーブルにカラムが定義されており、カラムの定義(型やカラム数)に沿ったデータの保存が求められます。
一方データストア(KVS)では、「キー」と「値」という関係でデータが保存され、カラムを意識する必要はありません。
RDBの方については特に違和感はないと思います。テーブルに定義されたカラム数以上のデータ、またカラム毎に定義された型と違ったデータは保存できません。
KVSについて、サンプルを用いて具体的に見て行きます。
今回は以下のようなサンプルを用意し、データストアに3つのエンティティー(いわゆる行、レコード)を作成してみます。
データストアへのデータの保存方法については、「Low Level APIでGAEのデータストアにアクセスする」を参考にしてください。
KvsTestServlet.java
public class KvsTestServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { DatastoreService dss = DatastoreServiceFactory.getDatastoreService(); Key key1 = KeyFactory.createKey("kvs",1); Entity entity1 = new Entity(key1); entity1.setProperty("name", "seit"); entity1.setProperty("age", 25); entity1.setProperty("gender", "man"); dss.put(entity1); Key key2 = KeyFactory.createKey("kvs",2); Entity entity2 = new Entity(key2); entity2.setProperty("name", "kobashing"); entity2.setProperty("gender", "man"); entity2.setProperty("pastime", "golf"); dss.put(entity2); Key key3 = KeyFactory.createKey("kvs",3); Entity entity3 = new Entity(key3); entity3.setProperty("name", "mhidaka"); entity3.setProperty("attribute", "hitsuji"); entity3.setProperty("gender", "man"); entity3.setProperty("join", "Techbooster"); dss.put(entity3); } }
データ保存方法の詳細な解説は前述のリンクにお任せするとして、ここでは簡単に解説しておくと、
まず6行目でエンティティーのキーを生成しています。
7行目で生成したキーを用いてエンティティーを生成しています。
8、9、10行目で、EntityクラスのsetProperty()メソッドを用いて、エンティティーのプロパティー(列名:第1引数)とその中身(値:第2引数)を指定しています。
11行目でDatastoreServiceクラスのput()メソッドを用いて、生成したエンティティーをカインドに保存(永続化処理)しています。
なお、カインド名は6行目のキー生成時にKeyFactoryクラスのcreateKey()メソッド第1引数に指定した文字列となります。
あとは6〜11行目と同じ処理(プロパティーは異なる)を3回行うことで、3つのエンティティーを生成、保存しています。
さて、各エンティティー(entity1、 entity2、 entity3)に格納しているデータを見てみると、entity1にはname、age、genderというプロパティーでデータを保存しているのに対し、entity2ではageがなく、代わりにpastimeというプロパティーが定義されています。
またentity3では、attribute、joinというプロパティーが存在し、プロパティーの数もentity1およびentity2と異なります。
このような状態で保存した場合でも問題なく保存は完了し、データストアでは以下のような状態でデータが保存されています。
見た目はまるでRDBのようですが、例えば一行目のエンティティーには、pastime、attribute、joinのプロパティーは存在していません。
通常のRDBでは、基本的にテーブルにカラムが決められているため、エンティティー(RDBではレコード)毎に違ったプロパティー(RDBではカラム)でデータを保存しようとすると、カラムが存在しないということでエラーになります(上図参照)。
また、型についても各エンティティーの各プロパティーで指定できます。
例えば今回のサンプルの場合、各EntityのnameプロパティーにはString型の値を保存していますが、2行目のエンティティーのnameプロパティーにだけIntegerの値を保存する、といったことも可能です。
つまり、同じカインドでも各Entity間に関係性があるわけではなく、あくまで「キー」と「値」の関係で成り立っているのです。
さて、今回はデータストア(KVS)にデータを保存する際の特徴について解説しました。
KVSはRDBに変わるデータ保存の方式として注目されているので、この機会にGAEで勉強してみるのもいいのではないでしょうか。