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

时间:2012-06-26 14:45:46

标签: java google-app-engine objectify

我正在使用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实体。

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

1 个答案:

答案 0 :(得分:0)

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

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

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

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