简单的说明了为什么要使用Nosql。接下来我们看下如何把Nosql引入到我们的项目中,我们到底要不要把Nosql引入到项目中。
在过去,我们只需要学习和使用一种数据库技术,就能做几乎所有的数据库应用开发。因为成熟稳定的关系数据库产品并不是很多,而供你选择的免费版本就 更加少了,所以互联网领域基本上都选择了免费的MysqL数据库。在高速发展的WEB2.0时代,我们发现关系数据库在性能、扩展性、数据的快速备份和恢 复、满足需求的易用性上并不总是能很好的满足我们的需要,我们越来越趋向于根据业务场景选择合适的数据库,以及进行多种数据库的融合运用。几年前的一篇文 章《One Size Fits All - An Idea Whose Time Has Come and Gone》就已经阐述了这个观点。
当我们在讨论是否要使用Nosql的时候,你还需要理解Nosql也是分很多种类的,在Nosql百花齐放的今天,Nosql的正确选择比选择关系数据库还具有挑战性。虽然Nosql的使用很简单,但是选择却是个麻烦事,这也正是很多人在观望的一个原因。
Nosql的分类
Nosql仅仅是一个概念,Nosql数据库根据数据的存储模型和特点分为很多种类。
类型 |
部分代表 |
特点 |
列存储 |
Hbase Cassandra Hypertable |
顾名思义,是按列存储数据的。最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有非常大的IO优势。 |
文档存储 |
MongoDB CouchDB |
文档存储一般用类似json的格式存储,存储的内容是文档型的。这样也就有有机会对某些字段建立索引,实现关系数据库的某些功能。 |
key-value存储 |
Tokyo Cabinet / Tyrant Berkeley DB MemcacheDB Redis |
|
图存储 |
Neo4J FlockDB |
|
对象存储 |
db4o Versant |
通过类似面向对象语言的语法操作数据库,通过对象的方式存取数据。 |
xml数据库 |
Berkeley DB XML BaseX |
以上Nosql数据库类型的划分并不是绝对,只是从存储模型上来进行的大体划分。它们之间没有绝对的分界,也有交差的情况,比如Tokyo Cabinet / Tyrant的Table类型存储,就可以理解为是文档型存储,Berkeley DB XML数据库是基于Berkeley DB之上开发的。
Nosql还是关系数据库
虽然09年出现了比较激进的文章《关系数据库已死》,但是我们心里都清楚,关系数据库其实还活得好好的,你还不能不用关系数据库。但是也说明了一个事实,关系数据库在处理WEB2.0数据的时候,的确已经出现了瓶颈。
那么我们到底是用Nosql还是关系数据库呢?我想我们没有必要来进行一个绝对的回答。我们需要根据我们的应用场景来决定我们到底用什么。
如果关系数据库在你的应用场景中,完全能够很好的工作,而你又是非常善于使用和维护关系数据库的,那么我觉得你完全没有必要迁移到Nosql上面, 除非你是个喜欢折腾的人。如果你是在金融,电信等以数据为王的关键领域,目前使用的是Oracle数据库来提供高可靠性的,除非遇到特别大的瓶颈,不然也 别贸然尝试Nosql。
然而,在WEB2.0的网站中,关系数据库大部分都出现了瓶颈。在磁盘IO、数据库可扩展上都花费了开发人员相当多的精力来优化,比如做分表分库 (database sharding)、主从复制、异构复制等等,然而,这些工作需要的技术能力越来越高,也越来越具有挑战性。如果你正在经历这些场合,那么我觉得你应该尝 试一下Nosql了。
选择合适的Nosql
如此多类型的Nosql,而每种类型的Nosql又有很多,到底选择什么类型的Nosql来作为我们的存储呢?这并不是一个很好回答的问题,影响我们选择的因素有很多,而选择也可能有多种,随着业务场景,需求的变更可能选择又会变化。我们常常需要根据如下情况考虑:
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("SELECTidFROMcommentswhereaid='评论对象id'LIMIT0,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慢一点,但是完全可以用来缓存数据库的查询操作。
规避风险
由于Nosql是一个比较新的东西,特别是我们选择的Nosql数据库还不是非常成熟的产品,所以我们可能会遇到未知的风险。为了得到Nosql的好处,又要考虑规避风险,鱼与熊掌如何兼得?
现在业内很多公司的做法就是数据的备份。在往Nosql里面存储数据的时候还会往MysqL里面存储一份。Nosql数据库本身也需要进行备份(冷 备和热备)。或者可以考虑使用两种Nosql数据库,出现问题后可以进行切换(避免出现digg使用Cassandra的悲剧)。
总结
本文只是简单的从MysqL和Nosql的角度分析如何选择,以及进行融合使用。其实在选择Nosql的时候,你可能还会碰到关于CAP原则,最终一致性,BASE思想的考虑。因为使用MysqL架构的时候,你也会碰到上面的问题,所以这里没有阐述。