我为什么选择MongoDB

标签: 默认分类 | 发表时间:2011-05-30 18:55 | 作者:超群.com Caiwangqin
出处:http://www.fuchaoqun.com

大概在08年,那时候nosql的概念特别热,最早的那批开源项目好多参考google bigtable来设计,我也关注过其中的几个,比如hypertable,couchdb之类,阅读了一些相关的文档和博文,没有太跟进,那些开源项目的设计scope太大,想解决google都不一定很好解决的问题,事实上国内能真正碰到那种数据规模的人少,很少,极少;迁移的成本也很高,我们的项目大多构建在mysql+memcached上,关系型的操作很多,这种key-value或者类key-value的数据库不是特别合用;也觉得很难从那些产品中获得什么可预知的好处,不管是性能上的还是开发上的,所以也在那些项目上浅尝辄止。

mongodb是从09年开始关注,从最初的一些文档可以看出这家伙是来解决实际问题的,mongodb的作者们对mysql+memcached这套东西的优势和弊端看的非常清楚,项目的设计对我们这些lamp程序员来说,也有天然的亲和力,你可以很容易把mysql的那套东西照搬到mongodb,比如collection对于mysql里面的table,没有言必谈分布式,可以很容易在单机上开发测试,可以相信在mongodb早期的auto-sharding只是个噱头,事实上在早期的很多版本官方也不太推荐大家用。

我在选用一些技术的时候大多考虑这些方面:

1. 新的方案能不能解决目前项目中难以忍受的问题?

2. 新的方案是不是足够简单?见过很多的项目为了解决一个稍显复杂的问题引入一个更加复杂的方案,着实累人

3. 新的方案能不能很平滑的应用到项目中去?

4. 新的方案能不能被替换?不能被替换的方案都是烂方案

在mongodb之前,我碰到的问题是:

1. 项目的需求不断变化,数据库表结构需要不断调整来满足新的需求,FriendFeed用的是schema-less方法来解决这种问题,但是schema-less也有一些问题,在设计时候需要考虑动静分离,要不然为了更新某个小数据需要频繁的更新整个大数据块会比较烦躁,数据的一致性和有效性需要在代码中特别注意。

2. 多对多关系的处理,典型的例子是文章tag,一篇文章有多个tag,每个tag对应多篇文章,传统的做法是维护2张表,一张是tag表,里面是tag_id对应的tag_name,另外一张是文章对应tag表,里面维护3个字段,tag_id、文章id、tag被打的次数,然后当有用户新打tag的时候,你需要把新的tag和已有的tag比较,相同的+1,不存在的需要新建,然后置为1,删除什么的也是各种烦躁

mongodb文档型数据库设计可以很好的解决这些问题,schema less的设计可以把整片数据塞进去,可以很方便的对数据key建立索引,提高访问速度,tag处理也非常方便,直接把{tag_name:tag_times}数据丢进去就可以,非常方便。

mongodb支持大多数的mysql操作,原有代码稍作修改即可,可以很平滑的应用,对于一个MVC的应用来说,基本上小修改model层就可以,非常轻松,当然,如果一天mongodb不行了,再切换回去也不是什么困难的事情。

作为一个前中期的开源项目,mongodb也有一些问题需要注意:

1. 运维和监控工具不如mysql那么丰富

2. mongodb采用的mmap机制,在断电和某些异常情况下有可能丢失数据或者crash,好消息是1.8以后可以打开journal日志来避免此类问题

3. schema less是一把双刃剑,因为什么数据都可以往里面存,不像mysql那样会有字段的概念可以对数据有效性把最后一道关,需要在编写程序的时候特别注意一下数据有效性,当然用mysql也要注意

4. 没有auto increment id,这个很不爽,不过可以通过findandmodify来模拟出来

function autoIncrementId($domain, $collection = 'autoIncrementIds', $db = null)
{
    $result = $mongo->command(array(
        'findAndModify' => $collection,
        'query' => array('_id' => $domain),
        'update' => array('$inc' => array('val' => 1)),
        'new' => true,
        'upsert' => true
    ));
 
    if ($result['ok']) {
        return $result['value']['val'];
    }
 
    throw new Exception('Mongo: gen auto increment id failed');
}

如果你采用ColaPHP框架开发的话,这部分代码已经包含在里面了。

一个建议是如非必要,不要用mongodb里面独有的特性,用的越多,绑的越紧,这些特性包括auto-sharding之类。

