没有加入的生活......理解和共同的实践

sni*_*ker 59 orm hadoop join bigtable nosql

很多"BAW"(大屁股网站)正在使用数据存储和检索技术,这些技术依赖于带有索引的巨大表,并使用在查询中不会/不能使用JOIN的查询(BigTable,HQL等)处理可伸缩性和分片数据库.当你有大量和非常相关的数据时,它是如何工作的?

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

对于常用的ORM,它们如何处理无法使用连接?今天在大量使用的ORM中是否有对此的支持?或者大多数必须接近这一级别数据的项目是否倾向于自行推出?

所以这不适用于我现在正在进行的任何项目,但现在已经有几个月了,我只能猜测"最佳实践"是什么.我从来没有必要在任何项目中解决这个问题,因为他们从未达到过需要的规模.希望这个问题能帮助其他人......

如下所述,ORM在没有连接的情况下"无法正常工作".是否有其他数据访问层已经可供处理此级别数据的开发人员使用?

编辑: 有些澄清,Vinko Vrsalovic说:

"我相信窃笑者想要讨论NO-SQL,其中事务数据被非规范化并在Hadoop或BigTable或Cassandra方案中使用."

这正是我所说的.

抓住xkcd参考的人的奖励积分.

gtd*_*gtd 35

我看待它的方式,关系数据库是一个通用的工具来对冲你的赌注.现代计算机足够快,RDBMS'已经过充分优化,你可以在一个盒子上成长到相当可观的尺寸.通过选择RDBMS,您可以非常灵活地访问数据,并具有强大的正确性约束,从而可以更轻松地对数据进行编码.但是,RDBMS不能代表任何特定问题的良好优化,它只是让您可以轻松地轻松更改问题.

如果您开始快速增长并意识到您将不得不扩展到超过单个数据库服务器的规模,那么您突然有更难的选择.您需要开始识别瓶颈并将其删除.RDBMS将成为一个令人讨厌的狡猾的共同依赖结,你必须分开.您的数据越相互联系,您将需要做的工作就越多,但也许您不必完全解开整个问题.如果你读得很重,也许你可以通过简单的复制来实现.如果你正在使你的市场饱和并且增长趋于平稳,那么你可以将部分非规范化和分片到固定数量的数据库服务器.也许你只有一些问题表可以转移到一个更具伸缩性的数据存储.也许您的使用配置文件非常缓存,您可以将负载迁移到一个巨大的memcached集群.

在像BigTable这样的可扩展键值存储进入的情况下,当上述任何一个都无法工作时,并且您拥有单一类型的大量数据,即使它被非规范化,单个表对于一个服务器来说也是太多了.此时,您需要能够对其进行任意分区,并且仍然可以使用干净的API来访问它.当然,当数据分布在如此多的机器上时,您就无法拥有需要这些机器相互通信的算法,这是许多标准关系算法所需要的.正如您所建议的那样,这些分布式查询算法在正确索引的关系数据库中可能需要比等效JOIN更多的总处理能力,但由于它们是并行化的,因此实时性能比任何一台机器都要好几个数量级(假设一个可以保存整个索引的机器甚至存在).

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

要回答关于常用ORM如何处理无法使用JOIN的问题,简短的答案是他们没有.ORM代表对象关系映射,ORM的大部分工作只是翻译谓词逻辑简单面向对象数据结构的强大关系范例.他们给你的大部分价值根本不可能来自一个键值商店.在实践中,您可能需要建立和维护适合您特定需求的数据访问层,因为这些规模的数据配置文件会发生巨大变化,我相信对于通用工具的出现会有太多的权衡因素并成为RDBMS的主导方式.简而言之,你将不得不在这个规模上做更多的工作.

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

然而,现在很多应用程序正在转向网络,并且越来越多的世界人口在线,不可避免地会有越来越多的应用程序需要扩展,最佳实践将开始明确.知识差距将由AppEngine和EC2等云服务以及Cassandra等开源数据库从双方削减.在某种意义上,这与并行和异步计算密切相关,这也是处于起步阶段.绝对是成为程序员的迷人时光.


S.L*_*ott 21

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

数据仓库不会像事务应用程序规范化那样对数据进行规范化.没有"很多"的连接.相对较少.

特别是第二和第三范式违规不是"问题",因为数据仓库很少更新.当它们被更新时,通常只有一个状态标志改变,以使维度行为"当前"与"不是当前".

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

通常,DW数据根据星型模式进行分解.这将指导您将数据分解为包含度量的数字"事实"表 - 包含单位的数字 - 以及对维度的外键引用.

维度(或"业务实体")最好被认为是具有属性的真实世界.通常,这包括地理,时间,产品,客户等等.这些事情通常具有复杂的层次结构.层次结构通常是任意的,由各种业务报告需求定义,而不是作为单独的表建模,而只是用于聚合的维度中的列.


解决你的一些问题.

"这种加入必须在事物的应用方面完成".的种类.数据在加载之前是"预先连接"的.维度数据通常是关于该维度的相关源数据的联接.它作为一个相对扁平的结构连接和装载.

它没有更新.而不是更新,插入额外的历史记录.

"但这不会开始变得昂贵吗?" 的种类.获取数据需要一些小心.但是,没有很多报告/分析连接.数据已预先加入.

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

  • IMO,鉴于问题编辑,这现在是一个非答案(一个非常好的非答案,顺便说一句).我相信窃笑者想谈谈NO-SQL(blog.oskarsson.nu/2009/06/...),其中事务数据被非规范化并在Hadoop或BigTable或Cassandra方案中使用.现在在问题的任何地方都没有提到数据仓库. (2认同)

Qua*_*noi 14

A JOIN是纯粹的关系术语,并非所有数据库都是关系型的.

其他数据库模型还有其他建立关系的方法.

网络数据库使用其循环链find a key - fetch the reference - find a key应使用通用编程语言进行编程.

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

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

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

这使得遍历网络的速度更快 - 如果你写了一个有效的代码来做到这一点.

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

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

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

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

关系模型是为了简化开发人员的生活,而不是为了实现超级速度而无论如何.

这与汇编语言与高级语言相同,关系模型是更高级别的语言.

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

,我试图解释几种常用数据库模型之间的差异.