我正在将我的应用程序从关系数据库移动到objectify / google app引擎。
应用程序的关系建模如下:
一个Message
可以发送给许多Users
。每个User
可以有很多Message
个问题。
我需要能够扫描发送给特定Message
的所有User
。
如何使用Objectify做到这一点?
答案 0 :(得分:4)
有很多方法可以做到这一点。
您可以在用户对象中保存邮件列表。这将很好地满足您将所有消息发送给用户的要求,因为不需要进行查询。
您可以在邮件对象中保存用户列表。要获取发送给单个用户的所有邮件,请执行查询。
您可以保存上面的两个列表。请记住,在App Engine中通常不需要规范化并担心磁盘空间和重复。几乎总是构建您的结构,以便查询速度很快。
您可以忘记列表,并将关系对象与关系数据库中的表一样。在某些用例中,它仍然可以是App Engine中的不错选项,例如当列表太大(数千)并且会使对象膨胀并且甚至可能无法查询时。
最重要的变量将确定与您指定的查询相关的方法,通常会将消息发送给单个用户,并且是否会有最大数量的消息?如果我们谈论的是平均数十个或更少,最多几个,用户对象中的消息列表听起来像一个很好的选择。如果我们谈论更多,特别是如果无限制,它将无法正常工作,您将需要进行实际查询。
答案 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;
}
然后,如果要在删除用户时删除所有用户消息,只需在用户之前将其从数据存储中删除。如果您想为特定用户添加新消息,也完全相同。