app engineのエンティティグループ
エンティティグループはリレーションではない
祖先とか親とか子とかいう単語が出てくるので誤解しがちだけど、エンティティグループは、1:多のようなリレーションを表現するものではない。
トランザクションによりACID特性を保障したいときに設定するもの。
リレーションはkeyをコレクションで持ったり、Slim3のModelRefなどを使って表現する。
従来のリレーション(1:1、1:多とか、到達性とか)とは本来直交する概念です*2。
Entity Groupの意味ですが、同じEntity Groupに所属するEntity群の間でのみ、トランザクションが可能になります。
Entity Groupとその簡単な構成法 - Grな日々(uehajの日記)
エンティティグループの構成は一通りではない
Person(1)をルートとして、Person(2)とPerson(3)をひとつのエンティティグループに設定する場合、Person(1)/Person(2)/Person(3)とすることもできるし、Person(1)/Person(2)、Person(1)/Person(3)とすることもできる。
両者はAncestorQueryによる取得の際に結果が異なってくる。
パスの各キーによるAncestor Queryの結果は下記のようになる。(Slim3の場合)
// /grandParent/parent/child としてエンティティグループを構成 Slim3Model grandParent = new Slim3Model(); Slim3Model parent = new Slim3Model(); Slim3Model child = new Slim3Model(); Key grandParentKey = Datastore.put(grandParent); Key parentKey = Datastore.allocateId(grandParentKey, meta); parent.setKey(parentKey); Key childKey = Datastore.allocateId(parentKey, meta); child.setKey(childKey); Datastore.put(parent, child); // grandParentによるAncestor Queryはparentとchildも取得 List<Entity> list1 = Datastore.query(grandParentKey).asList(); assertThat(list1.size(), is(equalTo(3))); // parentによるAncestor QueryはgrandParentは取得されない List<Entity> list2 = Datastore.query(parentKey).asList(); assertThat(list2.size(), is(equalTo(2))); // childによるAncestor Queryはchildのみ取得 List<Entity> list3 = Datastore.query(childKey).asList(); assertThat(list3.size(), is(equalTo(1)));
**エンティティグループは分散しない
エンティティグループに属するエンティティは同一サーバ上に保存される(=分散しない)ため、アクセスはスケールアウトしない。
「Entity Groupを構成する」ということの、Datastoreレベルから見た具体的な意味は、Entityに「Ancesor情報つきのKey」を持たせるということです。
Entity Groupとその簡単な構成法 - Grな日々(uehajの日記)
例:1つのDepartmentと1000のEmployeeがある場合:両者を同じエンティティグループとすると、1つのDepartmentに属する1000のEmployeeのうち、いずれか1つのEmployeeしか同時にトランザクションを実行できない(他はエラーとなりリトライが必要となる)
トランザクションとエンティティグループ - スティルハウスの書庫