非关系型数据库(NoSql)

正文html

最近了解了一点非关系型数据库,刚刚接触,以为这是一个很好的方向,对于大数据 方面的处理,非关系型数据库能起到相当重要的地位。这里我主要是整理了一些前辈的经验,仅供参考。node

关系型数据库的特色

  1.关系型数据库 

关系型数据库,是指采用了关系模型来组织数据的数据库。 简单来讲,关系模型指的就是二维表格模型,而一个关系型数据库就是由二维表及其之间的联系所组成的一个数据组织。常见 的关系型数据库有Oracle、Mysql、sql server等等。

2. 关系型数据库瓶颈 
高并发读写需求 
网站的用户并发性很是高,每每达到每秒上万次读写请求,对于传统关系型数据库来讲,硬盘I/O是一个很大的瓶颈 
海量数据的高效率读写 网站天天产生的数据量是巨大的,对于关系型数据库来讲,在一张包含海量数据的表中查询,效率是很是低的 
高扩展性和可用性 
在基于web的结构当中,数据库是最难进行横向扩展的,当一个应用系统的用户量和访问量与日俱增的时候,数据库却没有办法像web server和app server那样简单的经过添加更多的硬件和服务节点来扩展性能和负载能力。对于不少须要提供24小时不间断服务的网站来讲,对数据库系统进行升级和扩展是很是痛苦的事情,每每须要停机维护和数据迁移。  
对网站来讲,关系型数据库的不少特性再也不须要了: 
事务一致性 
关系型数据库在对事物一致性的维护中有很大的开销,而如今不少web2.0系统对事物的读写一致性都不高 
读写实时性 
对关系数据库来讲,插入一条数据以后马上查询,是确定能够读出这条数据的,可是对于不少web应用来讲,并不要求这么高的实时性,好比发一条消息以后,过几秒乃至十几秒以后才看到这条动态是彻底能够接受的 
复杂SQL,特别是多表关联查询 
任何大数据量的web系统,都很是忌讳多个大表的关联查询,以及复杂的数据分析类型的复杂SQL报表查询,特别是SNS类型的网站,从需求以及产品阶级角度,就避免了这种状况的产生。每每更多的只是单表的主键查询,以及单表的简单条件分页查询,SQL的功能极大的弱化了  
在关系型数据库中,致使性能欠佳的最主要缘由是多表的关联查询,以及复杂的数据分析类型的复杂SQL报表查询。为了保证数据库的ACID特性,咱们必须尽可能按照其要求的范式进行设计,关系型数据库中的表都是存储一个格式化的数据结构。每一个元组字段的组成都是同样,即便不是每一个元组都须要全部的字段,但数据库会为每一个元组分配全部的字段,这样的结构能够便于标语表之间进行连接等操做,但从另外一个角度来讲它也是关系型数据库性能瓶颈的一个因素。 

非关系型数据库(NoSQL )

2009年初,Johan Oskarsson举办了一场关于开源分布式数据库的讨论,Eric Evans在此次讨论中提出了NoSQL一词,用于指代那些非关系型的,分布式的,且通常不保证遵循ACID原则的数据存储系统。Eric Evans使用NoSQL这个词,并非由于字面上的“没有SQL”的意思,他只是以为不少经典的关系型数据库名字都叫“**SQL”,因此为了表示跟这些关系型数据库在定位上的大相径庭,就是用了“NoSQL“一词。 
注:数据库事务必须具有ACID特性,ACID是Atomic原子性,Consistency一致性,Isolation
 var script = document.createElement('script'); script.src = 'http://static.pay.baidu.com/resource/baichuan/ns.js'; document.body.appendChild(script);
