59

许多“BAW”(大网站)正在使用依赖于带有索引的大表的数据存储和检索技术,并使用不会/不能在其查询中使用 JOIN 的查询(BigTable、HQL 等)处理可伸缩性和分片数据库。当您拥有大量非常相关的数据时,它是如何工作的?

我只能推测这种连接的大部分必须在应用程序方面完成,但这不是开始变得昂贵吗?如果您必须对几个不同的表进行多次查询以获取要编译的信息怎么办?与首先使用连接相比,多次访问数据库会不会变得更加昂贵?我想这取决于你有多少数据?

而对于常用的 ORM,他们倾向于如何处理无法使用 join 的问题?在当今大量使用的 ORM 中是否对此提供支持?还是大多数必须接近这种数据水平的项目都倾向于自行推出?

所以这不适用于我正在做的任何当前项目,但这是我几个月来一直在想的事情,我只能推测什么是“最佳实践”。我从来没有需要在我的任何项目中解决这个问题,因为它们从未达到需要的规模。希望这个问题也能帮助其他人..

正如下面有人所说,没有连接的 ORM “不起作用”。是否有其他数据访问层可供开发人员使用此级别的数据?

编辑: 为了澄清一下,Vinko Vrsalovic说:

“我相信 snicker 想要谈论 NO-SQL,其中事务数据被非规范化并用于 Hadoop 或 BigTable 或 Cassandra 方案。”

这确实是我要说的。

那些获得 xkcd 参考的人的奖励积分。

4

7 回答 7

35

在我看来,关系数据库是一种通用工具来对冲你的赌注。现代计算机足够快,并且 RDBMS 已经足够优化,您可以在单个机器上增长到相当可观的大小。通过选择 RDBMS,您可以非常灵活地访问数据,并且能够拥有强大的正确性约束,从而更容易针对数据进行编码。然而,RDBMS 并不代表任何特定问题的良好优化,它只是为您提供轻松更改问题的灵活性。

如果您开始快速增长并意识到您将不得不扩展超出单个数据库服务器的大小,那么您会突然做出更难的选择。您将需要开始识别瓶颈并消除它们。RDBMS 将是一个令人讨厌的相互依赖的结,您必须将其分开。您的数据相互关联越多,您要做的工作就越多,但也许您不必完全解开整个事情。如果您阅读量很大,也许您可​​以通过简单的复制来解决问题。如果您的市场已经饱和并且增长趋于平稳,那么您可以部分非规范化并分片到固定数量的数据库服务器。也许您只有少数可以移动到更具可扩展性的数据存储的问题表。

像 BigTable 这样的可扩展键值存储出现的地方是当上述任何一种方法都不起作用时,并且您拥有如此多的单一类型的数据,即使它被非规范化,单个表对于一台服务器来说也太多了。此时您需要能够任意对其进行分区,并且仍然有一个干净的 API 可以访问它。自然地,当数据分布在这么多机器上时,您就无法拥有需要这些机器相互进行大量通信的算法,而这是许多标准关系算法所需要的。正如您所建议的,这些分布式查询算法有可能比正确索引的关系数据库中的等效 JOIN 需要更多的总处理能力,

现在,一旦您可以水平扩展海量数据集(只需插入更多服务器),可扩展性的难点就完成了。好吧,我不应该说完成,因为这种规模的持续运营和开发比单服务器应用程序要困难得多,但关键是应用程序服务器通常可以通过无共享架构进行扩展,只要它们可以得到他们需要及时的数据。

要回答您关于常用 ORM 如何处理无法使用 JOIN 的问题,简短的回答是它们不会。ORM 代表对象关系映射,ORM 的大部分工作只是翻译谓词逻辑简单的面向对象数据结构的强大关系范式。他们为您提供的大部分价值根本不可能从键值存储中获得。在实践中,您可能需要构建和维护适合您特定需求的自己的数据访问层,因为这些规模的数据配置文件会发生巨大变化,而且我相信对于通用工具的出现有太多的权衡并以 RDBMS 的方式占据主导地位。简而言之,在这种规模下,你总是需要做更多的跑腿工作。

也就是说,看看可以在键值存储原语之上构建什么样的关系或其他聚合功能肯定会很有趣。我真的没有足够的经验来具体评论,但是在企业计算方面有很多关于这可以追溯到很多年前的知识(例如 Oracle),在学术界有很多未开发的理论知识,在谷歌、亚马逊、Facebook 等,但过滤到更广泛的开发社区的知识仍然相当有限。

然而,现在大量应用程序正在迁移到网络,并且世界上越来越多的人在线,不可避免地,越来越多的应用程序必须扩展,最佳实践将开始具体化。AppEngine 和 EC2 等云服务以及 Cassandra 等开源数据库将缩小双方的知识差距。在某种意义上,这与同样处于起步阶段的并行和异步计算密切相关。绝对是成为程序员的迷人时刻。

于 2009-10-16T08:18:39.120 回答
21

你是从一个错误的假设开始的。

数据仓库不像事务应用程序规范化数据那样规范化数据。没有“很多”连接。比较少。

特别是第二和第三范式违规不是“问题”,因为数据仓库很少更新。并且当它们被更新时,通常只需更改状态标志即可将维度行设置为“当前”与“非当前”。

由于您不必担心更新,因此您不会将事物分解到更新不会导致异常关系的 2NF 级别。没有更新意味着没有异常;没有分解也没有连接。您可以预先加入所有内容。