另外一个好消息是国内第一本mongodb图书出版了《MongoDB权威指南》,这是一本手册性质的指南,译者是mongodb中国社区的负责人程显峰,对于不喜欢E文的同学了解mongodb大有裨益,我也在读。

相关 [选择 mongodb] 推荐:

我为什么选择MongoDB

- Caiwangqin - 超群.com的博客
我在选用一些技术的时候大多考虑这些方面:. 新的方案能不能解决目前项目中难以忍受的问题. 见过很多的项目为了解决一个稍显复杂的问题引入一个更加复杂的方案,着实累人. 新的方案能不能很平滑的应用到项目中去. 在mongodb之前,我碰到的问题是:. 项目的需求不断变化,数据库表结构需要不断调整来满足新的需求,FriendFeed用的是schema-less方法来解决这种问题,但是schema-less也有一些问题,在设计时候需要考虑动静分离,要不然为了更新某个小数据需要频繁的更新整个大数据块会比较烦躁,数据的一致性和有效性需要在代码中特别注意.

[mongodb] java操作mongodb

- - 数据库 - ITeye博客
           //实例化Mongo对象,连接27017端口.                               //连接名为yourdb的数据库,假如数据库不存在的话,mongodb会自动建立. //从Mongodb中获得名为yourColleection的数据集合,如果该数据集合不存在,Mongodb会为其新建立.

【MongoDB】MongoDB之优化器Profiler

- - CSDN博客数据库推荐文章
在mysql数据库中,慢查询日志经常作为优化数据库的依据, mongodb中依然有类似的功能. Mongodb自带的profiler,可以方便地记录所有耗时的操作,以便于调优;. 一、开始profiler功能. 开启profier功能有两种:. 第一种就是直接在启动参数里面进行设置,就在茄冬mongodb时候添加-profile=级别.

夜说mongodb

- Lianhui Wang - NoSQLFan
前两天本站刚刚分享了wordnik使用MongoDB经验的文章:《Wordnik 的 MongoDB 使用经历》,今天又看到一位朋友对这方面做的总结,分享在这里,供大家参考. 赋闲以后很长没有更新博客了,说忙完全是借口,多半因为没有兴致所致. 今天凌晨比赛多多,趁着比赛的前奏和间隙,遂浏览些技术文章.

MongoDB与内存

- 高春辉 - 火丁笔记
但凡初次接触MongoDB的人,无不惊讶于它对内存的贪得无厌,至于个中缘由,我先讲讲Linux是如何管理内存的,再说说MongoDB是如何使用内存的,答案自然就清楚了. 据说带着问题学习更有效,那就先看一个MongoDB服务器的top命令结果:. 这台MongoDB服务器有没有性能问题. 先讲讲Linux是如何管理内存的.

白话MongoDB(一)

- Ease - 江边潮未尽,枫红一季秋
按照官方的说法,MongoDB是一种可扩展的高性能的开源的面向文档(document-oriented )的数据库,采用C++开发. 注意mongo不是mango(芒果),这个词是从humongous中截取出来的,其野心不言而明,直指海量数据存储. 和其他很多NoSQL不太一样,MongoDB背后有一个专门的商业公司在提供支持和推广,有点类似MySQL AB的模式.

MongoDB 索引

- - 博客园_首页
索引是用来加快查询的,数据库索引与数据的索引类似,有了索引就不需要翻遍整本书,数据库可以直接在索引中查找,. 使得查询速度很快,在索引中找到条目后,就可以直接跳转到目标文档的位置.. 要掌握如何为查询配置最佳索引会有些难度.. MongoDB索引几乎和关系型数据库的索引一样.绝大数优化关系型数据库索引的技巧同样适用于MongoDB..

MongoDB sql操作

- - 数据库 - ITeye博客
1.  基本查询:. 下面的示例等同于SQL语句的where name = "stephen" and age = 35.      --返回指定的文档键值对. 下面的示例将只是返回name和age键值对.      --指定不返回的文档键值对. 下面的示例将返回除name之外的所有键值对.

MongoDB Shareding部署

- - 开源小站
几年前写过 MongoDB的Sharding和replication. 其实现在看起来Replication还是可以,Sharding的部分有点过于简单了. 于是现在重新补充一下,至少也更新下,毕竟现在的MongoDB已经到了2.6,于当时的2.2还是有所差异的. 正常的情况下,应该是有6台主机实现一个比较像样的MongoDB Sharding集群,它们分别是mongos /router1台,config 3台,shard 2台.