使用客体化的多对多关系?

时间:2014-05-14 07:20:15

标签: java google-app-engine objectify

我正在将我的应用程序从关系数据库移动到objectify / google app引擎。

应用程序的关系建模如下:

一个Message可以发送给许多Users。每个User可以有很多Message个问题。

我需要能够扫描发送给特定Message的所有User

如何使用Objectify做到这一点?

3 个答案:

答案 0 :(得分:4)

有很多方法可以做到这一点。

  1. 您可以在用户对象中保存邮件列表。这将很好地满足您将所有消息发送给用户的要求,因为不需要进行查询。

  2. 您可以在邮件对象中保存用户列表。要获取发送给单个用户的所有邮件,请执行查询。

  3. 您可以保存上面的两个列表。请记住,在App Engine中通常不需要规范化并担心磁盘空间和重复。几乎总是构建您的结构,以便查询速度很快。

  4. 您可以忘记列表,并将关系对象与关系数据库中的表一样。在某些用例中,它仍然可以是App Engine中的不错选项,例如当列表太大(数千)并且会使对象膨胀并且甚至可能无法查询时。

  5. 最重要的变量将确定与您指定的查询相关的方法,通常会将消息发送给单个用户,并且是否会有最大数量的消息?如果我们谈论的是平均数十个或更少,最多几个,用户对象中的消息列表听起来像一个很好的选择。如果我们谈论更多,特别是如果无限制,它将无法正常工作,您将需要进行实际查询。

答案 1 :(得分:3)

除了已发布的答案,我建议您包含用户与消息的链接,原因有三:

  • GAE中的馆藏很难限制为5000件。只要您的用户的收件箱超过5k项,您的应用就会开始抛出异常。

  • 扩展实体中的数据量会产生性能成本;加载一堆500k实体比加载一堆5k实体要慢。此外,由于您可以在同一空间内放置更少的项目,因此您对memcache的使用效率会降低。用户对象往往会加载 lot

  • 您可以轻松达到单个实体(1 / s)的交易率限制。如果50个人同时向您发送消息,则会出现大量并发问题,因为所有50个人都会因乐观失败而重试。

如果您可以为单个邮件提供5000个收件人的限制,则在邮件中存储目标密钥集(并将此集合编入索引以便查询用户的所有邮件)可能是一个很好的解决方案。将消息分配给发件人的@Parent几乎肯定也有优势。

如果您是类似Twitter的并且期望邮件的收件人数超过5k,或者您的邮件通常有很多收件人(因此邮件实体会膨胀),您可能希望考虑关系索引实体模式Brett Slatkin在2009年的Google I / O演讲中谈到:https://www.youtube.com/watch?v=AgaL6NGpkB8

答案 2 :(得分:1)

你必须自己维持这种关系。这是因为根据应用程序,让用户在没有消息的情况下存在是有意义的,甚至是相反的。

Objectify Wiki(https://code.google.com/p/objectify-appengine/wiki/IntroductionToObjectify多值关系)的建议方法是保留密钥的集合(或数组)

public class Message
{
    @Id String timeStamp;
    Key<User>[] destination;
}

public class User
{
    @Id String name;
    Key<Message>[] inbox;
}

然后,如果要在删除用户时删除所有用户消息,只需在用户之前将其从数据存储中删除。如果您想为特定用户添加新消息,也完全相同。