java - 对象化关系 : One-to-Many, 我可以有效地做到这一点吗?

标签 java google-app-engine objectify

我是 Objectify 的新手,我有一个快速的问题 做某事的最佳方式:

假设我有一个允许人们发送和接收的应用程序 消息(为简单起见考虑电子邮件)。当我的应用程序加载时,我没有 想要加载来自每个联系人的每条消息 向给定用户发送消息。那将是一种浪费。 相反,我想加载用户有消息的所有联系人 来自(已读或未读)以便我可以显示联系人列表 我的应用程序,当用户点击给定的联系人时,我想加载所有 来自该联系人的消息以显示给用户。

如果不加载帐户的所有消息,我找不到执行此操作的好方法。 我阅读了关于多对一关系的 Objectify wiki,但我仍然想不出 这样做的好方法不是非常低效。对于 objectify 网站推荐的方式,我似乎必须加载给定用户的所有消息,然后解析它们以获得唯一联系人。

我正在尝试使用尽可能少的 App Engine 读取和写入,以及在哪里 可能我正在尝试使用 Smalls 而不是 Reads(总成本 在我做这个的时候,运行我的应用程序是我的一个大问题)。

在 Objectify 上,我应该怎么做?

最佳答案

This is copied from my response on the objectify-appengine google group: https://groups.google.com/forum/?fromgroups#!topic/objectify-appengine/LlOyRJZRbnk

在处理像您描述的那样的“聚合数据”时,主要有三个选项:

1)需要的时候计算

您得出的结论是,我认为这太贵了。

2)按批处理间隔计算并存储此结果

不太令人满意,因为它涉及延迟。另外,您不想每晚都梳理整个数据库。

3)数据变化时更新聚合

每次数据更改时,这种方法都会涉及更多的工作,但这几乎肯定是您想要做的。

为每个用户创建某种联系人集合。当消息到达时,确保存在该收件人的发件人联系人。也许您还想在收件人删除发件人的最后一条消息时删除联系人。

注意不要碰到实体组事务速率限制(每秒一次写入)。我将向您介绍一些选项:

1) 您可以在每个收件人中存储一个联系人列表:

class Person {
   @Id Long id;
   Set<Key<Person>> contacts;
}

如果收件人同时收到来自 20 个新人的邮件,这将是一个明显的问题。这几乎肯定是个坏主意。另一方面,查找您的联系人是非常快速和高效的。一个小的改进是将其移动到一个由该人作为 parent 的单独实体中,这样您就不会总是加载该数据:

class Contacts {
   @Parent Key<Person> owner;
   @Id long id = 1;   // there's only ever one of these per person, and it should have a predictable key for fetching
   Set<Key<Person>> contacts;
}

当然,单个实体中的集合为您提供了 50,000 个条目限制。如果您首先达到 1M 实体大小限制,它可能会比这略小。如果您的 key 是 ~20 个字符,则大致相同。如果这是一个问题,您可以允许多个联系人实体,此时您会得到类似于 Brett Slatkin 2009 年 Google I/O 演讲中的关系索引实体模式的内容:http://www.youtube.com/watch?v=AgaL6NGpkB8

2) 你可以在另一个方向存储联系人列表

class Person {
   @Id Long id;
   @Index Set<Key<Peson>> contactOf;
}

这使得找出您的联系人是谁的成本有点高 - 您需要仅键查询,而不是简单的按键获取。但是您实际上不再受实体写入速率的限制。人们每秒发送的消息可能不会超过一条,如果他们批量发送 1000 条消息,您可以在单个事务中更新 contactOf。

如上所述,您可能希望将此索引移动到一个单独的实体中:

class Contacts {
   @Parent Key<Person> person;
   @Id long id = 1;   // there's only ever one of these per person, and it should have a predictable key for fetching
   Set<Key<Person>> of;
}

3) 您还可以将这些联系人存储在一个完全独立的实体中

class Contact {
   @Parent Key<Person> person;
   @Id Long id;
   @Index Key<Person> owner;
}

这实际上只是执行解决方案 #2 的一种空间效率较低的方法。

重要的是在发送或接收每条消息时不断更新此结构。

关于java - 对象化关系 : One-to-Many, 我可以有效地做到这一点吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9308997/

相关文章:

java - 在 Spring batch 中查询批处理作业元数据

java - 使用并发标记扫描 GC 收集器?

reflection - Guice 对象上的类层次结构问题

java - 没有注册类 'com.appspot.<projectname>.model.News'

Java:读取 .csv 文件并保存到数组中

java - 使用 Spring Security 的 JavaFX 中基于角色的内容

google-app-engine - 无法从本地 App Engine 开发服务器访问 BigQuery

android - 谷歌验证异常 : Unknown when authenticating with Cloud Endpoints

google-app-engine - 哪些支付网关在 AppEngine 上运行良好?

java - 与 IN 相反的对象化查询