"一言蔽之系列"--简说SQL与NoSQL那些事

454 阅读15分钟
原文链接: www.jianshu.com

一言蔽之,NoSQL ==Not Only SQL ,字面意思是“不仅仅是SQL”,是一类非关系型存储的数据库的统称


文章结构
1、关系型数据库:ACID理论
2、非关型系数据库:分布式存储理论、CAP理论、BASE理论、优缺点、常用NoSQL数据库
3、Python链接Mongodb的演示


1、关系型数据库

伴随着互联网技术的发展,计算机每天都在产生大量的非结构化、半结构化、结构化的数据,这些数据大部分都被关系型数据库系统(RDBMs)来处理,其严谨的数据建模和应用程序编程更加的简单那。

1.1、关系型数据的理论-ACID

ACID

ACID是指数据库管理系统(DBMS)在写入或更新数据的时候,为保证数据的事务(transaction)是正确可靠的,所必须具备的四个特性:

原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability)

  • A – Atomicity – 原子性

一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有被执行过一样。

  • C – Consistency – 一致性

在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。

  • I – Isolation – 隔离性

数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。

  • D – Durability – 持久性

事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

1.2、关系型数据库的小缺点

但是为了满足日益流行的大数据、物联网、云计算等新兴业务的需求,传统的RDBMs在一些业务方面已经无法满足其要去。首先,对数据库的容量需求越来越高,单机无法满足需求,很多时候需要使用集群的技术来解决问题,而传统的关系型数据由于要支持join、union等操作,一般不支持分布式集群。其次,在大数据大行其道的今天,很多数据都“频繁读取/写入,不频繁修改”,而RDBMs对所有操作一视同仁,这就为改进与优化带来了空间。此外,互联网时代业务的不确定性导致数据库存储的模式也需要频繁的改变,不自由的存储模式增大了运维的复杂性与扩展的难度。 关系型数据库严格遵循ACID理论。但当数据库要开始满足横向扩展、高可用、模式自由等需求时,需要对ACID理论进行取舍,不能严格遵循ACID。以CAP理论和BASE理论为基础的NoSQL数据库开始出现。

2、非关系数据库兴起(NoSQL)

NoSQL是一项全新的数据库革命,早期就有人提出,发展至2009年趋势愈发的高涨。这类数据库的特点:

非关系型的、分布式的、开源的、水平可扩展的

最初的目的是为了大规模的web应用。NoSQL的拥护者们提倡运用非关系的数据存储,通常的应用有一下的特点:模式自由、支持简易的复制、简单的API、最终的一致性(非ACID)、大数据容量等特点。

2.1、分布式系统理论

2.1.1 分布式系统介绍
分布式系统的核心理念是让多台服务器协同工作,完成单台服务器无法处理的任务,尤其是高并发或者大数据量的任务。分布式是NoSQL数据库的必要条件。

分布式系统由独立的服务器通过网络松散耦合组成的。每个服务器都是一台独立的PC机,服务器之间通过内部网络连接,内部网络速度一般比较快。因为分布式集群里的服务器是通过内部网络松散耦合,各节点之间的通讯有一定的网络开销,因此分布式系统在设计上尽可能减少节点间通讯。此外,因为网络传输瓶颈,单个节点的性能高低对分布式系统整体性能影响不大。比如,对分布式应用来说,采用不同编程语言开发带来的单个应用服务的性能差异,跟网络开销比起来都可以忽略不计。

因此,分布式系统每个节点一般不采用高性能的服务器,而是使用性能相对一般的普通PC服务器。提升分布式系统的整体性能是通过横向扩展(增加更多的服务器),而不是纵向扩展(提升每个节点的服务器性能)实现。

分布式系统最大的特点是可扩展性,它能够适应需求变化而扩展。企业级应用需求经常随时间而不断变化,这也对企业级应用平台提出了很高的要求。企业级应用平台必须要能适应需求的变化,即具有可扩展性。比如移动互联网2C应用,随着互联网企业的业务规模不断增大,业务变得越来越复杂,并发用户请求越来越多,要处理的数据也越来越多,这个时候企业级应用平台必须能够适应这些变化,支持高并发访问和海量数据处理。分布式系统有良好的可扩展性,可以通过增加服务器数量来增强分布式系统整体的处理能力,以应对企业的业务增长带来的计算需求增加。

2.2、分布式存储的问题 – CAP理论

