为什么 NoSQL 比 RDBMS 更擅长“扩展”?

我在 技术博客中读过下面的文章,讨论了 NoSQL 的优点和缺点:

”多年来,为了提高数据库服务器的性能,数据库管理员不得不购买更大的服务器作为数据库 负载增加(扩展)而不是分发数据库 随着负载的增加(向外扩展) ,跨多个“主机” 通常不容易扩展,但较新的 NoSQL 数据库可以 实际上是设计来容易扩展,以利用新的节点和 通常都是以低成本的大宗商品硬件为设计理念。”

我对 RDBMS 和 NoSQL 的可伸缩性感到困惑。

我的困惑是:

  1. 为什么关系数据库管理系统不能扩展?以及购买更大的服务器而不是更便宜的服务器的原因。
  2. 为什么 NoSQL 能够扩展?
43350 次浏览

RDBMS 具有 ACID (http://en.wikipedia.org/wiki/ACID)并支持事务。由于这些概念,使用 RDBMS 进行“扩展”更难实现。

NoSQL 解决方案通常提供记录级原子性,但不能保证一系列操作将成功(事务)。

它归结为: 为了保持数据完整性和支持事务,多服务器 RDBMS 需要有一个快速的后端通信通道来同步所有可能的事务和写,同时防止/处理死锁。

这就是为什么您通常只看到1个主(作者)和多个从(读者)。

典型的 RDBM 强烈地保证了一致性。这在一定程度上要求每个事务的节点之间进行通信。这限制了向外扩展的能力,因为更多的节点意味着更多的通信。

NoSQL 系统做出了不同的权衡。例如,它们不能保证第二个会话会立即看到第一个会话提交的数据。因此,将存储某些数据的事务与使该数据对每个用户可用的过程分离开来。谷歌“最终保持一致”。因此,单个事务不需要等待任何(或更少)节点间通信。因此,它们能够更容易地利用大量节点。

所以我一直在试图弄清楚 NoSQL 和 RDBMS 之间的真正底线,结果总是得到一个不怎么样的响应。在我的研究中,NoSQL 和 SQL 之间有两个主要的区别,其中只有一个是真正的优势。

  1. ACID vs BASE -NoSQL 通常遗漏了 SQL 的一些 ACID 特性,这是一种“欺骗”,通过将这一抽象层留给程序员来获得更高的性能。这已经被之前的海报覆盖了。

  2. 水平伸缩 -NoSQL 的真正优势是水平伸缩,即分片。考虑到 NoSQL“文档”是一种“自包含”对象,对象可以位于不同的服务器上,而不必担心从多个服务器连接行,关系模型就是这种情况。

假设我们想返回这样一个对象:

post {
id: 1
title: 'My post'
content: 'The content'
comments: {
comment: {
id: 1
}
comment: {
id: 2
}
...


views: {
view: {
user: 1
}
view: {
user: 2
}
...
}
}

在 NoSQL 中,该对象基本上按原样存储,因此可以作为一种自包含对象驻留在单个服务器上,而不需要与可以驻留在其他 DB 服务器上的其他表中的数据进行连接。

但是,对于关系数据库,文章需要与来自 comments表的注释以及来自 views表的视图联接。这在 SQL 中不成问题,直到数据库被分解成碎片,在这种情况下,“注释1”可能在一个数据库服务器上,而“注释2”则在另一个数据库服务器上。这使得在水平扩展的 RDBMS 中创建相同的对象比在 NoSQL DB 中创建相同的对象更加困难。

有没有数据库专家证实或争论这些观点?

对于 NO SQL, 1.与一个集合相关的所有子集都在同一服务器上的同一位置等,并且没有从另一个服务器查找数据的连接操作。

2.没有模式,因此在任何服务器上都不需要锁,事务处理留给客户机。

以上两种方法节省了 NO-SQL 中的大量伸缩开销。

在 RDBMS 中,当数据量变得很大时,可能会发生表分布在多个系统中的情况,在这种情况下,执行 JOIN 等操作的速度非常慢。

如果 NoSQL 中的一般相关数据存储在同一台机器上(无论是在单个文档-面向文档的数据库中,还是在宽列数据存储中,相关列都存储在同一台机器上)。因此,它很容易在许多低端机器上扩展,很明显,在这种情况下,在多个地方会出现重复数据,而在 RDBMS 中则不是这种情况

为什么 NoSQL 数据库比 SQL 数据库更容易水平扩展?我一直在想为什么人们总是这么说。我碰到过许多文章,它们只是把我和它们不熟悉的行业术语和模糊的假设混淆了。我建议您阅读 Martin Kleppman 的《设计数据密集型应用程序》。此外,我将分享一些我对这个主题的理解。

JOINS -在多对一或多对多关系的情况下,目前发明的任何数据库都无法将数据保存在一个表或文档中,因此如果数据被分片(或分区) ,无论是 SQL 还是 NoSQL,延迟都是相同的,数据库必须同时查找这两个文档。NoSQL 似乎只在一对多关系的情况下占主导地位。例如:

NoSql

学生

{
"name": "manvendra",
"education": [
{
"id": 1,
"Degree": "High School"
},
{
"id": 2,
"Degree": "B.Tech"
}
]
}

教育学院收费

[
{
"id": "1",
"name": "army public school"
},
{
"id": "2",
"name": "ABES Engineering College"
}
]

Sql

学生桌

id | name
1  | Manvendra

教育学院

id | Name
1  | Army public school
2  | ABES Engineering college

研究表

student  | education institute | degree
1        | 1                   | high school
1        | 2                   | B.tech

现在假设在 NoSql 的情况下,如果两个数据集的数据都在不同的节点上,那么需要一些额外的时间来解析教育机构的 id,这种情况在 SQL 数据库的情况下是相似的,那么这样做的好处在哪里呢?我想不出来。

还有,你一定在想为什么我们不能把教育机构的信息也存储在同一个学生收藏中,然后就会像这样:

{
"name": "manvendra",
"education": [
{
"name": "Army public school",
"Degree": "High School"
},
{
"name": "ABES Engineering College",
"Degree": "B.Tech"
}
]
}

这是一个很糟糕的设计,因为学生和教育机构之间有一个多对多的关系,很多学生可能在同一所学校学习,所以明天如果学校名称或者任何信息有变化的话,在任何地方都很难改变。

然而,在一对多关系的情况下,我们可以将所有的信息聚合在一起,例如: 考虑一个客户和一个订单关系

{
"name": "manvendra",
"order": [
{
"item": "kindle",
"price": "7999"
},
{
"item":"iphone 12",
"price":"too much"
}
]
}

由于订单只属于一个客户,因此在一个地方存储订单信息是有意义的,但是存储项目 ID 或名称是另一种选择,如果我们在这里使用 SQL 数据库,将有两个表与订单和客户,将不会给查询提供良好的结果,如果数据不存储在同一个节点。

因此,在参数中说明为什么 NoSql 数据库更容易水平伸缩是没有意义的。

交易

SQL (Postgres、 MySQL 等)和 NoSQL (MongoDB、 Amazon 的 DynamoDB 等)都支持事务,因此没有什么可讨论的了。

ACID 被过度使用,就像 CAP 一样,实际上它只是向客户端显示一个数据副本,而实际上可能有多个数据副本(以增强可用性、容错性等) ,以及数据库使用什么策略来做到这一点。例如在 Postgres 的主从分布式系统中,人们可以选择同步或异步复制,可以使用 WAL (提前写日志)进行复制,MongoDB 的情况也是如此,只是在 WAL 的地方有 oplog (操作日志) ,既支持流复制,也支持故障转移。 那有什么区别呢?实际上,我找不到一个非常有力的理由来解释为什么 NoSql 数据库可以轻松扩展。我要说的是 NoSql 是最新的,因此数据库提供了现成的横向扩展支持,例如 MongoDB 中的 Mongos,它们完成了所有分片文档、将请求路由到特定碎片等肮脏的工作。因此,明天如果 Postgres 或 MySQL 提出一种智能分片表的机制,使所有相关数据大多保存在一个节点中,那么这场争论可能就会结束,因为关系数据库中没有任何内在的东西阻止它横向扩展。

从乐观的角度来看,我相信在不久的将来,一切都将与战略有关。您计划如何扩展以及这些策略将与您如何在表或文档中存储数据无关。例如,在 Amazon 的 DocumentDB 中,有一个自动伸缩的概念,但是如果你想通过分片来实现这一点,那么每次伸缩时都要复制数据将是一个负担。在 DocumentDB 中,它被看作是一个共享集群卷(数据存储与计算分离) ,对于所有实例(主要或次要)来说,它只是一个共享磁盘,为了避免共享磁盘故障的风险,DocumentDB 将共享磁盘的数据复制到不同可用性区域的其他六个磁盘上。因此,这里需要指出的是,DocumentDB 混合了共享磁盘和标准复制策略的概念,以实现其目标。因此,重要的是您在数据库中使用的策略