隔离性,Durability持久性。  
非关系型数据库提出另外一种理念,例如,以键值对存储,且结构不固定,每个元组能够有不同的字段,每一个元组能够根据须要增长一些本身的键值对,这样就不会局限于固定的结构,能够减小一些时间和空间的开销。使用这种方式,用户能够根据须要去添加本身须要的字段,这样,为了获取用户的不一样信息,不须要像关系型数据库中,要对多表进行关联查询。仅须要根据id取出相应的value就能够完成查询。但非关系型数据库因为不多的约束,他也不可以提供像SQL所提供的where这种对于字段属性值状况的查询。而且难以体现设计的完整性。他只适合存储一些较为简单的数据,对于须要进行较复杂查询的数据,SQL数据库显的更为合适。 
关系型数据库与非关系型数据库的区别 
关系型数据库的最大特色就是事务的一致性:传统的关系型数据库读写操做都是事务的,具备ACID的特色,这个特性使得关系型数据库能够用于几乎全部对一致性有要求的系统中,如典型的银行系统。 
可是,在网页应用中,尤为是SNS应用中,一致性却不是显得那么重要,用户A看到的内容和用户B看到同一用户C内容更新不一致是能够容忍的,或者说,两我的看到同一好友的数据更新的时间差那么几秒是能够容忍的,所以,关系型数据库的最大特色在这里已经无用武之地,起码不是那么重要了。 相反地,关系型数据库为了维护一致性所付出的巨大代价就是其读写性能比较差,而像微博、facebook这类SNS的应用,对并发读写能力要求极高,关系型数据库已经没法应付(在读方面,传统上为了克服关系型数据库缺陷,提升性能,都是增长一级memcache来静态化网页,而在SNS中,变化太快,memchache已经无能为力了),所以,必须用新的一种数据结构存储来代替关系数据库。 
关系数据库的另外一个特色就是其具备固定的表结构,所以,其扩展性极差,而在SNS中,系统的升级,功能的增长,每每意味着数据结构巨大变更,这一点关系型数据库也难以应付,须要新的结构化数据存储。 
因而,非关系型数据库应运而生,因为不可能用一种数据结构化存储应付全部的新的需求,所以,非关系型数据库严格上不是一种数据库,应该是一种数据结构化存储方法的集合。 必须强调的是,数据的持久存储,尤为是海量数据的持久存储,仍是须要一种关系数据库。 
非关系型数据库简介 
SQLite 
1. ACID事务 
2. 零配置 – 无需安装和管理配置 
3. 储存在单一磁盘文件中的一个完整的数据库 
4. 数据库文件能够在不一样字节顺序的机器间自由的共享
 5. 支持数据库大小至2TB 
6. 足够小, 大体3万行C代码, 250K 
7. 比一些流行的数据库在大部分普通数据库操做要快8. 简单, 轻松的API 
9. 包含TCL绑定, 同时经过Wrapper支持其余语言的绑定10. 良好注释的源代码, 而且有着90%以上的测试覆盖率 11. 独立: 没有额外依赖 
12. Source彻底的Open, 你能够用于任何用途, 包括出售它 13. 支持多种开发语言,C, PHP, Perl, Java, ASP .NET,Python

下面介绍下key相关的命令 
exits key 测试指定key是否存在,返回1表示存在,0不存在 
del key1 key2 ....keyN  删除给定key,返回删除key的数目,0表示给定key都不存在 
type key 返回给定key的value类型。返回 none 表示不存在key,string字符类型,list 链表类型 set 无序集合类型... 
keys pattern 返回匹配指定模式的全部key,下面给个例子 redis> set test dsf OK 
redis> set tast dsaf OK 
redis> set tist adff OK 
redis> keys t* 1. "tist" 2. "tast" 3. "test" 
redis> keys t[ia]st 1. "tist" 2. "tast" 
redis> keys t?st 1. "tist" 2. "tast" 3. "test"  
randomkey 返回从当前数据库中随机选择的一个key,若是当前数据库是空的,返回空串  rename oldkey newkey 原子的重命名一个key,若是newkey存在,将会被覆盖,返回1表示成功,0失败。多是oldkey不存在或者和newkey相同 
renamenx oldkey newkey 同上,可是若是newkey存在返回失败 dbsize 返回当前数据库的key数量 
expire key seconds 为key指定过时时间,单位是秒。返回1成功,0表示key已经设置过过时时间或者不存在 
ttl key 返回设置过过时时间的key的剩余过时秒数 -1表示key不存在或者没有设置过过时时间 
select db-index 经过索引选择数据库,默认链接的数据库全部是0,默认数据库数是16个。返回1表示成功,0失败 
move key db-index  将key从当前数据库移动到指定数据库。返回1成功。0 若是key不存在,或者已经在指定数据库中 
flushdb 删除当前数据库中全部key,此方法不会失败。慎用 
flushall 删除全部数据库中的全部key,此方法不会失败。更加慎用  
2. string 类型 
string是redis最基本的类型,并且string类型是二进制安全的。意思是redis的string能够包含任何数据。好比jpg图片或者序列化的对象 

 

