Java Objectify/GAE——一个具体的非规范化问题

Java Objectify/GAE——一个具体的非规范化问题,java,google-app-engine,objectify,Java,Google App Engine,Objectify,我正在使用Google App Engine和Objectify 3.1,慢慢地学习非规范化和基于使用情况设计实体,但在某些方面我仍在苦苦挣扎 我目前正在构建一个系统,其中用户实体可以参与游戏实体,并且需要能够找到用户参与的所有游戏。在我看来,有两种基本解决方案: 解决方案1) 在游戏中存储用户密钥(participantKeys)列表,并按如下方式查找成员参与的游戏: List<Key<User>> userList = new ArrayList<Key<

我正在使用Google App Engine和Objectify 3.1,慢慢地学习非规范化和基于使用情况设计实体,但在某些方面我仍在苦苦挣扎

我目前正在构建一个系统,其中用户实体可以参与游戏实体,并且需要能够找到用户参与的所有游戏。在我看来,有两种基本解决方案:

解决方案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();
User myUser = userDao.getUser(myUserId);
Collection<Game> games = user.getParticipatedGameKeys();
List userList=new ArrayList();
add(新键(User.class,myUserId));
Collection games=ofy().query(Game.class).filter(“participantKeys in”,userList.list();
解决方案2)

除了在游戏实体上存储参与者列表外,还要在用户实体上存储用户已参与的游戏列表,并按如下方式查找游戏:

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();
User myUser = userDao.getUser(myUserId);
Collection<Game> games = user.getParticipatedGameKeys();
User myUser=userDao.getUser(myUserId);
Collection games=user.getParticiatedGameKeys();
一旦系统中有很多游戏,解决方案1就会变得非常缓慢

解决方案2将使查找游戏更快,但我需要在用户加入和退出游戏时不断更新列表

一旦用户长期使用该系统,游戏列表也会变得很大。我只想返回用户当前参与的所有游戏,因此需要遍历列表并排除“历史”游戏

我是否错过了一个更优雅的解决方案?以上两项似乎都不太吸引人

非常感谢您的任何帮助

编辑:

在考虑了很长一段时间的替代方案后,我决定尝试米克尔建议的方法。。所以很高兴听到一个非常类似的解决方案:-)

我已经创建了一个游戏参与实体,其中包含游戏链接、用户链接以及我需要获得的所有其他信息

每次加入游戏时,我都会更新GameParticipation实体以反映游戏的当前状态。当游戏结束时,我会删除实体。此外,当游戏更改时,我会更新所有相关的游戏参与实体


我做了一些性能测试,它似乎工作得相当好

您还可以拥有另一个实体,我不知道如何称呼它(UserGame?),但在这个实体中,您将存储游戏密钥、用户密钥以及您想要访问的一些信息,例如用户名、游戏名称等。然后,当用户进入游戏时,您将创建此实体

使用此实体,您可以轻松检索成员参与的游戏以及参与游戏的所有用户

这种方法的不便之处在于,如果用户属性或游戏属性发生更改,您还需要更新存储在USerGame实体中的信息,如用户名

我不知道这是否是一个好的解决方案,但它应该有效