如果我们期待实现一套严格满足ACID的分布式事务,很可能出现的情况就是系统的可用性和严格一致性发生冲突。在可用性和一致性之间永远无法存在一个两全其美的方案。由于NoSQL的基本需求就是支持分布式存储,严格一致性与可用性需要互相取舍,由此延伸出了CAP理论来定义分布式存储遇到的问题。

CAP理论告诉我们:一个分布式系统不可能同时满足一致性(C:Consistency)、可用性(A:Availability)、分区容错性(P:Partitiontolerance)这三个基本需求,并且最多只能满足其中的两项。

对于一个分布式系统来说,分区容错是基本需求,否则不能称之为分布式系统。因此架构师需要在C和A之间寻求平衡。

CAP
  • C – Consistency – 一致性(与ACID的C完全不同)

一致性是指“all nodes see the same data at the same time”,即更新操作成功并返回客户端完成后,所有节点在同一时间的数据完全一致。

对于一致性,可以分为从客户端和服务端两个不同的视角。

从客户端来看,一致性主要指的是多并发访问时更新过的数据如何获取的问题。

从服务端来看,则是更新如何复制分布到整个系统,以保证数据最终一致。一致性是因为有并发读写才有的问题,因此在理解一致性的问题时,一定要注意结合考虑并发读写的场景。

从客户端角度,多进程并发访问时,更新过的数据在不同进程如何获取的不同策略,决定了不同的一致性。对于关系型数据库,要求更新过的数据能被后续的访问都能看到,这是强一致性。如果能容忍后续的部分或者全部访问不到,则是弱一致性。如果经过一段时间后要求能访问到更新后的数据,则是最终一致性。

  • A – Availability – 可用性

可用性是指“Reads and writes always succeed”,即服务一直可用,而且是正常响应时间。

对于一个可用性的分布式系统,每一个非故障的节点必须对每一个请求作出响应。也就是说,该系统使用的任何算法必须最终终止。当同时要求分区容忍性时,这是一个很强的定义:即使是严重的网络错误,每个请求必须完成。

好的可用性主要是指系统能够很好的为用户服务,不出现用户操作失败或者访问超时等用户体验不好的情况。在通常情况下,可用性与分布式数据冗余、负载均衡等有着很大的关联。

  • P – Partition tolerance – 分区容错性

分区容错性是指“the system continues to operate despite arbitrary message loss or failureof part of the system”,即分布式系统在遇到某节点或网络分区故障的时候,仍然能够对外提供满足一致性和可用性的服务。

分区容错性和扩展性紧密相关。在分布式应用中,可能因为一些分布式的原因导致系统无法正常运转。好的分区容错性要求能够使应用虽然是一个分布式系统,但看上去却好像是一个可以运转正常的整体。比如现在的分布式系统中有某一个或者几个机器宕掉了,其它剩下的机器还能够正常运转满足系统需求,或者是机器之间有网络异常,将分布式系统分隔成未独立的几个部分,各个部分还能维持分布式系统的运作,这样就具有好的分区容错性。

  • CA without P

如果不要求P(不允许分区),则C(强一致性)和A(可用性)是可以保证的。但其实分区不是你想不想的问题,而是始终会存在,因此CA的系统更多的是允许分区后各子系统依然保持CA。

  • CP without A

如果不要求A(可用),相当于每个请求都需要在Server之间强一致,而P(分区)会导致同步时间无限延长,如此CP也是可以保证的。很多传统的数据库分布式事务都属于这种模式。

  • AP without C

要高可用并允许分区,则需放弃一致性。一旦分区发生,节点之间可能会失去联系,为了高可用,每个节点只能用本地数据提供服务,而这样会导致全局数据的不一致性。现在众多的NoSQL都属于此类。

CAP理论定义了分布式存储的根本问题,但并没有指出一致性和可用性之间到底应该如何权衡。于是出现了BASE理论,给出了权衡A与C的一种可行方案。


2.3、 权衡一致性与可用性 - BASE理论**

**Base = Basically Available + Soft state + Eventuallyconsistent **基本可用性+软状态+最终一致性,由eBay架构师DanPritchett提出。Base是对CAP中一致性A和可用性C权衡的结果,源于提出者自己在大规模分布式系统上实践的总结。核心思想是无法做到强一致性,但每个应用都可以根据自身的特点,采用适当方式达到最终一致性。

  • BA - Basically Available - 基本可用