随着互联网web2.0网站的兴起,非关系型的数据库如今成了一个极其热门的新领域, 非关系数据库产品的发展很是迅速。而传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不 从心,暴露了不少难以克服的问题,例如:

一、High performance – 对数据库高并发读写的需求 
web2.0网站要根据用户个性化信息来实时生成动态页面和提供动态信息,因此基本上没法使用动态页面静态化技术,所以数据库并发负载很是高,每每要达到 每秒上万次读写请求。关系数据库应付上万次SQL查询还勉强顶得住,可是应付上万次SQL写数据请求,硬盘IO就已经没法承受了。其实对于普通的BBS网 站,每每也存在对高并发写请求的需求,例如像JavaEye网站的实时统计在线用户状态,记录热门帖子的点击次数,投票计数等,所以这是一个至关广泛的需 求。mysql

二、Huge Storage – 对海量数据的高效率存储和访问的需求 
相似Facebook,twitter,Friendfeed这样的SNS网站,天天用户产生海量的用户动态,以Friendfeed为例,一个月就达到 了2.5亿条用户动态,对于关系数据库来讲,在一张2.5亿条记录的表里面进行SQL查询,效率是极其低下乃至不可忍受的。再例如大型web网站的用户登 录系统,例如腾讯,盛大,动辄数以亿计的账号,关系数据库也很难应付。git

三、High Scalability && High Availability- 对数据库的高可扩展性和高可用性的需求 
在基于web的架构当中,数据库是最难进行横向扩展的,当一个应用系统的用户量和访问量与日俱增的时候,你的数据库却没有办法像web server和app server那样简单的经过添加更多的硬件和服务节点来扩展性能和负载能力。对于不少须要提供24小时不间断服务的网站来讲,对数据库系统进行升级和扩展 是很是痛苦的事情,每每须要停机维护和数据迁移,为何数据库不能经过不断的添加服务器节点来实现扩展呢?github

在上面提到的“三高”需求面前,关系数据库遇到了难以克服的障碍,而对于web2.0网站来讲,关系数据库的不少主要特性却每每无用武之地,例如:web

一、数据库事务一致性需求 
不少web实时系统并不要求严格的数据库事务,对读一致性的要求很低,有些场合对写一致性要求也不高。所以数据库事务管理成了数据库高负载下一个沉重的负 担。redis

二、数据库的写实时性和读实时性需求 
对关系数据库来讲,插入一条数据以后马上查询,是确定能够读出来这条数据的,可是对于不少web应用来讲,并不要求这么高的实时性,比方说发一条消息之 后,过几秒乃至十几秒以后,个人订阅者才看到这条动态是彻底能够接受的。sql

三、对复杂的SQL查询,特别是多表关联查询的需求 
任何大数据量的web系统,都很是忌讳多个大表的关联查询,以及复杂的数据分析类型的复杂SQL报表查询,特别是SNS类型的网站,从需求以及产品设计角 度,就避免了这种状况的产生。每每更多的只是单表的主键查询,以及单表的简单条件分页查询,SQL的功能被极大的弱化了。数据库

