范示化

数据表示的方式有很多种,其中最重要的问题之一就是在多大程度上对数据进行范式化。
mongoDB.jpg

范式化(normalization)是将数据分散到多个不同的集合,不同集合之间可以相互引用数据。虽然很多文档可以引用某一块数据,但是这块数据只存储在一个集合中。所以,如果要修改这块数据,只需修改保存这块数据的那一个文档就行了。但是,MongoDB没有提供连接(join)工具,所以在不同集合之间执行连接查询需要进行多次查询。

反范式化(denormalization)与范式化相反:将每个文档所需的数据都嵌入在文档内部。每个文档都拥有自己的数据副本,而不是所有文档共同引用同一个数据副本。这意味着,如果信息发生了变化,那么所有相关文档都需要进行更新,但是在执行查询时,只需要一次查询,就可以得到所有数据。

决定何时采用范式化何时采用反范式化时比较困难的。范式化能够提高数据写入速度,反范式化能够提高数据读取速度。需要根据自己应用程序的使用场景进行权衡。

教科书上介绍范式化的一个例子可能是将用户和用户地址保存在不同的集合中。但是,人们几乎不会改变住址,所以不应该为了这种概率极小的情况(某人改变了住址)而牺牲每一次查询的效率。在这种情况下,应该将地址内嵌在用户文档中。

基数

一个集合中包含的对其他集合的引用数量叫做基数(cardinality)。常见的关系有一对一、一对多、多对多。假如有一个博客应用程序。每篇博客文章(post)都有一个标题(title),这是一个对一个的关系。每个作者(author)可以有多篇文章,这是一个对多的关系。每篇文章可以有多个标签(tag),每个标签可以在多篇文章中使用,所以这是一个多对多的关系。

在MongoDB中,many(多)可以被分拆为两个子分类:many(多)和few(少)。假如,作者和文章之间可能是一对少的关系:每个作者只发表了为数不多的几篇文章。博客文章和标签可能是多对少的关系:文章数量实际上很可能比标签数量多。博客文章和评论之间是一对多的关系:每篇文章可以拥有很多条评论。

只要确定了少与多的关系,就可以比较容易地在内嵌数据和引用数据之间进行权衡。通常来说,“少”的关系使用内嵌的方式会比较好,“多”的关系使用引用的方式比较好。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

BFC原理及其应用 上一篇
利用跨域资源共享CORS解决跨域问题 下一篇