原文链接
By William Zola, Lead Technical Support Engineer at MongoDB
这是我们介绍MongoDB的1 vs N关系模型的最后一站。在part 1仲,我介绍了三种基本方法去模型化1 vs N关系。Part 2仲,我介绍了一些基于它们的扩张,像双向引用和去标准化。
去标准化是已更加复杂和昂贵的修改为代价,去避免一定程度的应用层面的链接(application-level joins)。只有当读比写多得多的时候,去标准化这些字段才有意义。
来!看看这些选择!
所以,回顾一下:
- 你可以嵌套,引用1这一侧,或者引用N这一侧,又或成对使用这些技术。
- 你可以把尽量多的字段放到1这一侧,或者N这一侧
实际上,去标准化给了我们很多选择: 如果有在一个关系模型中有8个候选字段可以去标准化。那么就有2 的8次方,就是1024种去标准化的方法(包括不做去标准化)。又因为有三种不同的引用方法,所以对于这个关系一共有超过3000种不同的模型化方法。
猜猜看,你现在已经被困在选择的悖论里 - 因为你是有这么多的方法去模型化一个1vsN的关系。这会使你更加难的去选择真么模型化它。
经验法则:
这里有一些经验法则让你穿过这些数不清的选择
第一: 除非有很强的理由,嵌套是一个好的选择。
第二:需要去单独访问这个实体是一个很好的理由不去选择使用嵌套。
第三:数组不应该没有边界的扩展。如果多于几百个文档在N这一侧,不要嵌套它们。如果在N这一侧有大于几千个文档,不要引用一个装载着ObjectID的数组。高基数数组也是一个很好的理由不去选择使用嵌套。
第四:不要害怕应用层面的链接:如果你正确建立了索引和使用了投影区分符的话,应用层面的链接只是比在数据库层面的链接多花极少极少的代价而已。
第五:使用去标准化的时候要考虑读写比例。对于一个大多数时候被读和极少时候被修改的字段,去标准化是一个很好的选择。但如果你把一个经常要修改的字段做去标准化,你将会发现去标准化所节省的花费会被额外的查询和修改工作的花费所淹没。
第六:在MongoDB中,怎样去模型化你的数据完全是基于你的实际的应用是以什么样的模式去使用这些数据的。你需要建造你的数据从而更加匹配你的应用去查询和修改。
奔向彩虹
当在MongoDB中模型化1vsN关系时,你会有由多种多样的选择。所以你要非常小心的去想怎么构造你的数据。下面罗列了一些你主要考虑的标准:
- 关系中的基数是多大?1 vs 少量? 中等数量? 还是海量?
- 你需要独立访问N这一侧中的对象吗?或者只需要查看它的父对象?
- 对于特定的字段,写和读的操作比例是多少?
构造数据的主要选择有:
- 对于1vs少量关系,可以使用一个数组嵌套到文档里
- 对于1vs中等数量的关系,或者N这一侧的对象需要独立出来,那就应该使用一个数组去引用。也可以在N这一侧使用父引用从而优化你使用数据的模式
- 对于1vs海量的关系,你就应该在N这一侧使用父引用了。
一旦你决定了整个数据的结构,跟着你就可以选择在一些文档中去使用去标准化。无论是吧N放到1 或者把1放到N都可以。但是请记住只有当这些字段的读操作远大元写操作的频率,而且不需要很强的数据一致性的时候才可以做去标准化。因为这会使更新去标准化了的字段变得更慢,更昂贵,而且不能使原子性的更新。
生产能力和扩张性
这就在设计你的数据库模式去满足你的应用需求时,MongoDB能提供的能力。你可以在MongoDB中结构化你的数据,从而更加容易去变化,和支持你应用最常使用的查询和更新。