数据库设计 - 谷歌应用引擎

时间:2010-06-25 17:47:30

标签: google-app-engine database-design bigtable appointment

3 个答案:

答案 0 :(得分:9)

您指定了网站需要提供的两个特定“视图”:

  1. 安排约会。您当前的方案应该可以正常使用 - 您只需要执行您提到的第一个查询。

  2. 整体运营情况。我不确定这会带来什么,但如果您需要执行上面提到的四个查询字符串来获得此信息,那么您的设计可能会使用一些改进。详情如下。

  3. 四个数据存储区查询本身并不一定是全局的。在您的情况下,问题是两个查询很昂贵,甚至可能不可能。我将通过每个查询:

    1. 获取约会列表 - 没问题。此查询将能够扫描索引以有效地检索您指定的日期范围内的约会。

    2. 从#1获取每个约会的所有订单项 - 这是一个问题。此查询要求您执行IN查询。 IN个查询会转换为N sub-queries behind the scenes - 因此您最终会从#1获得每个约会的一个查询!这些将并行执行,因此不是那么糟糕。主要问题是IN查询仅限于一小部分值(最多只有30个值)。如果#1返回的约会密钥超过30个,则此查询将无法执行!

    3. 获取订单项引用的所有发票 - 没问题。你这个查询很便宜是正确的,因为你可以直接通过密钥获取所有相关的发票。 (注意:此查询仍然是同步的 - 我不认为异步是您要查找的单词)。

    4. 获取#3返回的所有发票的所有付款 - 这是一个问题。与#2一样,此查询将是IN查询,如果#3返回您需要为其获取付款的中等数量的发票,则该查询将失败。

    5. 如果#1和#3返回的项目数量足够小,那么GAE几乎可以能够在允许的限制范围内执行此操作。这应该足以满足您的个人需求 - 听起来您最需要它才能工作,并且不需要扩展到大量用户(它不会)。

      改进建议:

      • 非规范化!尝试在约会本身的列表中存储与给定约会相关的Line_ItemInvoicePayment个实体的密钥。然后,您可以删除IN个查询。确保这些新的ListProperty 已编入索引以避免exploding indices
      • 出现问题

      其他不太具体的改进想法:

      • 根据您的“整体操作视图”显示的内容,您可以拆分检索所有这些信息。例如,您可能首先显示约会列表,然后当经理想要了解有关特定约会的更多信息时,您可以继续获取与该约会相关的信息。如果您在单个页面上进行此交互,您甚至可以通过AJAX执行此操作。
      • Memcache是​​您的朋友 - 使用它来缓存数据存储区查询的结果(甚至是更高级别的结果),这样您就不必在每次访问时从头开始重新计算它。

答案 1 :(得分:7)

正如您所注意到的,此设计无法扩展。它需要4(!!!)DB查询来呈现页面。这太多了:)

使用App Engine数据存储区的主流概念是,​​您希望在编写内容时尽可能多地完成工作,这样在检索和呈现内容时几乎不需要执行任何操作。你可能会将数据写入很少次,而不是它渲染的次数。

归一化同样是你似乎正在努力的事情。数据存储区在归一化中没有任何价值 - 它可能意味着数据不一致,但这也意味着读取数据的速度会慢得多(4次读取?!!)。由于您的数据读取的频率比写入的频率高,因此优化读取,即使这意味着您的数据偶尔会在短时间内重复或不同步。

不要考虑数据在存储时的外观,而是考虑数据在向用户显示时的外观。尽可能接近该格式存储,即使这意味着在数据存储区中存储预呈现的HTML。阅读将是闪电般的,这是一件好事。

因此,既然您应该优化读取,那么您的写入通常会增长到巨大的比例。如此巨大,以至于您无法在30秒的时间限制内完成请求。嗯,这就是task queue的用途。将您认为模型的“必需品”存储在数据存储区中,然后触发任务队列将其拉出,生成要呈现的HTML,并将其放在后台。这可能意味着您的模型可以立即显示,直到任务完成,因此在这种情况下您需要优雅降级,即使这意味着在数据完全填充之前将其呈现为“缓慢的方式”。任何进一步的读取都会很快。

总之,我没有任何与您的数据库直接相关的具体建议 - 这取决于您希望数据在用户看到时的样子。

可以给你的是一些关于数据存储的超级有用视频的链接:

  • Brett Slatkin的20082009谈论在App Engine上构建可扩展的复杂应用程序,以及this year关于数据管道的一个很好的应用程序(我认为这不是直接适用的,但一般来说真的很有用)
  • App Engine Under the Covers:App Engine如何在幕后完成它的工作
  • AppStats:了解您正在执行的数据存储读取数量的好方法,以及减少该数量的一些提示

答案 2 :(得分:2)

以下是我认为您必须应对的一些应用引擎特定因素:

  • 使用不等式查询时,只能在one property上使用不等式。例如,如果您在7月1日到7月4日之间的过滤日期过滤,则无法按price > 200过滤

  • 与您可能习惯使用的SQL数据库相比,app引擎上的事务有点棘手。您只能对同一个“entity group”的实体进行交易。