欢迎大家一起讨论:
MongoDB
不支持事务
也许需不需要数据库事务成了是否选择 MongoDB 的决定性因素,MongoDB 不支持数据库事务。
有很多应用对数据一致性其实要求不高,例如很多社交应用,大多数应用逻辑只是简单存取(发一段文字,上传一张照片),极少的不一致是不影响应用的。 而一些严肃应用,例如交易系统,就很需要数据库事务的支持了,否则就需要在应用层自己实现一个粗糙的、充满 Bug 的事务支持。如果有兴趣自己实现事务操作,可以看 MongoDB 的文章 Perform Two Phase Commits。
如果有跨系统的事务操作,就不能完全依赖数据库事务,还要有应用层的重试或回滚操作(例如远程调用支付接口)。数据库层面支持事务的话,起码让维护系统内部数据一致性更轻松。
查询语法
MongoDB 的原生查询语法是 JavaScript,JavaScript 程序员可能对此欣喜若狂。我最初感觉也是很新鲜,但久了就觉得很烦躁。JavaScript 太多的括号和花括号,在组合多个查询条件的时候作括号匹配很费神。SQL 是一个查询 DSL,虽然看起来有点古老,但是在查询这个特定领域上做得很好。
如果应用使用 ORM,可能很多时候不需要写原生查询语句。除了 PHP 社区外,其他社区也不推荐写原生查询。不过少数情况下,复杂查询还是原生语句更高效,而且数据库终端也是调试查询错误的最终手段,所以查询语法至少不能让人难受。
默认不安全
MongoDB 的开发者假设你是一个资深系统管理员,并且把 MongoDB 部署在安全的内部网络当中,所以他们官方安装包内含的配置没有设置任何安全验证,接收任何来源的访问,结果就是一些初级系统管理员(例如我)把 MongoDB 直接暴露到了公网,造成数据泄漏。
这不仅是 MongoDB 的问题,Redis、Elasticsearch 也是这样,姑且把这认为是一种设计“哲学”。Ubuntu 的软件源管理者不认同这个“哲学”,从软件源安装的 MongoDB 的默认只接受本地连接,这保护了一些初级系统管理员,但如果追新使用数据库开发方的安装包就会中招。顺便一提,PostgreSQL 默认配置只接受本地连接。
无论用什么数据库都好,使用前一定要完整读一遍文档,特别是设置和安全相关的章节,同时设置系统防火墙。
库
MongoDB 的官方驱动更新没有问题,不过一般不会直接使用驱动写程序(写过,很繁琐),而是使用 ODM(对象-文档映射)工具,在 Ruby 中就是 Mongoid。
Mongoid 已经做得很好,提供了类似 ActiveRecord 的 API,并且很好的利用了 MongoDB 的特性,但在关注度和社区规模上还不及 ActiveRecord。ActiveRecord 作为 Rails 的默认组件,每次都是跟随 Rails 的更新同时更新的,Mongoid 则要滞后一段时间。所以如果你希望紧跟 Rails 的更新,那么最好使用 ActiveRecord 和关系数据库。
为什么是 PostgreSQL 而不是 MySQL/MariaDB
今年开始,我的精力投入到一个交易网站的开发,所以一开始就打算迁移到关系数据库。至于为什么用 PostgreSQL 而不是 MySQL/MariaDB,有几个理由:
1.有趣,我还没用过 PostgreSQL。
2.PostgreSQL 的数据类型更多,我主要需要 Array 和 HStore。这些数据类型可以减少开发量,在 MySQL 实现 Tag 属性需要多两张表。
3.过去的工作中让我接触到 MySQL 不好的一面,例如因为 JOIN 性能不好(我没验证过),不允许用 includes 方法,基本上只做主键查询,所以我之前那么容易接受 MongoDB。
4.MySQL 被 Oracle 收购后社区出现分裂(MariaDB),我对 Oracle 印象也不好,前公司旗下一个网站因为域名带有 Java 而收到律师函,所以我尽可能避开 Oracle 的产品。
5.PostgreSQL 的社区热度在增加,ActiveRecord 对其特性的支持也在完善。
基于以上理由,我选择了 PostgreSQL,目前为止工作得很好。
如果说插件式存储引擎API为MongoDB 3.0打造了一个武器库,那么WiredTiger绝对是武器库中第一枚也是最重要的一枚重磅炸弹。因为MMAP存储引擎自身的天然缺陷(耗费磁盘空间和内存空间且难以清理,库级别锁),MongoDB为数据库运维人员带来了极大痛苦,甚至一部分人已经开始转向TokuMX,尽管后者目前也不甚稳定。意识到这一问题的MongoDB,做出了有钱任性的决定,直接收购存储引擎厂商WiredTiger,将WiredTiger存储引擎集成进3.0版本(仅在64位版本中提供)。
#4
更多评论