IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

我为什么选择MongoDB

超群.com的博客 2011-05-31 13:57:18 累计浏览 4,754 次
本机暂存

大概在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之类。

同分类推荐文章

  1. 使用deepseek进行Oracle恢复,引起重大故障 (2026-06-22 10:56:00)
  2. 接手一个只差临门一脚的数据库恢复 (2026-06-18 00:13:09)
  3. 我做了一个 AI 版的 StarRocks 升级风险扫描工具,直接帮我定位到一个风险 (2026-06-15 01:00:00)

查看更多 数据库 文章 →

建议继续学习

  1. 用Hyer来进行网站的抓取 (累计阅读 158,250)
  2. MySQL数据库在实际应用一些方面的介绍 (累计阅读 36,397)
  3. WordPress插件开发 -- 在插件使用数据库存储数据 (累计阅读 29,164)
  4. Mysql监控指南 (累计阅读 21,351)
  5. 由浅入深探究mysql索引结构原理、性能分析与优化 (累计阅读 16,523)
  6. 分布式缓存系统 Memcached 入门 (累计阅读 16,243)
  7. HFile存储格式 (累计阅读 15,973)
  8. hbase运维 (累计阅读 14,923)
  9. 什么是全栈工程师? (累计阅读 14,038)
  10. 30分钟3300%性能提升――python+memcached网页优化小记 (累计阅读 13,742)