基本可用。这里是指分布式系统在出现故障的时候,允许损失部分可用性,即保证核心功能或者当前最重要功能可用。对于用户来说,他们当前最关注的功能或者最常用的功能的可用性将会获得保证,但是其他功能会被削弱。

  • S – Soft State - 软状态

允许系统数据存在中间状态,但不会影响到系统的整体可用性,即允许系统在不同节点的数据副本之间进行数据同步时存在延时。

  • E - Eventually Consistent - 最终一致性

要求系统数据副本最终能够一致,而不需要实时保证数据副本一致。最终一致性是弱一致性的一种特殊情况。最终一致性有5个变种:

  • 因果一致性
  • 读己之所写(因果一致性特例)
  • 会话一致性
  • 单调读一致性
  • 单调写一致性
主流NoSQL数据库介绍及其适用场景

2.4、几种常见的NoSQL数据库

1. Redis

1.1 介绍

Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。

1.2 适用场景

  • 数据变化较少,执行预定义查询,进行数据统计的应用程序

  • 需要提供数据版本支持的应用程序

    例如:股票价格、数据分析、实时数据搜集、实时通讯、分布式缓存

2. MongoDB

2.1 介绍

MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。

MongoDB 是一个介于关系型数据库和非关系型数据库之间的产品,是非关系型数据库当中功能最丰富,最像关系型数据库的非关系型数据库。

2.2 适用场景

  • 需要动态查询支持
  • 需要使用索引而不是 map/reduce功能
  • 需要对大数据库有性能要求
  • 需要使用 CouchDB但因为数据改变太频繁而占满内存
3.Neo4j

3.1 介绍 Neo4j是一个高性能的NoSQL图形数据库,它将结构化数据存储在网络上而不是表中。它是一个嵌入式的、基于磁盘的、具备完全的事务特性的Java持久化引擎,但是它将结构化数据存储在网络(从数学角度叫做图)上而不是表中。Neo4j也可以被看作是一个高性能的图引擎,该引擎具有成熟数据库的所有特性。

3.2 适用场景

  • 适用于图形一类数据
  • 这是 Neo4j与其他NoSQL数据库的最显著区别
  • 例如:社会关系,公共交通网络,地图及网络拓谱
4.Cassandra

4.1 介绍

Apache Cassandra 是一套开源分布式 Key-Value 存储系统。它最初由 Facebook 开发,用于储存特别大的数据。 Cassandra 不是一个数据库,它是一个混合型的非关系的数据库,类似于Google 的 BigTable。Cassandra 的数据模型是基于列族(Column Family)的四维或五维模型。

4.2适用场景

  • 银行业,金融业
  • 写比读更快
5. HBase

5.1 介绍

HBase是一个分布式的、面向列的开源数据库,该技术来源于Google论文“Bigtable:一个结构化数据的分布式存储系统”。就像Bigtable利用了Google文件系统(File System)所提供的分布式数据存储一样,HBase在Hadoop之上提供了类似于Bigtable的能力。它是一个适合于非结构化数据存储的数据库。另一个不同的是HBase基于列的而不是基于行的模式。

5.2适用场景

  • 对大数据进行随机、实时访问的场合

例如: Facebook消息数据库

3、Python链接Mongodb数据库示例

作为程序猿只玩理论那才是蛋疼,老老实实码代码才是我们的最爱,文末来上一段怎么使用python链接数据库的代码作为结尾吧。

怎么安装mongodb就不用我说了吧。。。

MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。
在高负载的情况下,添加更多的节点,可以保证服务器性能。
MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。

记录格式
# coding:utf-8
# 导入链接mongodb的第三方包,没安装的用:sudo pip install pymongo 安装
import pymongo
# 保存到mongodb数据库
def connMongodb(item):
    # 本机数据库地址
    mongo_url = 'localhost:27017'
    # 你的数据库名称
    mongo_db='ceshi'
    # 存储到哪一个表,非关系数据库里叫集合
    collection='ZhiHuText'
    con=pymongo.MongoClient(mongo_url)
    db=con[mongo_db]
    # 插入记录到数据库
    db[collection].insert(dict(item))

if __name__ == '__main__':
    # 插入一条记录
    item={'title':'简书','content':'哎吆,不错哦'}
    connMongodb(item)


总感觉有可执行代码的文章才是干货,给出一小段Demo完美啦(๑ᴖᴖ๑)!

您获得新的升级包