私はGoogleAppEngineとObjectify3.1を使用しており、非正規化とその使用法に基づいたエンティティの設計についてゆっくりと学習していますが、まだいくつかの側面に苦労しています。
私は現在、ユーザーエンティティがゲームエンティティに参加でき、ユーザーが参加しているすべてのゲームを見つけることができる必要があるシステムを構築しています。私の見方では、2つの基本的な解決策があります。
解決策1)
ゲームにユーザーキー(participantKeys)のリストを保存し、次のようにメンバーが参加しているゲームを見つけます。
List<Key<User>> userList = new ArrayList<Key<User>>();
userList.add(new Key<User>(User.class, myUserId));
Collection<Game> games = ofy().query(Game.class).filter("participantKeys in" , userList).list();
解決策2)
ゲームエンティティに参加者リストを保存することに加えて、ユーザーが参加したゲームのリストもユーザーエンティティに保存し、次のようなゲームを見つけます。
User myUser = userDao.getUser(myUserId);
Collection<Game> games = user.getParticipatedGameKeys();
システムに多くのゲームがあると、ソリューション1はかなり遅くなります。
解決策2を使用すると、ゲームの検索が速くなりますが、ユーザーがゲームに参加したりゲームから離れたりするときに、リストを常に最新の状態に保つ必要があります。
ユーザーがシステムを長期間使用していると、ゲームのリストも大きくなります。ユーザーが現在参加しているすべてのゲームのみを返したいので、リストをトラバースして「履歴」ゲームを除外する必要があります。
よりエレガントなソリューションが欠けていますか?上記のどちらもあまり魅力的ではないようです。
ありとあらゆる助けに大いに感謝します!
編集:
長い間代替案を考えた後、Miklが提案したようなものを試してみることにしました。それで、それと非常によく似た解決策を聞くのは良いことです:-)
ゲームへのリンク、ユーザーへのリンク、および取得する必要のあるその他すべての情報を含むGameParticipationエンティティを作成しました。
ゲームに参加するたびに、GameParticipationエンティティを更新して、ゲームの現在の状態を反映します。ゲームが残ったら、エンティティを削除します。また、ゲームが変更された場合、関連するすべてのGameParticipationエンティティを更新します。
私は少しパフォーマンステストを行いましたが、それはかなりうまくいくようです!