所以,关系数据库在这些愈来愈多的应用场景下显得不那么合适了,为了解决这类问题的非关系数据库应运而生,如今这两年,各类各样非关系数据库,特别是键值 数据库(Key-Value Store DB)风起云涌,多得让人眼花缭乱。前不久国外刚刚举办了NoSQL Conference,各路NoSQL数据库纷纷亮相,加上未亮相可是名声在外的,起码有超过10个开源的NoSQLDB,例如:json

Redis,Tokyo Cabinet,Cassandra,Voldemort,MongoDB,Dynomite,HBase,CouchDB,Hypertable, Riak,Tin, Flare, Lightcloud, KiokuDB,Scalaris, Kai, ThruDB ,  ……

这些NoSQL数据库,有的是用C/C++编写的,有的是用Java编写的,还有的是用Erlang编写的,每一个都有本身的独到之处,看都看不过来了,这 些NoSQL数据库大体能够分为如下的三类:

1、知足极高读写性能需求的Kye-Value数据库:Redis,Tokyo Cabinet, Flare

高性能Key-Value数据库的主要特色就是具备极高的并发读写性能,Redis,Tokyo Cabinet, Flare,这3个Key-Value DB都是用C编写的,他们的性能都至关出色,但出了出色的性能,他们还有本身独特的功能:

一、Redis
Redis是一个很新的项目,刚刚发布了1.0版本。Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库统 统加载在内存当中进行操做,按期经过异步操做把数据库数据flush到硬盘上进行保存。由于是纯内存操做,Redis的性能很是出色,每秒能够处理超过 10万次读写操做,是我知道的性能最快的Key-Value DB。

Redis的出色之处不只仅是性能,Redis最大的魅力是支持保存List链表和Set集合的数据结构,并且还支持对List进行各类操做,例如从 List两端push和pop数据,取List区间,排序等等,对Set支持各类集合的并集交集操做,此外单个value的最大限制是1GB,不像 memcached只能保存1MB的数据,所以Redis能够用来实现不少有用的功能,比方说用他的List来作FIFO双向链表,实现一个轻量级的高性 能消息队列服务,用他的Set能够作高性能的tag系统等等。另外Redis也能够对存入的Key-Value设置expire时间,所以也能够被看成一 个功能增强版的memcached来用。

Redis的主要缺点是数据库容量受到物理内存的限制,不能用做海量数据的高性能读写,而且它没有原生的可扩展机制,不具备scale(可扩展)能力,要 依赖客户端来实现分布式读写,所以Redis适合的场景主要局限在较小数据量的高性能操做和运算上。目前使用Redis的网站有 github,Engine Yard。

二、Tokyo Cabinet和Tokoy Tyrant
TC和TT的开发者是日本人Mikio Hirabayashi,主要被用在日本最大的SNS网站mixi.jp上,TC发展的时间最先,如今已是一个很是成熟的项目,也是Kye-Value 数据库领域最大的热点,如今被普遍的应用在不少不少网站上。TC是一个高性能的存储引擎,而TT提供了多线程高并发服务器,性能也很是出色,每秒能够处理 4-5万次读写操做。

TC除了支持Key-Value存储以外,还支持保存Hashtable数据类型,所以很像一个简单的数据库表,而且还支持基于column的条件查询, 分页查询和排序功能,基本上至关于支持单表的基础查询功能了,因此能够简单的替代关系数据库的不少操做,这也是TC受到你们欢迎的主要缘由之一,有一个 Ruby的项目miyazakiresistance将TT的hashtable的操做封装成和ActiveRecord同样的操做,用起来很是爽。

TC/TT在mixi的实际应用当中,存储了2000万条以上的数据,同时支撑了上万个并发链接,是一个久经考验的项目。TC在保证了极高的并发读写性能 的同时,具备可靠的数据持久化机制,同时还支持相似关系数据库表结构的hashtable以及简单的条件,分页和排序操做,是一个很棒的NoSQL数据 库。

