如果一个 Document 需要经常被访问,而其中的一个内嵌 Document 很少被访问到,这时不太适合使用内嵌;因为这会使 MongoDB 在检索数据时增加内存的消耗。
如果一个 Document 中的一个内嵌 Document 需要经常修改,或者大小经常发生变化,而另一个内嵌 Document 相对静态,这是也不要考虑使用内嵌结构。
由于内嵌 Document 的增加和减少会导致整个 Document 大小发生变化,当变化超过了分配给 Document 的磁盘空间时会导致数据库从新为 Document 分配空间。
引用除了内嵌之外还可以使用引用的方式来关联数据。引用的方式和关系型数据库表的主外键很想。你可以把主表和外键表分别存储成一个 Collection,然后用他们的_id进行关联,_id是 MongoDB 文档中一个比较特殊的字段,他会被 MongoDB 自动生成并且唯一存在在一个 Collection 中。但是,在使用引用的时候需要注意一下几点:
在一些复杂的多对多关系表中,不要尝试引用,因为这会加���应用程序逻辑上的开发和维护。
当使用内嵌结构产生过多重复数据的时候,可以考虑使用引用。
虽然 MongoDB 不支持 JOIN 操作,但是可以通过 Aggregation 中的$lookup指令来完成连接多表的操作请求。
应用集成有了数据模型的定义,我们就可以开始进行应用集成。集成的方法可以使用 MongoDB 的 Driver,它支持了几乎常用的各种计算机语言。使用简单和开发效率高是 MongoDB 的两大特点。于 SQL 语句不同的是,MongoDB 采用了 API 的方法提供接口,开发人员可以选择支持自己熟悉语言的 Driver,DBA 可以直接使用 Mongo Shell 脚本。幸运的是,MongoDB 提供了 API 和 SQL 语句的对照表供大家参考,SQL to MongoDB Mapping Chart。
另一个强大的功能不能不提的是 Aggregation Framework(聚合)。并不是所有 NoSQL 数据库都支持 Aggregation,简单理解 Aggregation 可以把它当成是 Hadoop 里面的 Map Reduce,或者 SQL 里面的 Left Join。在没有 Aggregation 的情况下,开发人员进行数据迁移不得不进行如下操作:
在应用程序层开发类似 Aggregation 的功能,将数据聚合在一起并写进数据库。这样做加大了应用程序的复杂度,并且很难适应各种不同数据的组合情况。没遇到一个新的需求都需要进行一定量的开发工作。
有些人会把数据到如今 Hadoop,然后在上面运行 MapReduce 生成结果,之后将结果倒进 NoSQL 中。这是一个折中的方法,但是他并不支持实时数据迁移,只能进行线下操作。
MongoDB 支持原生 Aggregation 操作,你可以把需要迁移的数据进行聚合操作,每一次操作可以想象成一个流水线上的环节,将所有的操作连接起来可以构成一条 Aggregation Pipeline。在 Pipeline 上面的每一个节点都有自己的输入输出,前一个节点的输出是下一个节点的输入。有兴趣的同学可以在这个连接上找到更多的关于 Aggregation 操作,它列出了每一个 Aggregation 命令和 SQL 语句的对应关系,SQL to Aggregation Mapping Chart
数据完整性在关系型数据库中,有很多支持 ACID 事务操作的方法和应用,DBA 并不希望在数据迁移的过程中有任何闪失,例如损失数据完整性。MongoDB 在这方面具有不同形式的支持。在 3.0 以上版本中,MongoDB 支持了 WiredTiger Storage Engine,他支持了 Document 级别上的锁操作。也就是说,在进行数据库写操作时,MongoDB 可以保证针对一个 Document 操作的原子性,这个操作可以和其他操作完全分隔开来。除了对单个 Dcoument 的原子操作支持外,MongoDB 还支持多 Document 的事务,比如,findAndModify方法允许你在进行多个文档操作的时保持事务完整。再比如,可以通过Perform Two Phase Commits实现更新多个文档的原子操作,更多信息请访问 Perform Two Phase Commits。
数据一致性在数据一致性方面,MongoDB 通过 Read Preference 来调节一致性的程度。默认情况下,在一个 MongoDB Replica Set 中,所有的数据库读操作都会发到 Primary 服务器上,Replica Set 中的所有 Secondary 保证数据最终一致性。同时,MongoDB 提供了修改这种一致性的行为方式。数据库管理员可以通过修改 Read Preference 参数达到对一致性不同要求的场景。数据一致性可以有下面集中方案:
primary: 默认模式,所有请求都会发送到 Primary 上。
primaryPreferred:大部分读请求都会发送到 Primary,但是当 Primary 无法访问时,改请求会被转发到 Secondary 上。
secondary: 所有请求都会发送到 Secondary 上。
secondaryPreferred: 大部分情况下,读请求被发送到 Secondary 中,但是如果 Replica 中没有 Secondary,请求会发送到 Primary 上。
nearest: 请求会被发送到网络最近的服务器上。该模式在多数据中心上非常有效。
数据迁移