踏上 NoSQL 之路
最近的项目中,异想天开突然想要引进一些新的技术。这个项目其实我已经开发了 3 个月了,是一个非常普通的 PHP + MySQL 的 Web 项目。所以我一开始所想的不是要将 MySQL 去掉完全利用 NoSQL,而是在想如何在我的项目中利用 NoSQL。
在这之前,我对于 NoSQL 几乎没半点概念,只知道 NoSQL 似乎是为了解决 RDBMS 扩展问题 (scaling problem) 而出现的。除此之外真的一点也不知道 NoSQL 有什么功用。于是乎我就开始在网上搜索资料,对 NoSQL 进行学习。有不少说明何谓 NoSQL 的资料,过程中我也了解到 NoSQL 有 4 种 [1],这 4 种都有不同的功能。
在清楚何谓 NoSQL 之后就开始进行思考了,究竟要如何在项目中利用 NoSQL?恰巧在 HN 上读到一篇文章 [2],发现原来 Redis 可以这么利用,而且文章也指出 Redis 在处理排行榜中的各种优势,于是就决定将项目中有关排行榜的那一部分从 MySQL 移植到 Redis。
之前,我对于排行榜的处理方式是将分数与玩家资料放在一起。由于某些页面有必要获取玩家的排名,因此就预先将排名算好当做玩家资料的表格的另一个栏储存起来。每次分数有所更动就必须全部重新计算,计算时间其实相当长。
在 Redis 则利用 Sorted Sets,只须将玩家的 ID 和分数记录下来,每次更动也无需进行任何计算,要获取玩家排名也不过直接 zrevrank ID 就可以了,非常方便。利用 Redis 之后,我也可以增加一些新的功能,比如根据玩家的种族进行排名,诸如此类在 MySQL 上会相当麻烦且花时间的功能都能够轻易实现。
成功利用 Redis 之后,我就看了看其他的 NoSQL 如 MongoDB,发现其实项目中暂时没有适合利用这种 NoSQL 的地方。当然,如果硬要利用 MongoDB 那还是可以的,但是其实没有这个必要。MongoDB 是一种 Document store database,这类数据库相关资料都必须放在同一个 Document 中,举例来说就是博客中 Article, Comments 和 Author 都必须在同一个 Document,在这个 Document 中的关系是每个 Article 都有多个 Comments 和一个 Author。对于我目前这个项目来说,各个元素之间有相当复杂的关系,如果要利用这种数据库会搞到一个 Document 非常巨大,结果可能不理想。
直到目前来说,还没有想到项目中还有哪一个部分可以移植到 NoSQL 去。但是就目前这个状况,我也挺满足的了。
> 数据库相关资料都必须放在同一个 Document 中,举例来说就是博客中 Article, Comments 和 Author 都必须在同一个 Document
mongodb的Document概念只是一个存储单元的实例,相当于RMDBS的一条记录,只不过是可以嵌套的复杂结构,而Collection对应的是RMDBS的Table。Article,Comment,Author可以放在同一个Document里面(Embed),也可以放在各自的Collection的Document里,甚至是不同db的Collection的Document(dbref),关联的时候用dbref来或者是你自定义的关联字段,详情可以看这里http://www.mongodb.org/display/DOCS/Schema+Design
嗯,原来还有这样的事情啊。但是你给我的链接中下面也提到 reference 很慢,效果貌似也不是很理想。那不是变成完全没有利用的原因了吗?
这个开销是必需的,就像关系数据库一样。用Embed还是ref…各有优缺点,取和舍的问题。