NoSQL 还是 SQL ?这一篇讲清楚

2018-03-08 17:15:53 浏览数 (1)

1.NoSQL的诞生原因

随着互联网快速发展,各种类型的应用层出不穷,所以导致在这个云计算的时代,对技术提出了更多的需求,主要体现在下面这四个方面:

  1. 低延迟的读写速度:应用快速地反应能极大地提升用户的满意度; 原因:当数据量达到一定规模时,由于关系型数据库的系统逻辑非常复杂,使得其非常容易发生死锁等的并发问题,所以导致其读写速度下滑非常严重;
  2. 支撑海量的数据和流量:对于搜索这样大型应用而言,需要利用PB级别的数据和能应对百万级的流量; 原因:有限的支撑容量:现有关系型解决方案还无法支撑Google这样海量的数据存储
  3. 大规模集群的管理:系统管理员希望分布式应用能更简单的部署和管理; 原因:由于存在类似Join这样多表查询机制,使得数据库在扩展方面很艰难;
  4. 庞大运营成本的考量:IT经理们希望在硬件成本、软件成本和人力成本能够有大幅度地降低; 原因:企业级数据库的License价格很惊人,并且随着系统的规模,而不断上升;

业界为了解决上面提到的几个需求,推出了多款新类型的数据库,并且由于它们在设计上和传统的NoSQL数据库相比有很大的不同,所以被统称为 “NoSQL”系列数据库。总的来说,在设计上,它们非常关注对数据高并发地读写和对海量数据的存储等,与关系型数据库相比,它们在架构和数据模型方量面 做了“减法”,而在扩展和并发等方面做了“加法”。现在主流的NoSQL数据库有BigTable、HBase、Cassandra、SimpleDB、 CouchDB、MongoDB和Redis等

2.为何要使用NoSQL数据库?

  1. NoSQL具有灵活的数据模型,可以处理非结构化/半结构化的大数据 现在,我们可以通过Facebook、D&B等第三方轻松获得与访问数据,如个人用户信息、地理位置数据、社交图谱、用户产生的内容、机器日志数 据以及传感器生成的数据等。对这些数据的使用正在快速改变着通信、购物、广告、娱乐以及关系管理的特质。没有使用这些数据的应用很快就会被用户所遗忘。开 发者希望使用非常灵活的数据库,能够轻松容纳新的数据类型,并且不会被第三方数据提供商内容结构的变化所累。很多新数据都是非结构化或是半结构化的,因此 开发者还需要能够高效存储这种数据的数据库。但遗憾的是,关系型数据库所使用的定义严格、基于模式的方式是无法快速容纳新的数据类型的,对于非结构化或是 半结构化的数据更是无能为力。NoSQL提供的数据模型则能很好地满足这种需求。很多应用都会从这种非结构化数据模型中获益,比如说CRM、ERP、 BPM等等,他们可以通过这种灵活性存储数据而无需修改表或是创建更多的列。这些数据库也非常适合于创建原型或是快速应用,因为这种灵活性使得新特性的开 发变得非常容易。
  2. NoSQL很容易实现可伸缩性(向上扩展与水平扩展) 如果有很多用户在频繁且并发地使用你的应用,那么你就需要考虑可伸缩的数据库技术而非传统的RDBMS了。对于关系型技术来说,很多应用开发者会发现动态 的可伸缩性是难以实现的,这时就应该考虑切换到NoSQL数据库上。对于云应用来说,关系型数据库一开始是普遍的选择。然而,在使用过程中却遇到了越来越 多的问题,原因就在于他们是中心化的,向上扩展而非水平扩展的。这使得他们不适合于那些需要简单且动态可伸缩性的应用。NoSQL数据库从一开始就是分布 式、水平扩展的,因此非常适合于互联网应用分布式的特性。 在三层互联网架构的Web/应用层上,多年来向上扩展已经成为默认的扩展方式了。随着应用使用人数的激增,我们需要添加更多的服务器,性能则是通过负载均 衡来实现的,这时的代价与用户数量成线性比例关系。在NoSQL数据库之前,数据库层的默认扩展方式就是向上扩展。为了支持更多的并发用户以及存储更多的 数据,你需要越来越好的服务器,更好的CPU、更多的内存、更大的磁盘来维护所有表。然而,好的服务器意味着更加复杂、私有、并且也更加昂贵。这与 Web/应用层所使用的便宜的硬件形成了鲜明的对比。
  3. 动态模式 关系型数据库需要在添加数据前先定义好模式。比如说,你需要存储客户的电话号码、姓名、地址、城市与州等信息,SQL数据库需要提前知晓你要存的是什么。 这对于敏捷开发模式来说是场灾难,因为每次完成新特性时,数据库的模式通常都需要改变。因此,如果在开发过程中想将客户喜欢的条目加到数据库中,那就得向 表中添加这一列才行,然后要做的就是将整个数据库迁移到新的模式上。
  4. 自动分片 由于是结构化的,关系型数据库通常会垂直扩展,单台服务器要持有整个数据库来确保可靠性与数据的持续可用性。这样做的代价就是非常昂贵、扩展受到限制,并 且数据库基础设施会成为失败点。这个问题的解决方案就是水平扩展,添加服务器而不是为单台服务器增加更多的能力。NoSQL数据库通常都支持自动分片,这 意味着他们本质上就会自动在多台服务器上分发数据,应用甚至都不知道这些事情。数据与查询负载会自动在多台服务器上做到平衡,当某台服务器当机时,它能快 速且透明地被替换掉。
  5. 复制 大多数NoSQL数据库也支持自动复制,这意味着你可以获得高可用性与灾备恢复功能。从开发者的角度来看,存储环境本质上是虚拟化的。

