答案 0 :(得分:9)
您指定了网站需要提供的两个特定“视图”:
安排约会。您当前的方案应该可以正常使用 - 您只需要执行您提到的第一个查询。
整体运营情况。我不确定这会带来什么,但如果您需要执行上面提到的四个查询字符串来获得此信息,那么您的设计可能会使用一些改进。详情如下。
四个数据存储区查询本身并不一定是全局的。在您的情况下,问题是两个查询很昂贵,甚至可能不可能。我将通过每个查询:
获取约会列表 - 没问题。此查询将能够扫描索引以有效地检索您指定的日期范围内的约会。
从#1获取每个约会的所有订单项 - 这是一个问题。此查询要求您执行IN
查询。 IN
个查询会转换为N
sub-queries behind the scenes - 因此您最终会从#1获得每个约会的一个查询!这些将并行执行,因此不是那么糟糕。主要问题是IN
查询仅限于一小部分值(最多只有30个值)。如果#1返回的约会密钥超过30个,则此查询将无法执行!
获取订单项引用的所有发票 - 没问题。你这个查询很便宜是正确的,因为你可以直接通过密钥获取所有相关的发票。 (注意:此查询仍然是同步的 - 我不认为异步是您要查找的单词)。
获取#3返回的所有发票的所有付款 - 这是一个问题。与#2一样,此查询将是IN
查询,如果#3返回您需要为其获取付款的中等数量的发票,则该查询将失败。
如果#1和#3返回的项目数量足够小,那么GAE几乎可以能够在允许的限制范围内执行此操作。这应该足以满足您的个人需求 - 听起来您最需要它才能工作,并且不需要扩展到大量用户(它不会)。
改进建议:
Line_Item
,Invoice
和Payment
个实体的密钥。然后,您可以删除IN
个查询。确保这些新的ListProperty
不已编入索引以避免exploding indices 其他不太具体的改进想法:
答案 1 :(得分:7)
正如您所注意到的,此设计无法扩展。它需要4(!!!)DB查询来呈现页面。这太多了:)
使用App Engine数据存储区的主流概念是,您希望在编写内容时尽可能多地完成工作,这样在检索和呈现内容时几乎不需要执行任何操作。你可能会将数据写入很少次,而不是它渲染的次数。
归一化同样是你似乎正在努力的事情。数据存储区在归一化中没有任何价值 - 它可能意味着数据不一致,但这也意味着读取数据的速度会慢得多(4次读取?!!)。由于您的数据读取的频率比写入的频率高,因此优化读取,即使这意味着您的数据偶尔会在短时间内重复或不同步。
不要考虑数据在存储时的外观,而是考虑数据在向用户显示时的外观。尽可能接近该格式存储,即使这意味着在数据存储区中存储预呈现的HTML。阅读将是闪电般的,这是一件好事。
因此,既然您应该优化读取,那么您的写入通常会增长到巨大的比例。如此巨大,以至于您无法在30秒的时间限制内完成请求。嗯,这就是task queue的用途。将您认为模型的“必需品”存储在数据存储区中,然后触发任务队列将其拉出,生成要呈现的HTML,并将其放在后台。这可能意味着您的模型可以立即显示,直到任务完成,因此在这种情况下您需要优雅降级,即使这意味着在数据完全填充之前将其呈现为“缓慢的方式”。任何进一步的读取都会很快。
总之,我没有任何与您的数据库直接相关的具体建议 - 这取决于您希望数据在用户看到时的样子。
我可以给你的是一些关于数据存储的超级有用视频的链接:
答案 2 :(得分:2)
以下是我认为您必须应对的一些应用引擎特定因素:
使用不等式查询时,只能在one property上使用不等式。例如,如果您在7月1日到7月4日之间的过滤日期过滤,则无法按price > 200
过滤
与您可能习惯使用的SQL数据库相比,app引擎上的事务有点棘手。您只能对同一个“entity group”的实体进行交易。