然而,在这个话题中,共识似乎是在大型表上进行连接不一定会太昂贵,而且在某种程度上"过分强调"了去规范化。
那么,为什么这些系统不允许连接并强制将所有内容合并到单个表中以实现可扩展性呢?是因为需要存储在这些系统中的数据量很大(许多TB)吗?
对于这些规模,一般的数据库规则是否不适用于这些系统? 还是因为这些数据库类型专门针对存储许多相似对象而设计?
或者我错过了一些更重要的东西?
我对它们不是太熟悉(我只是读了和其他人一样的博客/新闻/示例),但我的看法是,他们选择了以可扩展性为名牺牲了许多正常的关系型数据库功能 - 我会尝试解释。
想象一下你的数据表中有200行。
在Google的数据中心,其中50行存储在A服务器上,50行存储在B服务器上,另外100行存储在C服务器上。此外,D服务器包含来自A和B服务器的冗余数据副本,而E服务器包含C服务器上的数据的冗余副本。
(在现实生活中,我不知道会使用多少台服务器,但它被设置来处理数百万行,所以我想应该会有相当多)。
要“选择 “* where name ='orion'”,基础架构可以将该查询发送到所有服务器,并聚合返回的结果。这使得它们几乎可以在任意数量的服务器上线性扩展(FYI,这几乎就是mapreduce的工作原理)。
然而,这意味着您需要做出一些折衷。
如果您需要在某些数据上进行关系连接,其中数据分散在5个服务器上,那么每个服务器都需要为每行数据从彼此拉取数据。当您在10台服务器上分散了200万行时,请尝试这样做。
这导致了折衷方案#1-没有连接。
此外,根据网络延迟,服务器负载等因素,您的一些数据可能会立即保存,但有些可能需要等待一两秒钟。同样,当您有数十个服务器时,这变得越来越长,而“每个人只需等到最慢的那个完成”正常方法也不再可行。
这导致了折衷方案#2-写入后您的数据可能并非立即可见。
我不确定还有什么其他折衷方案,但这是我能想到的主要两个。
我理解的是,“去规范化,不使用连接”的整个理念存在,并非因为连接本身在大型系统中无法扩展,而是因为在分布式数据库中实现连接几乎是不可能的。
当您存储单一类型的基本不变数据时(就像Google所做的那样),这似乎是相当合理的。我理解得对吗?
如果你谈论的是几乎只读的数据,规则就会改变。在数据经常变化的情况下,去规范化是最困难的,因为需要增加工作量,并且锁定问题更多。如果数据几乎不发生变化,则去规范化就不是那么大的问题。
现今,您需要找到更多用于数据库的互操作环境。通常,您不仅需要关系型数据库,如MySQL或MS SQL,还需要像Hadoop这样的大数据平台或非关系型数据库,如MongoDB。在某些情况下,所有这些数据库将在一个解决方案中使用,因此它们的性能在宏观尺度上必须尽可能相等。这意味着您将不能只使用Azure SQL作为关系型数据库,再使用一个具有2个内核和3GB RAM的VM来运行MongoDB。您必须扩展您的解决方案并尽可能使用数据库作为服务(如果不可能,则在云中构建自己的群集)。