如何学习NoSQL?

How You Should Go About Learning NoSQL

作者在twitter上总结:
1: 用 MongoDB. 2: 花20分钟学习Redis 3: 观察这个video理解Dynamo.

这篇文章主要是明确两个概念:
1.第二索引和Join问题,在关系数据库中,通常除了主索引主键primary key之外,还有第二个index。而NoSQL一般只有主键,没有第二索引,那怎么替换呢?

作者认为可以无需第二索引,以Score表为例子,有主键Id, LeaderboarId 和UserId以及Score四个字段。作者意思再创建另外一个表有两个字段:LeaderboardId 和 ScoreIds,表达属于同一个leaderboard所有Score。通过两次查询,首先根据LeaderboarId获得所有的 ScoreId集合,然后再在Score表中根据主键Id(ScoreId)获得其余字段。

在关系数据库中可能将ScoreIds看成一个数组,因而效率不太好,但是如果数据库引擎将其看成是一个整块对象(可以Push remove和切片slice),这个方案就不会那么夸张了,当然,不可否认第二索引也许更好些。

第二个需要明确的是joins,虽然有些NoSQL支持第二索引有些其他不支持,但是他们几乎都认为joins是狗屎。

为什么呢?因为joins导致数据库切分sharding无法实施,Sharding是大多数NoSQL可伸缩的方案。

以score为例,leaderboard的1 3 5 7 9的score数据也许在服务器1,而服务器2包含 leaderboard的2 4 6 8 10数据,一旦你这样开始切分你的数据,join将不会起作用。比如要通过join Scores,userId和Users.Id获得UserName,因为在不同服务器上,就无法获得。

那么我们如果处理无join(joinless)世界呢?在你自己应用程序中使用join类似功能,比如通过二次查询,你首先获得所有scores数据,然后,通过再通过查询Users表获得UserName集合。增加代码必要的复杂性才能进行水平伸缩。

作者在该文还谈了具体几个NoSQL的特点,待续。

[该贴被banq于2011-08-16 09:58修改过]

MongoDB是最容易学习的第一个NoSQL,到其官方网站下载后,在本地硬盘建立 c:/data/db (或 /data/db), 启动 bin/mongod 即可。通过程序连接需要相应的驱动插件。

MongoDB 支持第二索引,可以替换90%的关系数据库应用场合。是一个较为通用的NoSQL。

但是不完美,文档不是很丰富;数据集大于内存很慢。

MongoDB 使用MapReduce替代SQL的聚合功能进行分析,但是当前是单线程,并不可伸缩。

作者的MongoDB快速使用手册:http://mongly.com/tutorial/index

Redis是最容易被误解的NoSQL,它是一个in-memory data structure engine内存数据结构引擎(IMDG in-memory数据网格?)它内建支持五种数据结构,当然最简单的是key-value。这也是人们把它归结于key-value原因,其实远不止这些。

使用Redis取决于对于你的数据重新思考,否则会发生方形木桩插入圆形孔的问题,它不支持第二索引。

如果我们想跟踪用户总数和每天登陆系统的唯一用户数:

用户总数是一个key-value,key是日期:
redis.incr(Time.now.utc.strftime('%Y-%m-%d'))

读取过去一星期的用户总数:
redis.mget *Array.new(7){|i| (Time.now.utc - (86400 * i)).strftime('%Y-%m-%d') }

Redis 也并不完美,需要数据集正好都能适合内存大小,Redis Cluster可以进行复制和手工failover.

作者两篇Redis文章:talks about using Redis with MongoDB.,以Score为案例比较了MongoDB和Redis对于数据模型的不同。

Rethink your Data Model
在该文中,作者发现关系数据库能够过滤一个字段,而Redis限制你查询数据的方式。Key-value意味着只能关注Key,其他都放入value中。作者认为这和愚蠢,差点放弃NoSQL(banq注:我觉得作者有些愚蠢,将Value理解成一个对象即可,而对象是数据的集合,在OO中我们经常用Map这么干,结果在文章后面他开始沿着这个思路实现了)。

Cassandra是Dynamo最广泛的开源实现, 作者认为 Cassandra不但难于设置,还要重新考虑数据模型。

banq注:Cassandra是Java实现的,让作者以Java等OO方式考虑数据是一种颠覆或痛苦,对于其他习惯关系数据库方式思考数据的人来说应该是一样。

再说一下架构思路上的差异:NoSQL选择依据和关系数据库是不一样的,过去我们可以在一个系统中选择一种关系数据库,而现在现在要根据业务数据(实际是领域模型)的不同,选择不同的NoSQL,不可能一种数据库包打天下了。

选择依据还是要依据CAP理论,所有NOSQL都有P(分布式分区),不同的就是在A和C之间侧重点,所以,要对你的业务根据C一致性要求进行划分。

正如Amazon云存储分别采取S3(适合静态大文件)和RDS(动态小数据)一样,下图是一个电子商务系统NoSQL方案:

从这张电子商务系统NOSQL图看出,Cassandra实时性好,用于购物车和用户帐户状态比较好,而淘宝网使用实时性并不很好的HBase来实现购物车(传说),可能存在误用。见这篇文章:banq认为淘宝网可能误用HBase
[该贴被banq于2011-08-19 10:01修改过]


NoSQL就业趋势调查

对九个NOSQL进行了就业需求调查: Cassandra, Redis, Voldemort, SimpleDB, CouchDB, MongoDB, HBase, Hypertable and Riak. 这是来自Indeed.com报告

从以上2006年到2011年职位需求看出:MongoDB 在过去18个月的职位需求领先于Cassandra(banq注:MongoDB相对通用),其次是Cassandra,最近几个月平缓,第三是HBase,第四是Redis,第五CouchDB也在增长,其余好像停止增长。

再看看2009年到2011年短期的职位需求:

上图显示, Cassandra and MongoDB领先于HBase快速增长。

还有一张相对增长率,可见原文。

其他文章:闲话淘宝网和新浪微博架构
[该贴被banq于2011-08-26 17:53修改过]

NoSQL就业趋势调查? 纳闷,从事NoSQL工作的人都需要什么知识,处理什么问题呢?