3.NoSQL优缺点

在优势方面,主要体现在下面这三点:

  1. 简单的扩展:典型例子是Cassandra,由于其架构是类似于经典的P2P,所以能通过轻松地添加新的节点来扩展这个集群;
  2. 快速的读写:主要例子有Redis,由于其逻辑简单,而且纯内存操作,使得其性能非常出色,单节点每秒可以处理超过10万次读写操作;
  3. 低廉的成本:这是大多数分布式数据库共有的特点,因为主要都是开源软件,没有昂贵的License成本;

但瑕不掩瑜,NoSQL数据库还存在着很多的不足,常见主要有下面这几个:

  1. 不提供对SQL的支持:如果不支持SQL这样的工业标准,将会对用户产生一定的学习和应用迁移成本;
  2. 支持的特性不够丰富:现有产品所提供的功能都比较有限,大多数NoSQL数据库都不支持事务,也不像MS SQL Server和Oracle那样能提供各种附加功能,比如BI和报表等;
  3. 现有产品的不够成熟:大多数产品都还处于初创期,和关系型数据库几十年的完善不可同日而语;

上面NoSQL产品的优缺点都是些比较共通的,在实际情况下,每个产品都会根据自己所遵从的数据模型和CAP理念而有所不同。

4.适合场景

NoSQL数据库正在成为数据库领域的重要力量。如果使用恰当,那么它会带来很多好处。然而,企业应该非常小心并注意到这些数据库的限制与问题。

NoSQL这两年越来越热,尤其是大型互联网公司非常热衷这门技术。根据笔者的经验,并不是任何场景,NoSQL都要优于关系型数据库。下面我们来具体聊聊,什么时候使用NoSQL比较给力:

1) 数据库表schema经常变化 比如在线商城,维护产品的属性经常要增加字段,这就意味着ORMapping层的代码和配置要改,如果该表的数据量过百万,新增字段会带来额外开销(重建索引等)。NoSQL应用在这种场景,可以极大提升DB的可伸缩性,开发人员可以将更多的精力放在业务层。

2)数据库表字段是复杂数据类型

对于复杂数据类型,比如SQL Sever提供了可扩展性的支持,像xml类型的字段。很多用过的同学应该知道,该字段不管是查询还是更改,效率非常一般。主要原因是是DB层对xml字 段很难建高效索引,应用层又要做从字符流到dom的解析转换。NoSQL以json方式存储,提供了原生态的支持,在效率方便远远高于传统关系型数据库。

3)高并发数据库请求

此类应用常见于web2.0的网站,很多应用对于数据一致性要求很低,而关系型数据库的事务以及大表join反而成了”性能杀手”。在高并发情况 下,sql与no-sql的性能对比由于环境和角度不同一直是存在争议的,并不是说在任何场景,no-sql总是会比sql快。有篇article和大家 分享下,http://artur.ejsmont.org/blog/content/insert-performance-comparison-of-nosql-vs-sql-servers

4)海量数据的分布式存储

海量数据的存储如果选用大型商用数据,如Oracle,那么整个解决方案的成本是非常高的,要花很多钱在软硬件上。NoSQL分布式存储,可以部署在廉价的硬件上,是一个性价比非常高的解决方案。Mongo的auto-sharding已经运用到了生产环境。http://www.mongodb.org/display/DOCS/Sharding

并不是说NoSQL可以解决一切问题,像ERP系统、BI系统,在大部分情况还是推荐使用传统关系型数据库。主要的原因是此类系统的业务模型复杂,使用NoSQL将导致系统的维护成本增加。

5.选择SQL还是NoSQL

上面说明了为什么要使用NoSQL。接下来我们看下如何把NoSQL引入到我们的项目中,我们到底要不要把NoSQL引入到项目中。

在过去,我们只需要学习和使用一种数据库技术,就能做几乎所有的数据库应用开发。因为成熟稳定的关系数据库产品并不是很多,而供你选择的免费版本就 更加少了,所以互联网领域基本上都选择了免费的MySQL数据库。在高速发展的WEB2.0时代,我们发现关系数据库在性能、扩展性、数据的快速备份和恢 复、满足需求的易用性上并不总是能很好的满足我们的需要,我们越来越趋向于根据业务场景选择合适的数据库,以及进行多种数据库的融合运用。几年前的一篇文 章《One Size Fits All - An Idea Whose Time Has Come and Gone》就已经阐述了这个观点。