TC主要的缺点是没有scale的能力,若是单机没法知足要求,只能经过主从复制的方式扩展,另外有人提到TC的性能会随着数据量的增长而降低,当数据量 上亿条之后,性能会有比较明显的降低。

这个是Tim Yang作的一个Memcached,Redis和Tokyo Tyrant的简单的性能评测,仅供参考

三、Flare
TC是日本第一大SNS网站mixi开发的,而Flare是日本第二大SNS网站green.jp开发的,有意思吧。Flare简单的说就是给TC添加了 scale功能。他替换掉了TT部分,本身另外给TC写了网络服务器,Flare的主要特色就是支持scale能力,他在网络服务端以前添加了一个 node server,来管理后端的多个服务器节点,所以能够动态添加数据库服务节点,删除服务器节点,也支持failover。若是你的使用场景必需要让TC可 以scale,那么能够考虑flare。

flare惟一的缺点就是他只支持memcached协议,所以当你使用flare的时候,就不能使用TC的table数据结构了,只能使用TC的 key-value数据结构存储。

2、知足海量存储需求和访问的面向文档的数据库:MongoDB,CouchDB

面向文档的非关系数据库主要解决的问题不是高性能的并发读写,而是保证海量数据存储的同时,具备良好的查询性能。MongoDB是用C++开发的,而 CouchDB则是Erlang开发的:

一、MongoDB
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构很是松散,是相似 json的bjson格式,所以能够存储比较复杂的数据类型。Mongo最大的特色是他支持的查询语言很是强大,其语法有点相似于面向对象的查询语言,几 乎能够实现相似关系数据库单表查询的绝大部分功能,并且还支持对数据创建索引。

Mongo主要解决的是海量数据的访问效率问题,根据官方的文档,当数据量达到50GB以上的时候,Mongo的数据库访问速度是MySQL的10倍以 上。Mongo的并发读写效率不是特别出色,根据官方提供的性能测试代表,大约每秒能够处理0.5万-1.5次读写请求。

由于Mongo主要是支持海量数据存储的,因此Mongo还自带了一个出色的分布式文件系统GridFS,能够支持海量的数据存储,但我也看到有些评论认 为GridFS性能不佳,这一点仍是有待亲自作点测试来验证了。

最后因为Mongo能够支持复杂的数据结构,并且带有强大的数据查询功能,所以很是受到欢迎,不少项目都考虑用MongoDB来替代MySQL来实现不是 特别复杂的Web应用,比方说why we migrated from MySQL to MongoDB就是一个真实的从MySQL迁移到MongoDB的案例,因为数据量实在太大,因此迁移到了Mongo上面,数据查询的速度获得了很是显著 的提高。

MongoDB也有一个ruby的项目MongoMapper,是模仿Merb的DataMapper编写的MongoDB的接口,使用起来很是简单,几 乎和DataMapper如出一辙,功能很是强大易用。

二、CouchDB
CouchDB如今是一个很是有名气的项目,彷佛不用多介绍了。可是我却对CouchDB没有什么兴趣,主要是由于CouchDB仅仅提供了基于HTTP REST的接口,所以CouchDB单纯从并发读写性能来讲,是很是糟糕的,这让我马上抛弃了对CouchDB的兴趣。

3、知足高可扩展性和可用性的面向分布式计算的数据库:Cassandra,Voldemort

面向scale能力的数据库其实主要解决的问题领域和上述两类数据库还不太同样,它首先必须是一个分布式的数据库系统,由分布在不一样节点上面的数据库共同 构成一个数据库服务系统,而且根据这种分布式架构来提供online的,具备弹性的可扩展能力,例如能够不停机的添加更多数据节点,删除数据节点等等。因 此像Cassandra经常被当作是一个开源版本的Google BigTable的替代品。Cassandra和Voldemort都是用Java开发的:

