我最近第一次使用MongoDB,发现它非常易于使用且性能卓越.这引出了我的问题 - 为什么不是MongoDB?
让我们说我正在实施一个问答应用程序.我的方法是在MySQL数据库中实现用户数据,然后使用MongoDB进行问答存储 - 一个存储问题和所有响应的集合.
这种方法有什么问题吗?
MongoDB听起来像是一个很好的应用程序,但你有很多理由不使用它.
MongoDB不适合需要的应用程序:
多对象事务:MongoDB仅支持单个文档的ACID事务.
SQL:SQL是众所周知的,很多人都知道如何编写非常复杂的查询来做很多事情.这些知识可以跨MongoDB的查询语言特定于它的许多实现进行转移.
强大的ACID保证:MongoDB允许读取不一致的内容,这在某些应用程序中很好,但并非全部.
传统BI:存在许多非常强大的工具,允许OLAP和其他强大的BI应用程序以及针对传统SQL数据库运行的应用程序.
MongoDB是一个很棒的数据库,我很喜欢使用它.也就是说,如果你来自SQL的世界,它有一些陷阱.
除了ACID和其他有充分记录的事情(以及其他答案),这些事情让我们感到惊讶:
MongoDB希望你有内存.很多记忆.如果你无法将你的工作集安装在内存中,你可以忘掉它.这与大多数只使用内存作为缓存的关系数据库不同! 更具体一点: MongoDB使用RAM作为主存储,并将不需要的部分"交换"到磁盘上(Mongo决定将哪些部分"交换"到内核).传统的RDBMS以相反的方式工作 - 它们使用磁盘作为主存储,并使用RAM作为缓存机制.所以一般来说MongoDB使用更多的RAM.这本身并不是一件坏事,但结果是"真正的" RAM消耗难以预测,一旦工作集超过(难以预测)的限制,就会导致严重且意外的性能下降.
删除记录时,存储不会自动收缩.每个集合分配的空间将保持分配状态,直到您使用repair
DB或删除集合.它在数据库级别(数据文件)上以巨大的块分配,然后在需要时(扩展区)分配给集合.也就是说,在集合的已分配空间内,已删除的文档会为同一集合中的其他文档释放空间.这是对概念的一个很好的解释:http://www.10gen.com/presentations/storage-engine-internals
与在服务器端解析的SQL形成对比,在Mongo中,您将数据结构传递给查询和CRUD函数.结果是每个驱动程序提供不同的语法,这有点烦人.例如,PyMongo使用元组列表而不是字典(可能是因为Python中的dict不保留键的顺序)来指定将返回哪些字段find()
:(公平地说,这可能是唯一理智的方法) - 但这是不使用SQL等基于字符串的语言的结果
MongoDB shell: db.test.find({}, {a:1})
PyMongo: db.find({}, fields=[(a,1,)]
这不应被视为对MongoDB的批评 - 我喜欢使用它,它已被证明是一种可靠且高效的工具.但要正确使用它,您需要了解其空间管理.
可能的缺点:
您在仅使用SQL关系数据库的组织中工作.您还没有批准或支持使用NoSQL数据库.
您从未管理过MongoDB集群; 与所有技术一样,学习曲线也是如此.
你的数据真的是关系型的(例如,一个用户有很多问题;一个问题有很多答案),你忽略了这种可能性.
MondoDB是一个很好的解决方案,适用于适用的情况.如果你可以使用它,为什么不呢?