MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
特点:高性能、易部署、易使用,存储数据非常方便。
主要功能特性有:
Ø 面向集合存储,易存储对象类型的数据
Ø 模式自由
Ø 支持动态查询
Ø 支持完全索引,包含内部对象
Ø 支持查询
Ø 支持复制和故障恢复
Ø 使用高效的二进制数据存储,包括大型对象(如视频等)
Ø 自动处理碎片,以支持云计算层次的扩展性
Ø 支持RUBY,PYTHON,JAVA,C++,PHP等多种语言
Ø 文件存储格式为BSON(一种JSON的扩展)
Ø 可通过网络访问
使用原理
所谓“面向集合”(Collenction-Oriented),意思是数据被分组存储在数据集中,被称为一个集合(Collenction)。每个集合在数据库中都有一个唯一的标识名,并且可以包含无限数目的文档。集合的概念类似关系型数据库(RDBMS)里的表(table),不同的是它不需要定义任何模式(schema)。
模式自由(schema-free),意味着对于存储在mongodb数据库中的文件,我们不需要知道它的任何结构定义。如果需要的话,你完全可以把不同结构的文件存储在同一个数据库里。
存储在集合中的文档,被存储为键-值对的形式。键用于唯一标识一个文档,为字符串类型,而值则可以是各种复杂的文件类型。我们称这种存储形式为BSON(Binary JSON)。
优势:
1. 文档存储
数据存储以BSON/JSON文档,这对于Web应用程序有很大的意义。开发者API喜欢以JSON形式传输,这使得整个项目的数据表示可采用统一的模型。所有这一切都无需任何前期架构设计。
2. 可扩展性
MongoDB被用在一些规模庞大的环境中,FourSquare/Craiglist都在使用它。通过分片数据缩放处理理论上可实现更高的吞吐量。
3. 简单的复制
就像分片技术一样,MongoDB范围内复制过程同样简单好用,在副本机器上还有大量的复制选项。灵活的功能可满足用户应用的需求。
4. 易于查询
MongoDB以文档的形式存储数据,不支持事务和表连接。因此查询的编写、理解和优化都容易得多。简单查询设计思路不同于SQL模式,嵌入文档在特定的环境下可得到更好的查询,然而这需要先加入集合。如果需要执行多个请求到数据库则需要加入其到客户端。在MongoDB时ODM工具(如Doctrine2)将发挥自身的优势。
5. 安全性
由于MongoDB客户端生成的查询为BSON对象,而不是可以被解析的字符串,所以可降低受到SQL注入的攻击的危险。最常见的攻击类型为针对Web应用程序的攻击,在MongoDB上使用Doctrine2 ODMs 查询语言可减轻攻击风险。
6. 支持
用户在选择数据库时总是喜欢积极和充满活力的,这点非常重要。MongoDB在业界有非常大的影响力,用户也会定期的组织活动。MongoDB的标签在StackOverFlow是非常活跃的。你永远不会陷入困境,因为总有人与你讨论并解决问题。
7. 价格
MongoDB是免费的!
快速!(当然,这和具体的应用方式有关,通常来说,它比一般的关系型数据库快5位左右。)
很高的可扩展性 – 轻轻松松就可实现PB级的存储(但是可能我们并不需要PB级的存储,10TB可能就够了)
他有一个很好的 replication 模式 (replica sets)
有很完善的Java API
他的存储格式是Json的,这对Java来说非常好处理,对javascirpt亦然。
运维起来非常方便,你不用专门为它安排一个管理员。
它有一个非常活跃的社区(我提出的一个bug在20分钟内就能得到修复。多谢Elliot)
他的版本控制非常清楚。
MongoDB 背后的公司(10gen)已经准备好了明天在 MongoDB 上面的投入的资金了。
劣势
与关系型数据库相比,MongoDB的缺点:
①mongodb不支持事务操作。
所以事务要求严格的系统(如果银行系统)肯定不能用它。(这点和优点①是对应的)
②mongodb占用空间过大。
关于其原因,在官方的FAQ中,提到有如下几个方面:
1、空间的预分配:为避免形成过多的硬盘碎片,mongodb每次空间不足时都会申请生成一大块的硬盘空间,而且申请的量从64M、128M、256M那 样的指数递增,直到2G为单个文件的最大体积。随着数据量的增加,你可以在其数据目录里看到这些整块生成容量不断递增的文件。
2、字段名所占用的空间:为了保持每个记录内的结构信息用于查询,mongodb需要把每个字段的key-value都以BSON的形式存储,如果 value域相对于key域并不大,比如存放数值型的数据,则数据的overhead是最大的。一种减少空间占用的方法是把字段名尽量取短一些,这样占用 空间就小了,但这就要求在易读性与空间占用上作为权衡了。我曾建议作者把字段名作个index,每个字段名用一个字节表示,这样就不用担心字段名取多长 了。但作者的担忧也不无道理,这种索引方式需要每次查询得到结果后把索引值跟原值作一个替换,再发送到客户端,这个替换也是挺耗费时间的。现在的实现算是 拿空间来换取时间吧。
3、删除记录不释放空间:这很容易理解,为避免记录删除后的数据的大规模挪动,原记录空间不删除,只标记“已删除”即可,以后还可以重复利用。
4、可以定期运行db.repairDatabase()来整理记录,但这个过程会比较缓慢
③MongoDB没有如MySQL那样成熟的维护工具,这对于开发和IT运营都是个值得注意的地方。
应用经验缺乏,我们都没有相关NoSQL 产品的使用经验。
项目相对来说还比较新。
和以往的存储相比,数据的关系性操作不再存在。