当我们在讨论是否要使用NoSQL的时候,你还需要理解NoSQL也是分很多种类的,在NoSQL百花齐放的今天,NoSQL的正确选择比选择关系数据库还具有挑战性。虽然NoSQL的使用很简单,但是选择却是个麻烦事,这也正是很多人在观望的一个原因。

6.NoSQL的分类

NoSQL仅仅是一个概念,NoSQL数据库根据数据的存储模型和特点分为很多种类。

以上NoSQL数据库类型的划分并不是绝对,只是从存储模型上来进行的大体划分。它们之间没有绝对的分界,也有交差的情况,比如Tokyo Cabinet / Tyrant的Table类型存储,就可以理解为是文档型存储,Berkeley DB XML数据库是基于Berkeley DB之上开发的。

7.选择和使用建议

虽然09年出现了比较激进的文章《关系数据库已死》,但是我们心里都清楚,关系数据库其实还活得好好的,你还不能不用关系数据库。但是也说明了一个事实,关系数据库在处理WEB2.0数据的时候,的确已经出现了瓶颈。

那么我们到底是用NoSQL还是关系数据库呢?我想我们没有必要来进行一个绝对的回答。我们需要根据我们的应用场景来决定我们到底用什么。

如果关系数据库在你的应用场景中,完全能够很好的工作,而你又是非常善于使用和维护关系数据库的,那么我觉得你完全没有必要迁移到NoSQL上面, 除非你是个喜欢折腾的人。如果你是在金融,电信等以数据为王的关键领域,目前使用的是Oracle数据库来提供高可靠性的,除非遇到特别大的瓶颈,不然也 别贸然尝试NoSQL。

然而,在WEB2.0的网站中,关系数据库大部分都出现了瓶颈。在磁盘IO、数据库可扩展上都花费了开发人员相当多的精力来优化,比如做分表分库 (database sharding)、主从复制、异构复制等等,然而,这些工作需要的技术能力越来越高,也越来越具有挑战性。如果你正在经历这些场合,那么我觉得你应该尝 试一下NoSQL了。

一、选择合适的NoSQL 如此多类型的NoSQL,而每种类型的NoSQL又有很多,到底选择什么类型的NoSQL来作为我们的存储呢?这并不是一个很好回答的问题,影响我们选择 的因素有很多,而选择也可能有多种,随着业务场景,需求的变更可能选择又会变化。我们常常需要根据如下情况考虑:

1.数据结构特点。包括结构化、半结构化、字段是否可能变更、是否有大文本字段、数据字段是否可能变化。

2.写入特点。包括insert比例、update比例、是否经常更新数据的某一个小字段、原子更新需求。

3.查询特点。包括查询的条件、查询热点的范围。比如用户信息的查询,可能就是随机的,而新闻的查询就是按照时间,越新的越频繁。

二、NoSQL和关系数据库结合 其实NoSQL数据库仅仅是关系数据库在某些方面(性能,扩展)的一个弥补,单从功能上讲,NoSQL的几乎所有的功能,在关系数据库上都能够满足,所以选择NoSQL的原因并不在功能上。

所以,我们一般会把NoSQL和关系数据库进行结合使用,各取所长,需要使用关系特性的时候我们使用关系数据库,需要使用NoSQL特性的时候我们使用NoSQL数据库,各得其所。

举个简单的例子吧,比如用户评论的存储,评论大概有主键id、评论的对象aid、评论内容content、用户uid等字段。我们能确定的是评论内 容content肯定不会在数据库中用where content=’’查询,评论内容也是一个大文本字段。那么我们可以把 主键id、评论对象aid、用户id存储在数据库,评论内容存储在NoSQL,这样数据库就节省了存储content占用的磁盘空间,从而节省大量IO, 对content也更容易做Cache。

//从MySQL中查询出评论主键id列表 commentIds=DB.query(“SELECT id FROM comments where aid=’评论对象id’ LIMIT 0,20”); //根据主键id列表,从NoSQL取回评论实体数据 CommentsList=NoSQL.get(commentIds);NoSQL代替MySQL 在某些应用场合,比如一些配置的关系键值映射存储、用户名和密码的存储、Session会话存储等等,用NoSQL完全可以替代MySQL存储。不但具有更高的性能,而且开发也更加方便。

三、NoSQL作为缓存服务器 MySQL Memcached的架构中,我们处处都要精心设计我们的缓存,包括过期时间的设计、缓存的实时性设计、缓存内存大小评估、缓存命中率等等。

NoSQL数据库一般都具有非常高的性能,在大多数场景下面,你不必再考虑在代码层为NoSQL构建一层Memcached缓存。NoSQL数据本身在Cache上已经做了相当多的优化工作。

Memcached这类内存缓存服务器缓存的数据大小受限于内存大小,如果用NoSQL来代替Memcached来缓存数据库的话,就可以不再受限于内存大小。虽然可能有少量的磁盘IO读写,可能比Memcached慢一点,但是完全可以用来缓存数据库的查询操作。

0 人点赞