千寻中数据库的一点经验

发布于2012年5月8日 -

通过半个多学期的实践,我发现,想用好数据库真的是没那么容易。

之前有两篇文章来叙述千寻的数据库设计,但在实践中,千寻并没有按照之前设计的方式来使用数据库。最主要的原因是,数据在MongoDB和redis中重复出现,这个冗余带来的一致性问题比较难以解决,虽然在写代码的时候已经通过code review来尽量避免数据的不一致,但一致性的bug还是难以避免。

在这个项目中,我们一共使用了MongoDB和Redis两个数据库。下面分别来简述一下两个数据库在使用中的优劣:

MongoDB:MongoDB是一个典型的文档型数据库。在一些场合下,MongoDB真的是非常适合,比如保存一下用户信息,或者文章之类的。但是一旦需要用到relation,MongoDB就无能为力了。同样,在需要事务的场合,MongoDB也是无能为力的。但是MongoDB也具有无可替代的优点,它支持空间索引,常见的数据库里,只有MongoDB支持空间数据索引,这正是千寻所需要的核心功能。

Redis:Redis是一个非常好用的key-value数据库,和memcached相比,它的功能要强大很多,不仅支持简单的key-value存储,还提供集合、对象、列表等较高级的存储功能,此外也提供了自增等原子操作,基本上可以满足千寻这样一个交流工具的需求。但在使用中,我们也发现,Redis的编程方式与传统的程序不一样,这使得调试变得格外困难。

实践中,Redis的表现非常突出,不仅性能很高,而且它对多种数据结构的支持使得它足以应付千寻中除了空间索引外的其他所有需求。因此,通过对千寻的开发,我们认为,一个更理想的数据库设计应该是:使用Redis作为主数据库,而MongoDB仅用于存储地理位置,以提供近邻查找的功能。

由于我们也是刚开始接触NoSQL,有些观点难免确保正确,因此欢迎各位批评指正。