3

我最近读了很多关于数据库查询中的连接如何减慢速度的文章。显然 Google App Engine 甚至不允许它们。

我想知道人们如何设计一个没有连接的应用程序。例如,我正在开发一个具有contacts和的应用程序organizations。一个联系人可以在多个组织中,一个组织可以有多个联系人。如果没有连接两个实体的第三张表,怎么可能建立这种关系......

contacts --< contacts_organizations >-- organizations

这是否意味着在 GAE 中不能建立多对多关系?您只是省略了需要加入的功能?

我猜您可能organizations在表中有一个 TEXT 列,其中contacts包含以空格分隔的每个联系人的组织 ID 列表。不过这似乎有点奇怪。

4

7 回答 7

13

这是一个将软件减速的神话,就像断言在应用程序代码中编写循环会使软件减速一样是一个神话。

我的意思是,为什么要写一个循环?那只是一次又一次地运行相同的代码行!一次还不够吗?这是一个巨大的浪费!

上述陈述旨在具有讽刺意味。

我的观点是,一个查询包含一个连接,目的是:得到正确的答案。低效或不必要地使用连接当然是糟糕的设计,例如将循环不变的代码放入循环中。

避免连接作为一般策略是过早优化的一个例子。如果你编写高效代码的方法是想出这样的一揽子规则,那么避免连接对你没有帮助。


至于 Google App Engine,它确实支持实体之间的关系,但由于它不是严格意义上的关系数据库模型,所以连接的概念并没有真正出现。相反,您可以从给定的引用中获取相关实体,这更像是模型的 ORM 接口,它与 SQL 中的联接不同。

您可以在此处阅读更多信息: http ://code.google.com/appengine/articles/modeling.html

(该链接在此线程的另一个答案中,但已被删除)

于 2009-01-04T21:20:15.270 回答
7

挑剔点:Google 不允许在其数据库中使用 JOIN 以防止用户运行“昂贵”的查询;数据库不是关系型的,所以“JOIN”SQL 动词一开始并不真正适用。

通过这种方式,BigTable 与Amazon 的 SimpleDB相同- 数据被非规范化并剥离了模式,因此您可以有效地最终获得巨大、高效的哈希表,其中包含桶中允许的任意数据。

这些哈希表非常非常容易扩展,尤其是与关系数据库相比。对于像 GAE 这样的应用程序,极端的可扩展性比完整的功能集具有更高的优先级。

于 2009-01-04T22:33:41.193 回答
3

您使用db.ReferenceProperty来链接对象,有关详细信息和示例,请参阅Google App Engine:一对多 JOIN

于 2009-01-04T20:48:31.530 回答
3

通常,当您谈论不允许连接的数据库时,您谈论的是不一定适合一台服务器的非常大的数据库。最近的例子是云数据库,如Amazon 的 SimpleDBMicrosoft 的 SQL Data ServicesGoogle 的 App Engine Datastore。有些提供有限的连接能力,但最大的困难是跨“分区”进行连接。在像这样的大型数据库中,您对数据进行分区,因此它不必驻留在同一台服务器上。您必须决定对它进行分区的正确方法。

在您的示例中,我会将组织键列表存储在联系人表的字段中,反之亦然。这些数据库的设计与典型的规范化数据库不同。这些表通常是“稀疏表”,这基本上意味着每条记录可以有任意数量的字段,这些字段基本上是名称/值对。想想亚马逊上的产品表,以及不同类型的产品可能有多少不同的字段。书籍有页数,但 MP3 有持续时间。在稀疏表中,这些记录将存储在同一个表中。

于 2009-01-05T00:45:18.040 回答
1

我认为谷歌正在剥夺你一些计算量大的机制,所以你会寻找可以利用更多其他类型资源的方法,例如硬盘维护参考表和/或计数表,而不是浪费 CPU 周期来连接和聚合计算。

这并非不可能,您只需要使用其他类型的资源来帮助您解决它。

于 2009-01-04T21:36:09.733 回答
1

您可以在您的应用程序而不是数据库服务器中执行连接,方法是分别从每个表中获取结果然后将它们组合起来,但是对于大多数连接来说,这样做只会减慢您的速度,因为进行多次数据库往返而不是仅仅一。

但是:诚实的事实是加入不是你的问题。到了他们的时候,如果有的话,你甚至不需要问这个问题。您可以数出实际项目的数量,这些项目在您的手指上(主要是 Ebay),并且没有证据表明完全消除连接是这些项目可以扩展的唯一方法。

于 2009-01-05T01:00:49.897 回答
0

您提到的数据库充其量是版本化的记录存储,旨在跨多个服务器存储大量数据。称它们为“数据库”将是一个延伸。不支持连接,也不支持 ACID 事务,回滚等。您可以编写没有它们的应用程序,但通常需要做更多的工作来提供功能。

为了:

contacts --< contacts_organizations >-- organizations

您可以对联系人中的组织和组织中的联系人进行去规范化和存储。但是您必须在应用程序处理同时更新到两个表时强制执行参照完整性。

更好的解决方案是将数据存储在三个表中并自己进行“连接”。

于 2009-07-23T22:02:41.060 回答