大数据技术核心之Nosql(一):
提纲:
数据采集:ETL
数据存储:关系型数据库、Nosql(Not Only sql)、sql等
数据分析与挖掘:(计算结果展现)数据的可视化
起源:
也许在企业界中早已习惯传统的关系型数据库,但随着待处理的数据逐渐增多,集群数据的不断增多。传统数据库已经不能满足更加迥异的数据格式了。于是大家开始不断探索,期待着一种在集群环境中易于编程且执行效率高的大数据处理技术,在此情况下,Nosql应运而生。
为什么,传统关系型数据库开始遇到瓶颈,哪些瓶颈?为什么数据增多,会伴随着非结构性数据的的增多?什么是非结构性数据?Nosql是什么?支持Nosql数据的数据库有哪些?Nosql数据库与关系型数据库的区别?Nosql挑战是什么?为何它会引起关注?什么样的人更应该关注Nosql?等等。
可能这就是一个新事物的诞生必将引起,好事者的一致追捧,提出各种你能想象的问题,想尽一切办法推促它前进。也可能在这个圈子中,总会有一批不知疲倦的人们在不断的探索,不断的寻求改变世界的方案,这也是这批人的引起为豪的乐趣。
Nosql发展如此迅速的原因:由于需要处理的数据越来越多,所以大型系统的扩展方式,由原来在单一计算机上的纵向扩展(scale up),转变为在计算机集群上的横向扩展(scale out)。这也应征了许多Nosql数据库的数据模型所具备的一个重要特征,那就是:可以把内容密切相关的数据组织成一种丰富的结构,并将其显示存储起来,以便作为一个单元(unit)来访问。这种结构,我们暂且称之为聚合(aggregate)。
关系与非关系型数据库对比:
关系型数据库
特征:
1、 持久化数据:能够持久化存储大量数据。这就存在“主存储器=内存”,“后备存储器=硬盘”。而硬盘就可以做持久化数据使用。
2、 并发:并非操作获取数据库中的数据极为困难。而通过“事务”(加“事务错误”)处理机制可以保证数据不受破坏,解决并发问题。
3、 集成:共享数据集成,将多个应用程序的数据保存在同一个数据库中。有利于团队合作开发。同时可以应对多个应用程序的并发机制。
4、 标准模型:这体现在数据库的标准化,有益于开发人员和数据库专家可以学习基本的关系模型,就可以运用到不同的项目中。虽不同的数据库之间存在差异,但核心机制是相同的,sql、“事务”操作方式也几乎一样。
弊端:
1、阻抗失谐:令开发者失望的是关系型数据库中的关系模型和内存中的数据结构之间存在差异,这种差异通常称为“阻抗失谐”。关系模型把数据组织成“表”(table)和“行”(row),(你可以理解成“表”、“行”太规范了),更准确的说,更应该是“关系”(relation)和“元组”(tuole)。而在关系模型中,元组是由“键值对”(key-value pair)构成的集合,而关系则是元组的集合。(如果大家稍微了解Nosql(暂且把Nosql定义为非关系型数据库)是基于key-value,上面的话就不难理解了)
2、集群:不能在集群中运行。随着互联网公司规模急剧增加。如何解决存储问题?这就引入纵向和横向扩展的问题。纵向:需要更强大的计算机。横向:就是采用多个小型计算机组成的集群。毋庸置疑的选择,减低成本又能提高性能。这就遇到问题了:关系型数据库并不是设计集群用的,它们需要一种可以支持集群的文件系统,该文件系统可将数据写入随时可用的磁盘子系统中。
关系型数据库也可以把数据划分为几个集合,并将其分配放在各自独立的服务器上运行,于是就能有效地对数据库分片。这么做虽然能将负载分到多个服务器之中,但是应用程序必须控制所有分片,它要知道数据库中的每份数据放在哪个服务器上才行。而且必须要考虑数据完整性等性质。如此一说,只能说这是“非常之法”,迫不得已之法了。
非关系型数据库(Nosql):
1、 Nosql数据库不使用或不怎么使用sql。不能说是优点还是缺点,问题在于,绝大多数人都是习惯了使用sql,突然不使用,这不是逼着人去改吗?你知道,它们很懒的。这就衍生出一些支持类sql插件的诞生,不要小看,这里面足够让你大吃一惊(稍后介绍)。
2、 开源(很关键)
3、 抛弃了关系模型
4、 能在集群中运行
5、“无模式”数据,即不用事先修改结构定义,也可以自由添加字段。
6、 Not Only sql。“不只是sql”,这中思维方式不仅仅把Nosql当做一项技术,而视为一场变革。
弊端:
1、 鉴于Nosql技术尚未成熟(最近诞生的如:Cassandra、MongoDB、Neo4J和Riak等),所以大部分企业级应用程序开发者目前还应以现有关系型数据库为主,但在前瞻性很强的项目中,可以选用先试先行。
2、 没有规范的定义,每种Nosql解决方案的模型(如:“键值”、“文档”、“列族”、“图”)都不同,导致不同版本的Nosql操作语句之间兼容性的差异。
两个概念:
1、数据模型:是认知和操作数据时所用的模型。数据模型描述了我们如何同数据库中的数据打交道。我们更关注数据模型。
2、存储模型:描述数据库内部存储及操作数据的机制。一般不涉及。
聚合数据模型:
聚合
关系模型把待存储的信息分割成元组(行,熟知数据库操作的人都知道:关系型数据库是对行操作的。意思是:读写都是按行操作)元组是种受限数据结构:它只能包含一系列的值,因此不能在元组中嵌套另一元组,也不能包含由值或元组所组成的列表。致使所有操作都必须以元组为目标,而且返回值也必须是元组。
面向聚合使用的方式与之不同,我们通常操作数据时所用的单元,其结构都比元组数据复杂的多。如果能以这种复杂的结构存放列表或嵌套其他记录结构,就解决了上面的问题,后面,“键值数据库”、“文档数据库”、“列族数据库”都使用的是这种更复杂的记录。基于这种复杂的记录简称“聚合”。
为了更明白的阐述什么是“聚合”,我们给出一个示例:
假设一个电子商务网站的用户记录,必须存储用户信息、商品目录、订单、收货地址、账单地址和付款方式等信息。这个应用场景,既可以用关系型数据模型建模,也可以用Nosql数据模型建模,我们来比较两者的优劣。
采用关系型模型建模:(简单示例)
1、 保证各张表格间不会出现重复数据。
2、 维护表格间的“完整性”
图面向关系型数据库的数据模型
图 范例数据
采用聚合模型建模:
图 聚合数据模型 黑色菱形代表各数据在聚合结构中的关系
范例数据,采用JSON格式来表示,因为它是Nosql领域中常用的数据格式
- //incustomers
- {
- "id":1,
- "name':"Martin",
- "billingAddress":[{"city":"Chicago"}]
- }
- //inorders
- {
- "id":99,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> "customerId": "orderItems":[
- "productId":27,108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> "price":32.45,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> "productName":"NosqlDistilled"
- }
- ],
- "shippingAddress":[{"city":"Chicago"}]
- "orderPayment":[
- "ccinfo":"1000-1000-1000"
- "txnId":"abelif879rft",108); list-style:decimal-leading-zero outside; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> "billingAdress":{"city":"Chicago"}
- }
这个模型有两个主要聚合:客户(Customer)和订单(Order)。客户数据包含一个账单地址(billing address)列表,订单数据包含订单项(order item)列表,收货地址(shipping address)和付款信息(payment),而付款信息有又含它所对应的账单地址。
同一逻辑地址(账单地址和收货地址所共用的“Chicago”)在示例数据中出现了三次,但是此处我们不用ID来指代,而是直接复制这个地址字符串。如果收货地址和账单地址都不会改变,这么做就很合适。在关系型数据库中,这种情况意味着Address表中的ID=77的那行数据保持不变。若要改变某个地址,需要在该表中创建新行。使用聚合模型后,我们就可以把整个地址结构复制到所有的聚合模型中。(?)
考虑到上述模型与关系型数据库要做权衡一样,这里我么也可以采用非常规的模式,将产品名称直接写入订单项。这种做法在聚合模型中很常见,我们希望在数据交互时尽量减少所需访问的聚合个数。实际上,我么也可以采用另一种方式,把客户下的全部订单放到客户聚合中。