9

我正处于开发体育统计网站(终极飞盘)的初期阶段,并希望知道您的意见,如果Google App Engine适合我。使用GAE数据存储的复杂查询

我使用Django在Python中编写它,并且对标准RDBMS已经很舒服多年了,但是这个站点是一个长期项目,而且我期待着非常大量的数据,因此我希望GAE的“无限”缩放数据存储提供。绝大多数对数据库的查询都会返回非常标准的结果,这会使数据存储看起来像是一个合理的选择。但是,我希望能够在将来进行极其复杂的查询,以提出新的统计指标或简单地提出有趣的结果。我打算将来会做很多这样的事情,但在数据已经收集之前不会知道这些查询是什么。

例如,你经常看到棒球统计分析师拿出了荒谬的统计数字,例如“这只是过去50年来的第一次,两个左手投手的姓氏以'Z'开头已经引发一击封闭在背靠背的日子里“。我希望在将来能够灵活地提出任何疑问。 :)

但是,我的印象是,像bigtable这样的非关系数据库要求您事先提供包含冗余数据的模型,并且所有工作都是在插入而不是抓取中进行的。我已经构建了包含几乎所有我需要查询的数据的django模型,但是我不知道什么是非常规模型,我希望从现在开始有一两年的时间。因此,我觉得在未来的GAE数据存储中进行复杂的查询会非常困难,并且需要我在使用python处理之前从服务器中提取大量信息。

谷歌应用程序引擎数据存储只是为我想要做的错误?或者我只是想念一些东西。非常感谢!

更新: 感谢您的回应。我意识到,我还应该提到,很多这些复杂的查询都是我希望用户能够做的查询,因此使离线数据库不是真正的选择。例如,用户应该能够看到各种特定球员在特定比赛或赛季期间在场上同时进行比赛的多种统计数据。虽然这些查询不如标准汇总统计信息那么频繁,但它们仍会定期发生。

有一个关系型数据库以及在GAE数据存储将是巨大的,但Django不默认还不支持多分贝的和修补的解决方案一起听起来困难和混乱。 Eric Florenzano对两个使用django模型的数据库都有nice solution,但如果我使用GAE数据存储,则必须改用应用引擎的db模型。想出一个好的解决方案,就像他为这个复杂的问题所做的那样,在这一点上超出了我的技能水平。

现在我最喜欢的两种选择是使用GAE任务队列来完成困难的查询,或者转到像webfaction这样的更加标准的webhost,然后在数据增长时我的表格会非规范化,我需要提高性能。

回答

12

您所描述的实质上是OLAP - 在线分析处理。 OLAP是'传统'RDBMS非常擅长的一件事,部分原因在于SQL的灵活性和强大功能 - 而像App Engine数据存储这样的非关系数据库则不是。听起来好像比较正常访问,虽然你的OLAP类型的查询会比较频繁,所以我建议以下两种方法之一:

  • 镜像所有间隔数据从App Engine数据存储到关系数据库,并对关系数据库执行分析查询。面向用户的流量仍由数据存储提供服务,因此您可以获得所有优势,但您可以使用可以执行复杂查询的离线副本。
  • 使用App Engine的Task Queue支持来执行检查大型数据集的查询。您可以用Python或Java编写查询,然后使用Task Queue在非常大的数据集中执行它,并在完成后异步获取结果。显然有一些基础设施工作需要做到这一点(尽管如此,请关注my blog这个未来的项目)。
+0

我希望你能回答:)。感谢这两个伟大的建议。我已更新了我的问题,以解决您的第一个建议中的潜在问题。至于你的第二,我甚至没有意识到任务队列存在!这需要一些研究,但我想知道这是否能解决我所有的问题。 – Spike 2009-11-11 06:09:19

+1

几年后,是的..但这个答案仍然是黄金,但现在你可以使用谷歌云数据库而不是脱机数据库,并有你的蛋糕和吃它! (http://stackoverflow.com/q/10905861/525541) – MindWire 2012-06-06 18:29:37

6

我要说的是,BigTable中类型的存储是不太适合的统计应用,对于你提到的非常原因。但这是一个你必须做的传统交易。我很少发现自己使用真正复杂的查询的灵活性,但很多时候被迫提出更多专门的解决方案来处理那些本来不应该放在db中的东西。

如果您坚持使用RDBMS,可以通过Hibernates持久性策略和Hibernate Shards来实现逻辑分区和非规范化。如果您可以处理稍慢的处理,您也可以在bigtable类型的存储上执行SQL查询(请参阅hadoop pig latin)。

+0

感谢您的建议!我可能可以忍受某些事情的较慢处理,并且如果可能的话,真的很想使用bigtable。 – Spike 2009-11-11 06:11:57

2

GAE数据存储是与RDBMS完全不同的动物。这是很容易在一个关系数据库写类似:

SELECT STDEV(player_score) 
FROM Table 
WHERE player_id = 1234 
    AND game_date BETWEEN '2007-01-01' AND '2009-11-10' 
    AND city <> 'London' 

GAE查询有许多限制 - see here - 因此它是不容易翻译这个。对于集合函数(sum,stdev等),您必须将所有数据提取到应用程序层,并计算或维护每个数据插入/更新时更新的聚合实体。

更新
您可以考虑使用GAE的UI和业务逻辑,但在像云有不同的关系数据库别处:微软SQL,在亚马逊,MySQL的DB2其他地方 - 而不是使用GAE的数据存储为预先计算的聚合和统计数据。因此统计数据仍然在RDBMS中计算,但是您将结果(部分,预先计算的统计数据)存储在GAE存储中;类似于分析立方体中的三维存储。

+0

我真的很感激你的意见。我相当设置使用Django的UI而不是appengine。混合使用两种不同的数据库类型确实听起来像是一种潜在的好方法,它听起来非常难以设置... – Spike 2009-11-11 06:14:56