1つのエンティティにプロパティをいくつまで作れるか |
1つのエンティティにプロパティをいくつまで作れるか(パート2) |
ふとした思い付きで、データストアの1つのエンティティにプロパティをいくつまで作ることができるのか、と思っていろいろ調べていました。1エンティティ当たり1MBというデータ量の制限はいろんなところに書かれていましたが、プロパティ数の制限については見つけられませんでした。
そこで今回、1つのエンティティにプロパティをいくつまで作ることができるのか、検証してはっきりさせてみたいと思います。
検証方法
検証のやり方はデータストアに大量のプロパティを持つエンティティを生成するプログラムを作成し、プロパティ数を増やしていきながら保存と取り出しがいくつまでエラーなくできるのかを確認します。
検証用の大量のプロパティを持つエンティティを生成するプログラムを、下記の通り簡単に作成します。
property変数で、生成するプロパティの数を指定できるようにします。これが実行されると、エンティティが1件作成されます。
long property = Long.valueOf(10000);
Entity entity = new Entity("myKind" + String.valueOf(property));
for (long i = 0; i < property; i++) {
entity.setProperty("property" + i, "text");
}
DatastoreService ds = DatastoreServiceFactory.getDatastoreService();
Key key = ds.put(entity);
try {
Entity ent = ds.get(key);
resp.setContentType("text/plain");
resp.getWriter().println("OK p.size="+ent.getProperties().size());
} catch (EntityNotFoundException e) {
e.printStackTrace();
}
検証パターン
データストアは、ローカル環境の擬似的なデータストアとGAEの実際のデータストアの2つあります。ローカルとGAE上のデータストアとでプロパティ数がどう違うのか比べ確認します。また、1エンティティ当たり1MBという制限がありますので、プロパティ数がプロパティ名や型、データのサイズに影響されることもありますので、統一して検証します。
プロパティ名・型・値によって保存できるプロパティ数が変わると想定している為、次のケースを考えました。カインド名は、一文字だけで生成します。
ケース名 | 型と桁数 | 値 |
ケース1 | String型1文字 | 1 |
ケース2 | int型1桁 | 1 |
ケース3 | byte型1桁 | 1 |
ケース4 | boolean型 | TRUE |
ケース5 | 0件のList型 | |
ケース6 | null値のText型 |
表1.検証に使用するケースと型
検証結果
ローカル環境とGAE上のデータストアとでプロパティをいくつまで保存させることができるのか検証しました。
ローカル環境のデータストア
ケース名 | 型と桁数 | 値 | 保存できるプロパティ最大数 |
ケース1 | String型1文字 | a | 75170 |
ケース2 | int型1桁 | 1 | 80953 |
ケース3 | byte型1桁 | 1 | 80953 |
ケース4 | boolean型 | TRUE/FALSE | 80953 |
ケース5 | 0件のList型 | 95670 | |
ケース6 | null値のText型 | 95672 |
表2.ローカル環境でのデータストアでの保存できる最大プロパティ数
ローカルでは上の表の通り一定数まで保存することが確認できました。一定数を超えると、The request to API call datastore_v3.Put() was too large.という例外が出ました。やはり1エンティティ当たり1MBという制限がある為、プロパティ数が制限されているのではないかと考えられます。
またローカル環境でのケース1~ケース6までを比べると、型によって保存できるプロパティ数が違っていることも確認できました。
- String型よりも整数型の方がデータ量が少ないので多くのプロパティを作成できる
- 整数型も真偽値型もデータ量は同じであるので最大プロパティ数も同じである
- null値のText型は最もデータ量が少ないのでデータ量を圧迫させない
GAE上のデータストア
驚いたことにGAE上のデータストアでの最大プロパティ数はケースに関わらず20000個まででした。20001個目のプロパティを作成して保存すると、Too many indexed propertiesという例外が発生しました。
この例外を調べたところ、index有りのプロパティを作成した場合に発生する例外であり、indexを作成しないでプロパティを作成すると例外が起きなくなるそうです。よって、プログラム1の?entity.setProperty(“property” + i, “text”);をentity.setUnindexedProperty(“property” + i, “text”);に書き換えて再度検証しました。
その結果、20000個の制限を越えて表3に示すようにローカル環境での結果(表2)と殆ど同じ結果になりました。
(厳密に言うと、表3の生成できるプロパティ最大数は表2より少なくなっていました。何故なんでしょう・・・)
表3の制限を越えると、java.lang.IllegalArgumentException: entity is too bigという例外が発生しました。
ケース名 | 型と桁数 | 値 | 保存できるプロパティ最大数 |
ケース1 | String型1文字 | a | 75169 |
ケース2 | int型1桁 | 1 | 80951 |
ケース3 | byte型1桁 | 1 | 80951 |
ケース4 | boolean型 | TRUE/FALSE | 80951 |
ケース5 | 0件のList型 | 95669 | |
ケース6 | null値のText型 | 95669 |
表3.GAE環境でのデータストアでの保存できる最大unindexedプロパティ数
エンティティの保存仕様はローカルとGAE上のデータストアとで違うことが今回の検証で分かりました。
またGAE上のデータストアは、indexed指定とunindexed指定とで作成できるプロパティ数が変わることも確認できました。
今回の検証でローカルではindexedとunindexedとで指定を行った検証をしていなかったので、次回以降ローカル環境でindexedとunindexedを指定した検証を追加で行います。
この検証結果が開発の役に立てばと思っております。
1つのエンティティにプロパティをいくつまで作れるか |
1つのエンティティにプロパティをいくつまで作れるか(パート2) |