通常,DW 数据按照星型模式进行分解。这将指导您将数据分解为包含度量的数字“事实”表——带单位的数字——以及对维度的外键引用。

最好将维度(或“业务实体”)视为具有属性的真实事物。通常,这包括地理、时间、产品、客户等。这些东西通常具有复杂的层次结构。层次结构通常是任意的,由各种业务报告需求定义,并且不建模为单独的表,而只是用于聚合的维度中的列。


解决您的一些问题。

“这种加入必须在事物的应用程序方面完成”。有点儿。数据在加载之前“预先加入”。维度数据通常是关于该维度的相关源数据的连接。它作为一个相对平坦的结构连接和加载。

它没有更新。插入的是附加的历史记录,而不是更新。

“但那不是开始变得昂贵了吗?”。有点儿。加载数据需要一些小心。但是,报告/分析联接并不多。数据是预先加入的。

ORM 问题在很大程度上没有实际意义,因为数据是预先加入的。您的 ORM 会根据需要映射到事实或维度。除非在特殊情况下,尺寸往往很小并且完全适合内存。例外情况是当您从事金融(银行或保险)或公用事业并拥有大量客户数据库时。这些客户维度很少适合记忆。

于 2009-10-07T15:14:46.987 回答
14

AJOIN是纯关系术语,并非所有数据库都是关系的。

其他数据库模型有其他方式来建立关系。

find a key - fetch the reference - find a key网络数据库使用应使用通用编程语言对其进行编程的无尽链。

代码可以在应用程序端或服务器端运行,但它不是SQL,甚至不是基于集合的。

如果设计得当,网络数据库可以比关系数据库快得多。

例如,网络数据库可以将对另一个实体的引用存储为指向文件中偏移量的直接指针,甚至可以存储有关该实体信息的磁盘上的块。

如果您编写了有效的代码来执行此操作,这会使遍历网络的速度更快。

关系数据库只能将引用存储为基本值对,如整数(或高阶三元组或元组)。

要在关系数据库中查找这些值,引擎应该执行以下操作:

  • 找出包含第一个值的元组所在的位置
  • 找到第二个值
  • B-Tree在保存第二个数字所指数据的a 中找到根的地址
  • 遍历这棵树
  • 找到指向实际表的指针(它可能存储为B-Tree本身,在这种情况下,指针是PRIMARY KEY我们所追求的行的值)
  • 通过指针查找表格所在行或遍历表格
  • 最后,得到结果。

你只能在一定程度上控制它。之后,您只需发出SQL查询并等待。

关系模型旨在简化开发人员的生活,而不是始终和无论如何都实现超速度。

这与汇编语言与高级语言相同,关系模型是高级语言。

您可能想阅读我博客中的文章

,其中我尝试解释几种常用数据库模型之间的差异。

于 2009-10-07T15:13:22.450 回答
4

当您以这种方式对数据进行非规范化时,您这样做是为了避免加入不同项目的成本;您接受某些数据可能是重复的,并且某些组合它的方式可能很困难,这是为了使用简单查询的性能优势。

如果您必须在应用程序级别进行任何大量的加入,这意味着您没有对其进行足够的非规范化。

理想情况下,您将能够对所需的任何数据集进行一次查询。在实践中,您不应该对应用程序的任何方面使用超过两个或三个查询,并且任何应用程序级别的连接都只是从单独的结果集中检索内容以插入到视图中的琐碎工作。

这种事情只有真正海量的数据集才真正需要,并且涉及各种权衡。仅举一个例子:BigTable 不能做聚合查询,比如给你一个计数。它可以用来为您提供一个大致准确的数字 - 从某种意义上说,如果您有 12,149,173 条记录,其中 23,721 条是在过去一小时内添加的,那么您能找到的最好的就是您有“大约 12,100,000 条记录”。如果您的应用程序依赖于在任何给定时刻知道精确的数字,那么您不应该为此使用 BigTable,这是普遍的态度。

于 2009-10-07T15:24:19.133 回答
3

像 facebook 这样的应用程序几乎没有数据更改,大部分时间用户都在发布新项目。因此,在更改项目时需要更新多个记录这一事实是一个较小的问题。

这允许在不遇到更新的常见问题的情况下不对数据进行规范化。

像亚马逊这样的应用程序可以将单个用户的所有数据加载到 RAM 中(购物车到底有多大?),然后更新 RAM 中的数据并将其作为单个数据项写入。

再次消除了对大多数数据进行标准化的需要。

您正在用扩展来换取应用程序开发的简易性,因此如果您不需要扩展至很高的高度,您可能希望保持 RDBMS 提供的应用程序开发的简易性。

于 2009-10-12T11:30:50.023 回答
0

我认为在这些情况下,您将几乎靠自己,并且必须自己滚动所有内容。我没有去过那里,但在我们的一些项目中考虑过。您可以使用关系数据库变得相当大(如 SO 所示),所以我现在将继续享受关系的好处。

于 2009-10-07T15:15:34.753 回答
0

通常,数据仓库是围绕使用连接和数据拆分为维度和事实表(使用所谓的“星型模式”等)构建的

连接通常会预先计算并存储为非规范化表。

我不知道有任何 ORM 工具可以与不允许连接的数据库系统一起使用,因为这些工具通常不被视为传统的关系数据库。

于 2009-10-07T15:17:07.480 回答