关系数据库(RDBMS)和NoSQL的比较

现在主流的SQL关系数据库有:oracle、SQL Server MySQL

NoSQL数据库有BigTable、HBase、Cassandra、SimpleDB、CouchDB、MongoDB和Redis等。

SQL月NoSQL的主要区别有:

1.数据的存储方式

关系数据库用表来存储数据,NoSQL数据库则用JSON、键值对、文档等方式存储数据,具体请看下图(http://zhuanlan.51cto.com/art/201712/561201.htm)

关系数据库(RDBMS)和NoSQL的比较_第1张图片

 

看这个图就可以知道,NoSQL拥有更加多样化的存储方式,并且使用类似JSON格式进行存储可以更好地支持半结构化和非结构数据。

非结构化数据::行数据,即用二维表可以表达的数据,SQL关系数据库

半结构化数据:相比于结构化数据而言,不方便用数据库二维表表现的数据。包括所有格式的办公文档、文本、图片、各类报表、图像和音频/视频信息等等。

半结构化数据:介于结构化数据和非结构化数据之间的数据。例如Html、xml、树、图等,这类数据似有结构可循(用元素支撑其结构),但又不便于用二维表表达(元素间的嵌套往往比较复杂)。

可以说,NoSQL更方便存储非结构化、半结构化的数据。

2.可扩展性

关系数据库:一般是向上扩展。

NoSQL:便于水平扩展。

先来了解一下两种扩展方式。(https://blog.csdn.net/qq_38737992/article/details/88817625)

  • 向上扩展

向上扩展,买更好的服务器,这种方式比较简单,一般情况下向上扩展就可以解决问题,但是如果代价太大了(规格越高的硬件需要花费的钱越多),就不可取了。而且向上扩展总有极限的。

  • 横向扩展

横向扩展是通过副本(读写分离)、垂直切分,水平切分的方式,把不同的数据放在不同的节点(物理部署的MySQL实例)中。

读写分离:给数据库(主数据库)增加一个从数据库,主数据库负责文本的写操作(增,删,改),从数据库负责数据读的操作,如下图所示。也可以一主多从(一个主数据库,多个从数据库),不过需要进行负载均衡。                           

垂直切分:按照功能模块划分数据,举一个例子:一个电商网站,数据库中可能有库存管理的数据,用户管理的数据,订单管理的数据,他们属于不同的功能,可以将一个数据库分成三个数据库,库存管理的数据库,用户管理的数据库,订单管理的数据数据库。

水平切分:将同一个表中的数据进行分片保存到不同的数据库中。例如:一个用户表,我们可以将用户分片保存的不同的数据库中,可以根据 用户的ID(userID),userID%3==0的用户放到一个库中,userID%3==1 放到一个库中,userID%3==2放到一个库中,如下图所示。

看了扩展方式的定义,我们可以思考为什么RDBMS难以横向扩展。

RDBMS的表与表之间维护着关系,一条查询语句往往涉及到多个表,用多个条件进行连接。这时如果要进行横向扩展(无论哪种方式都是要将数据分别放在多个数据库,乃至多个服务器上),在进行增删改查的时候就很麻烦了,因为要在多台服务器之间进行连接(join)操作。而NoSQL的存储方式,实际上是通过将所有的属性、字段、内容等存储在一个Id下,这样就避免了通过关系去维护多张表,即便是将数据放在多个服务器上,也可以轻松实现对数据的CRUD操作。另外,RDBMS的事务有ACID四大特性,也阻碍了横向扩展(至于为什么目前我也不是很清楚,请大侠指点)。NoSQL牺牲了一致性,各个副本之间仅追求最终一致性,有利于分布式存储。

扩展能力直接影响着分布式技术在数据库中的应用:

数据库所采用的分布式模型通常有分片和复制,复制又可以分为主从复制和对等复制。分片是将数据的各个部分存放在不同的服务器中,以此实现横向扩展。复制是将数据复制到多个节点。

主从复制模式下,有一个“主节点”用来负责更新操作;其余节点称为“从节点”,用来负责读数据;主从复制就是要让从节点和主节点同步(将数据从主节点复制到从节点)。该模式下,可以通过增加更多的从节点来进行水平扩展,以增强对数据的读取性能;当主节点出错后,从节点依然可以处理读取请求,增强了读取操作的故障恢复能力;并且当主节点出错后,可以很快指派一个从节点为新的主节点,尽快恢复主节点的写操作。但该模式适用于读操作较为频繁的情况,当写操作非常频繁时,频繁地将数据复制到从节点的效果并不好。

对等复制模式下,数据被“平等地”复制到所有节点,且所有节点都可以进行读写。任一节点出错时,只需要向其他节点继续请求读写操作即可。不必担心主从复制中主节点出错而带来的(即便是短暂的)失去写数据的能力。但此模式的最大问题还是“写入冲突”(两个节点同时试图更新同一条记录)。

因为RDBMS天然的数据结构,使得其难以横向扩展。因此,RDBMS也就难以支持分布式(分片和复制),而NoSQL对分布式具有天然的支持。

3.动态模式

RDBMS在存入数据之前要先定义好模式,比如你要存储用户的信息,就要先定义好用户表的各个字段名(name,age,sex...),这对于现在网络环境下的敏捷开发来说简直是灾难。因为每次想要在数据中加入新特性时,都意味着要更新表的字段。而NoSQL由于其使用类似JSON的数据结构来存储数据,对动态模式就具体有天然的支持。

4.数据一致性

RDBMS因为是在同一台服务器上进行读写操作,所以只需要通过事务去保证数据的一致性就会做的比较好。在一个事务中,同一条sql查询语句,多次读取,所得数据没有变化(没有受到其他事务的干扰)。而对于分布式下的NoSQL数据库来说就更加复杂一些。

更新一致性:A和B 同时修改不同节点上存储的同一数据。A、B之间会有一人在更新完后查询时发现自己刚刚更新的数据被另外一个人的更新内容替代了。更新一致性可用乐观锁和悲观锁解决。悲观锁是不允许冲突发生,就是加入A和B同时修改同一数据时,只有一个人能获得锁,当这个人修改完后,另一个人根据这个人修改的结果,再去判断自己是否要去修改。然而在高并发下,悲观锁容易引起死锁(即A和B都占有着各自的资源,并同时去请求对方占有的资源),且悲观锁会大幅降低系统响应能力。乐观锁是先让冲突发生,再去解决它。

读取一致性:A和B同时读取不同服务器上的同一数据,而与此同时C修改了它。由于网络延时等原因,A和B读到的内容可能发生不同。

在NoSQL中,为了引入分布式并顾及到效率,不得不放宽一致性约束,只保证最终一致性。最终一致性,即不保证在任意时刻任意节点上的同一份数据都是相同的,但是随着时间的迁移,不同节点上的同一份数据总是在向趋同的方向变化。也可以简单的理解为在一段时间后,节点间的数据会最终达到一致状态。

总结

NoSQL由于其数据存储方式,带来的优势有:可扩展性更好,对分布式的支持更好,对动态模式的支持更好。带来的问题是:不得不降低对数据一致性的要求,由强一致性转为若一致性或最终一致性。

 

参考文章:

《NoSQL精粹》   爱飞翔译

http://zhuanlan.51cto.com/art/201712/561201.htm

http://database.51cto.com/art/201808/582267.htm

https://blog.csdn.net/woshiyeguiren/article/details/80277475

https://www.jianshu.com/p/979ddd330f40

你可能感兴趣的:(数据库,NoSQL,SQL)