我正在使用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();
解决方案2)
除了在游戏实体上存储参与者列表外,还存储用户参与用户实体的游戏列表,并找到如下游戏:
User myUser = userDao.getUser(myUserId);
Collection<Game> games = user.getParticipatedGameKeys();
一旦系统中有很多游戏,解决方案1就会变得非常缓慢。
解决方案2可以让游戏更快找到,但我需要在用户加入和离开游戏时不断更新列表。
一旦用户长时间使用该系统,游戏列表也会变大。我只想返回用户当前参与的所有游戏,因此需要遍历列表并排除“历史”游戏。
我错过了更优雅的解决方案吗?上述两者都不具备吸引力。
非常感谢任何和所有帮助!
修改
我决定尝试像Mikl在长时间考虑替代品之后建议的东西......所以听到一个非常类似的解决方案是很好的: - )
我创建了一个GameParticipation实体,其中包含游戏链接,用户链接以及我需要获取的所有其他信息。
每次加入游戏时,我都会更新GameParticipation实体以反映游戏的当前状态。当游戏离开时,我删除了该实体。此外,当游戏发生变化时,我会更新所有相关的GameParticipation实体。
我做了一些性能测试,似乎工作得相当好!
答案 0 :(得分:0)
您还可以拥有另一个我不知道如何调用它的实体(UserGame?),但在此实体中,您将存储游戏密钥,用户密钥以及您要访问的某些信息,例如用户名,游戏名称等。然后,当用户进入游戏时,您将创建此实体。
使用此实体,您可以轻松检索成员参与的游戏以及参与游戏的所有用户。
此方法的不便之处在于,如果用户属性或游戏属性发生更改,您还需要更新存储在USerGame实体中的信息,例如userName。
我不知道它是否是一个很好的解决方案,但它应该有效。