本文来自去年整理发布的“十天掌握MongoDB”系列PPT,该系列PPT的内容来源于当时的《MongoDB权威指南(英文版)》。个人翻译能力有限,不能保证PPT的内容完全符合该书的内容。此外,我还加入了大量的自己的看法。今天分享给大家的是其中的第十课,主要是我个人当时的观点,这些观点在现在看来不一定都是正确的,请大家多多批评指正!

对NoSQL的理解

NoSQL并不是No-SQL,而是指Not Only SQL。NoSQL的出现是为了弥补SQL数据库因为事务等机制带来的对海量数据、高并发请求的处理性能上的欠缺。NoSQL不是为了替代SQL而出现的,它是一种替补方案,而不是解决方案的首选。绝大多数的NoSQL产品都是基于大内存和高性能随机读写的(比如具有更高性能的固态硬盘阵列),一般的小型企业在选择NoSQL时一定要慎重!不要为了NoSQL而NoSQL,可能会导致花了冤枉钱又耽搁了项目进程。NoSQL不是万能的,但在大型项目中,你往往需要它!

为什么是MongoDB?

MongoDB基于BSON,兼容JSON。它有广泛的驱动支持,高性能、开源、面向文档。此外,MongoDB还具有全文索引支持、自动复制分片、内置分布式文件系统以及内置MapReduce支持等特点。

不要被老陈骗了,我只是想罗列一下MongoDB的优点。如果想了解其他NoSQL产品,不妨查看这个网址:http://cloud.csdn.net/a/20110610/299526.html。

文档结构设计

在SQL时代,我们可以任意设计自己的表结构,仅仅需要注意数据类型的选择,只是无法直接使用树形设计而已。然而,在MongoDB中就没这么幸运了。MongoDB内置的查询机制非常有限,它无法让你的原来的设计那么轻松地就能迁移过来。

其实,MongoDB这样的“不给力”都是“故意”的!通过核心算法的约束,强迫开发者大量地使用冗余数据来提升计算效率。这个做法,好!也不好!好的是,的确可以解决很多问题;不好的是,因此我们需要改变之前一贯的思路,甚至是之前认为非常一般般的做法,还会给维护带来很多“看起来不必要”的麻烦。

MongoDB宣称自己占用的处理器资源是很低的——其实是因为它的架构就直接绕开了很多运算!

在这里,我想分享一些关于MongoDB的优化建议:

1. 不要吝啬存储空间,充分利用冗余数据的优点。

2. 索引和查询优化:在MongoDB中,传统的SQL优化技巧同样适用。不要为所有键都创建索引,也不要一个索引也不用。如果需要,请优先考虑复合索引,但请注意键的顺序。如果发现即使创建索引也无法有效提升性能,此时应该考虑将数据分片。设计查询时,应将能够过滤掉大量记录的条件放在前面,除非这样的改动影响了业务需求。尽量避免在数据库端处理各种排序,以提升数据库服务器的吞吐量。

3. 复制、分片和副本集:复制是将数据完整复制到其他MongoDB实例上;分片是将一块数据分成很多小块并分发到不同的集合或MongoDB实例;副本集具有故障转移特性。在生产环境中,我们应当混合使用这三个概念,并发挥到极致。数据安全、运算效率以及负载分流、故障转移等特性都需要做得很强壮。一个强壮的MongoDB集群可能需要至少十几台服务器,光硬件就是不小的投入。

4. 数据安全:不要迷信任何设备,应当经常备份重要的业务数据。使用复制可以对MongoDB的数据执行热备份,而不需要停掉主数据库引擎。

5. 其他建议:尽量少用嵌套文档,它会让你的数据库膨胀得非常快,且不利于扩展。MongoDB不适合存储高精度的数字,如财务数据等。MongoDB没有内联查询机制,全靠手工外键;没有自增标识,未来的规划中也没有迹象表明要支持。实际上,这是MongoDB故意的!我们建议使用随机标识,而不是递增标识。

总之,NoSQL并非人人都能驾驭,也不是人人都能玩得转的。一个强大的MongoDB集群可能需要至少十几台服务器,光硬件投入就不小。因此,在实际应用中,我们需要充分了解MongoDB的特点和优势,结合业务需求进行合理配置和优化,以提高系统性能和稳定性。