Java 谷歌应用引擎中的非规范化? 背景:

Java 谷歌应用引擎中的非规范化? 背景:,java,google-app-engine,database-design,denormalization,bigtable,Java,Google App Engine,Database Design,Denormalization,Bigtable,我正在为Java使用谷歌应用程序引擎(GAE)。我正在努力设计一个能够发挥big table优势和劣势的数据模型,以下是之前的两篇相关文章: 我已经初步决定使用一个完全规范化的主干网,将非规范化的属性添加到实体中,这样大多数客户机请求只需一个查询即可得到服务 我认为完全规范化的主干将: 如果我在反规范化过程中编码错误,请帮助维护数据完整性 从客户端的角度在一个操作中启用写入 允许对数据进行任何类型的意外查询(只要愿意等待) 而非规范化数据将: 使大多数客户端请求能够非常快速地得到服

我正在为Java使用谷歌应用程序引擎(GAE)。我正在努力设计一个能够发挥big table优势和劣势的数据模型,以下是之前的两篇相关文章:

我已经初步决定使用一个完全规范化的主干网,将非规范化的属性添加到实体中,这样大多数客户机请求只需一个查询即可得到服务

我认为完全规范化的主干将:

  • 如果我在反规范化过程中编码错误,请帮助维护数据完整性
  • 从客户端的角度在一个操作中启用写入
  • 允许对数据进行任何类型的意外查询(只要愿意等待)
而非规范化数据将:

  • 使大多数客户端请求能够非常快速地得到服务
基本反规范化技术: 我观看了一个应用引擎视频,描述了一种称为“扇出”的技术。其思想是快速写入规范化数据,然后使用任务队列在后台完成反规范化,而客户端不必等待。我把视频放在这里作为参考,但它有一个小时长,没有必要为了理解这个问题而观看它:

如果我使用这种“扇出”技术,每次客户端修改一些数据时,应用程序都会在一次快速写入中更新规范化模型,然后向任务队列发出非规范化指令,这样客户端就不必等待它们完成

问题::: 使用任务队列更新数据的非规范化版本的问题在于,客户机可能会在任务队列完成该数据的非规范化之前,对他们刚刚修改的数据发出读取请求。这将为客户机提供与他们最近的请求不一致的陈旧数据,从而使客户机感到困惑,并使应用程序出现错误

作为补救措施,我建议通过URLFetch对应用程序中的其他URL进行异步调用,并行展开非规范化操作:应用程序将等待所有异步调用完成,然后再响应客户端请求

例如,如果我有一个“约会”实体和一个“客户”实体。每一次预约都将包括一份非规范化的客户信息副本,供其预定的预约对象使用。如果客户更改了他们的名字,应用程序将进行30次异步调用;每个受影响的预约资源一个,以便更改每个预约资源中客户名字的副本

理论上,这一切都可以并行进行。所有这些信息都可以在大约1到2次写入数据存储所需的时间内更新。在非规范化完成后,可以及时向客户做出响应,消除客户暴露于不一致数据的可能性

我看到的最大的潜在问题是,应用程序在任何时候都不能有超过10个异步请求调用(这里有文档记录):)

建议的非规范化技术(递归异步扇出):: 我建议的补救方法是将非规范化指令发送到另一个资源,该资源递归地将指令拆分为大小相等的较小块,并使用较小的块作为参数调用自己,直到每个块中的指令数量足够小,可以直接执行。例如,如果有30个相关约会的客户更改了他们名字的拼写。我会打电话给非规范化资源,告诉它更新所有30个约会。然后,它将这些指令分成10组3条指令,并使用每组3条指令向其自己的URL发出10个异步请求。一旦指令集小于10,资源就会根据每条指令发出异步请求

我对这种方法的关注是:

  • 这可能被解释为试图规避应用程序引擎的规则,这将导致问题。(它甚至不允许URL调用自己,所以事实上我必须有两个URL资源来处理相互调用的递归)
  • 它很复杂,有多个潜在故障点

我非常感谢您对这种方法的一些意见。

这听起来非常复杂,设计越复杂,编码和维护就越困难

假设您需要对数据进行反规范化,我建议只使用基本的反规范化技术,但要跟踪哪些对象正在更新。如果客户机请求正在更新的对象,您知道需要查询数据库以获取更新的数据;如果没有,您可以依赖非规范化数据。一旦任务队列完成,它就可以从“正在更新”列表中删除该对象,并且一切都可以依赖于非规范化的数据


一个复杂的版本甚至可以跟踪每个对象被编辑的时间,这样一个给定的对象就可以知道它是否已经被任务队列更新了。

听起来像是在重新实现物化视图。

我建议您使用Memcache的简单解决方案。从客户端更新后,您可以在Memcache中保存一个实体,存储状态为“更新”的已更新实体的密钥。当任务完成时,它将删除Memcached状态。然后,您将在读取之前检查状态,以便在实体仍处于“锁定”状态时正确通知用户。

您真的确定使用常规数据库不会更好吗?如果你的应用程序不适合GAE/BigTable(听起来很可能是这样),那么你的生活就会变得不必要的复杂。此外,这听起来并不比常规数据库更适合BigTable