5.1 NoSQL简介
NoSQL = not only sql,具有以下特点
1. 灵活的可扩展性
可以很简单的进行横向扩展(加机器),相比较而言传统关系型数据库基本不能横向扩展,只能纵向扩展
2. 灵活的数据模型
传统型数据库有严格的数据模型,NoSQL则很灵活,甚至说没什么数据模型可言。
3. 与云计算紧密结合
云计算的一大特点就是计算和存储资源的自由伸缩,与NoSQL良好的横向扩展能力结合,便可以构建基于NoSQL的云数据库服务。
5.2 NoSQL兴起的原因
5.2.1 关系型数据库无法满足Web2.0的需求
1. 无法满足海量数据的管理需求:购物、社交、搜索等网络行为会产生海量的数据,传统关系型数据库无法对其有效管理。
2. 无法满足数据高并发的需求:Web1.0采用的动态网页静态化技术无法满足海量用户高并发的访问请求
3. 无法满足高扩展性和高可用性的需求:Web2.0时代,网站随时爆火,数据库读写负载随时有可能爆发,关系型数据库无法短时间内提高性能。
传统关系型数据库特点描述:① 完备的数学理论基础、完善的事务管理机制、从而也有高效的复杂查询处理引擎,② 适用于银行、电商等各类商业公司的业务数据管理需求,③ 当数据量逐渐增大时,通过主从服务器、分库、分表等方法解决,这些方法耗时、易出错、难以自动化。
5.2.2 关系型数据库的关键特性在Web2.0时代成为“鸡肋”
对于数据库的数据模型而言,主要有两大类业务场景,一是数据分析、一是在线业务。前者强调高吞吐量,后者强调低延时。而同一种数据模型不可能同时在两点上都优秀,但是传统的数据库的“One size fits all”思想正是在努力用同一套设计同时满足上述两点,因此愈发力不从心。新兴的NoSQL数据库层出不穷,但每一个往往侧重其中一点,比如Hadoop就是针对数据分析,而MongoDB、Redis等则是针对在线业务。
关系型数据库的以下几大优点愈发不重要
1)严格的数据库事务:对于银行系统而言,如果进行转账时数据库出错,一方的钱扣掉了,另一方却没有收到,这是很严重的事情,需要进行一些复杂的回滚操作。但如果用户发微博时,点了发送却没发送出去,这个事情就没多大所谓,顶多告诉他一声“发送失败”即可。即:Web2.0时代,这种用户数据不太需要严格的数据库事务管理。
2)严格的读写实时性:以银行存钱为例,如果已经存进去了一笔钱,数据库也写入了,然后接着再去ATM机取钱,结果显示“余额不足”,这就叫读写非实时,肯定也不行,因此传统数据库着力解决读写实时性问题。但是如果A在微博上关注了B,但是B没有实时看到“有个新粉丝”这种信息,甚至延迟个半小时,B也不会觉得怎么样。
3)高效复杂的SQL查询引擎:1.0时代,受限于高昂的存储价格等原因,传统数据库设计了很多范式,去避免冗余,也因此一家公司不同的事务对应着很多表,而查询时可能对很多表进行连接,而为了优化多表连接的复杂查询工作,传统数据库设计了强有力的查询引擎。但是,2.0时代,机器变便宜了很多,冗余不再是问题,很多NoSQL数据库设计之初就只整了个主键查询什么的,同一个信息这个表里有那个表里也有,这也无所谓。最终导致了传统数据库的查询优化机制难以有所作为。
5.3 NoSQL与传统关系型数据库的详细对比
1. 关系型数据库
优势:① 完备的理论原理基础,② 严格的事务机制下数据的强一致性、高完整性,③ 成熟的索引机制、高效的查询,④ 成熟的市场技术支持、标准化的技术。
劣势:① 较差的横向扩展性、受限的数据规模,② 严格一致性一定程度影响可用性。
其它特点:① 严格的数据模式。
2. NoSQL数据库
优势:① 强大的横向扩展能力,带来了超大规模数据存储能力,② 灵活的数据模式适用于Web2.0场景,非常高的可用性。
劣势:① 不成熟的理论、不成熟的技术、未标准化、不充分的技术支持,② 低效的复杂查询,③ 不能强一致性、很难数据完整性、不成熟的技术支持等。
3. 结论
两者各有优势、各有缺陷,有着不同的适用场景,因此有各自的目标用户群体和市场空间。
关系型数据库适用于严格的、要求数据强一致性的场景,如银行、超市、电商的业务系统等。
NoSQL适用于大数据量、并发高的场景,如:互联网公司,Web2.0网站、传统企业的非核心业务系统等。
5.4 NoSQL的四大类型
5.4.1 键值数据库
数据模型:一个个的k-v对,其中k是字符串,v可以是任意格式,包括整型、字符型、数组、对象等。
优势:大量写操作时非常高效
劣势:条件查询、关联查询
典型应用:内容缓存,如会话、配置文件、参数、购物车等
代表产品:Redis
5.4.2 列族数据库 略
5.4.3 文档数据库
数据模式:可以算是键值数据库的一种,不过值是文档格式,且通常假定是以某种标准格式封装存储的,如json、xml等。
优势:文档可以包含复杂的数据结构,如嵌套对象,且不需要外部引用,属于自包含。
劣势:没有统一的查询语法。
典型应用:存储、索引、管理面向文档的数据或者类似的半结构化数据
代表产品:MongoDB
5.4.4 图数据库
代表产品:Neo4j
其它略
5.5 NoSQL的三大基石
5.5.1 CAP理论
1. CAP概念
C:一致性(Consistency),指任何一个读操作总是能读取到之前完成的写操作结果,对于分布式环境而言即多点的数据是一致的。
A:可用性(Availability),指快速获取数据,对于读请求可以在确定的时间内返回结果
P:分区容忍性,即如果数据库存在网络分区的情况,若部分分区失效、失联、丢失信息等,不会影响系统的运行。
2. CAP理论
一个数据库设计,最多只能满足CAP中的其中两点。
1)选择CA,则必须放弃P,为了保证C和A,则不能对数据库进行网络分区的存储,传统数据库如MySQL等均采用了该原则。
2)选择CP,则放弃A,若存在网络分区,又要保证数据一致性,则每次写操作完成后必须等所有受影响的数据一致,然后才可以对外服务。Neo4j、BigTable、HBase等均采用了CP原则。可以说,CP原则适用于数据规模大、同时也带有点事务性质的数据。
3)选择AP,则放弃C,数据分区存储,又高可用,则同一时间的读操作返回的数据可能不一致(不同的数据节点还未同步)。适用于Web2.0网站的内容存储,如微博等,一个用户发了一条新微博,他的粉丝们就算同时刷新了微博,有的看到了有的没看到这也没什么。最终一致就可以了。
5.5.2 BASE
1. BA:Basically Avaible 基本可用
允许分区失败。一个分布式系统的一部分发生问题,其它部分仍可以正常运行。如10个节点中坏掉1个节点,那么其余9个节点仍然可以正常提供数据访问。只是此时暂时的有约10%的数据不可用。
2. S:Soft state 软状态
软状态,即数据暂时性地不一致。在写操作进行后,后续的读操作会暂时性地读不到最新地数据。
3. E:Eventual consistency 最终一致性
后续的读操作暂时性地读不到最新的数据,但最终能读到更新后的数据。即数据最终还是保持了一致。
5.5.3 最终一致性的进一步阐述
1. 两个角度理解
客户端角度:在高并发的访问操作下,后续访问尽可能快的获取到最新的数据。
服务端角度:尽快把数据更新传送到各个节点,保证数据的一致性。
2. 分类
1)因果一致性:A进程写完后通知B进程,则B进程能立刻读取到最新值,但其它进程可能只能待最终一致完成后才读到最新值。
2)读己之所写一致性:A进程自己执行了写操作,则它总能访问到更新后的值,而不会访问到旧值。
3)单调读一致性:如果任意一个进程已经看到某个对象的某个值,则任何后续访问都不会读到那个值之前的值。
4)会话一致性:
5)单调写一致性:同一个进程的多个写操作必须是顺序执行的。
3. 如何实现
对于分布式系统而言,设N是数据复制的份数,W是更新数据要求保证完成的节点数,R是读取数据要求读取的节点数。
W+R>N:强一致性。若N=2,W=2,其实就是把所有副本都写好才算完成写操作,此时R=1,也能读到最新数据。W+R=N+1是保证强一致性的最小设定。
W+R<=N:弱一致性。设N=2,W=1,R=1。数据复制两份,写操作完成任何一个则算完成,R=1即读到任何一个节点就算读取到。
4. N、W、R的设置
1)N=W,R=1:把所有的副本都更新才算写操作完成,保证了强一致性,可用性降低。HDFS是保证强一致性的。
2)其它设置,略。
5.6 NewSQL
传统数据库适用于严格事务场景,NoSQL适用于Web2.0场景,而NewSQL结合两者的优点,适用于分析类场景。
暂略
5.7 文档数据库MongoDB简介
1. 概述
1) 是NoSQL中最像关系型数据库的产品。
2)C++编写,基于分布式文件系统的开源数据库系统。
3)数据存储为文档,数据结构由键值对构成,类似于json对象。字段值也可能包括数组、字符串等。
2. 优势
1)操作简单
2)高效:针对任何属性的索引进行快速排序
3)较好的水平扩展性
4)丰富的查询表达式,可查询文档内嵌的对象、数组等
5)支持MapReduce
6)支持java、python等多种语言
3. 举个栗子
一篇博客的存储(包括内容、评论、评论投票等)
在传统数据库中,这些会被打散到多个表中。专门的文章表存储内容,文章ID作为主键;专门的评论表存储评论,评论id作为主键;专门的投票记录表存储投票的情况。这些表互相关联才能提取出一个文章的全部信息。
而在MongoDB中,则是存储为一个大的文档(就是一个大json串),不同的本部分用内部的键值对进行记录就可以了。
4. 其它特点
一个MongoDB可以有多个db,每个db可以有多个表(mongo称之为集合)。每个表中的一个row是一条文档记录,每个文档可以有不同的结构,键所对应的值可以有不同的类型等。