一、Cassandra
Cassandra项目是Facebook在2008年开源出来的,随后Facebook本身使用Cassandra的另一个不开源的分支,而开源出来 的Cassandra主要被Amazon的Dynamite团队来维护,而且Cassandra被认为是Dynamite2.0版本。目前除了 Facebook以外,twitter和digg.com都在使用Cassandra。

Cassandra的主要特色就是它不是一个数据库,而是由一堆数据库节点共同构成的一个分布式网络服务,对Cassandra的一个写操做,会被复制到 其余节点上去,对Cassandra的读操做,也会被路由到某个节点上面去读取。对于一个Cassandra群集来讲,扩展性能是比较简单的事情,只管在 群集里面添加节点就能够了。我看到有文章说Facebook的Cassandra群集有超过100台服务器构成的数据库群集。

Cassandra也支持比较丰富的数据结构和功能强大的查询语言,和MongoDB比较相似,查询功能比MongoDB稍弱一些,twitter的平台 架构部门领导Evan Weaver写了一篇文章介绍Cassandra:http://blog.evanweaver.com/articles/2009/07/06 /up-and-running-with-cassandra/,有很是详细的介绍。

Cassandra以单个节点来衡量,其节点的并发读写性能不是特别好,有文章说评测下来Cassandra每秒大约不到1万次读写请求,我也看到一些对 这个问题进行质疑的评论,可是评价Cassandra单个节点的性能是没有意义的,真实的分布式数据库访问系统必然是n多个节点构成的系统,其并发性能取 决于整个系统的节点数量,路由效率,而不只仅是单节点的并发负载能力。

二、Voldemort
Voldemort是个和Cassandra相似的面向解决scale问题的分布式数据库系统,Cassandra来自于Facebook这个SNS网 站,而Voldemort则来自于Linkedin这个SNS网站。提及来SNS网站为咱们贡献了n多的NoSQL数据库,例如 Cassandar,Voldemort,Tokyo Cabinet,Flare等等。Voldemort的资料不是不少,所以我没有特别仔细去钻研,Voldemort官方给出Voldemort的并发读 写性能也很不错,每秒超过了1.5万次读写。

从Facebook开发Cassandra,Linkedin开发Voldemort,咱们也能够大体看出国外大型SNS网站对于分布式数据库,特别是对 数据库的scale能力方面的需求是多么殷切。前面提到,web应用的架构当中,web层和app层相对来讲都很容易横向扩展,惟有数据库是单点的,极难 scale,如今Facebook和Linkedin在非关系型数据库的分布式方面探索了一条很好的方向,这也是为何如今Cassandra这么热门的 主要缘由。

补充说明:1.实质。  非关系型数据库的实质:非关系型数据库产品是传统关系型数据库的功能阉割版本,经过减小用不到或不多用的功能,来大幅度提升产品性能。2.价格。  目前基本上大部分主流的非关系型数据库都是免费的。而比较有名气的关系型数据库,好比Oracle、DB二、MSSQL是收费的。虽然Mysql免费,但它须要作不少工做才能正式用于生产。3.功能。  实际开发中,有不少业务需求,其实并不须要完整的关系型数据库功能,非关系型数据库的功能就足够使用了。这种状况下,使用性能更高、成本更低的非关系型数据库固然是更明智的选择。非关系型数据库在某些特定的领域很好用,好比redis做为数据的缓存,数据是存储在内存中,因此性能很是好,底层只有三万条代码,貌似知乎就用到了redis做为数据库。 非关系数据库只实现了关系数据库一部分的功能,但所以很大程度上扩充了某些功能的性能。通常用关系数据库就够了。严格说mysql在关系数据库兄是实现得也不是很完整的一类,从而在某些查询上,mysql有超出严格关系数据库不少的性能。具体应用须要权衡,特别是关联条件不少的数据,非关系数据库通常不合适,有时候甚至mysql也不合适。

相关文章
相关标签/搜索