文档数据结构是数据的自然表达。我们仅仅在70年代将数据拆分为行和列来优化数据的访问。由于当时存储和计算能力的价格高昂,耗费开发者的时间将数据减少、拆散为行和列的模式是有意义的,通过范式、相互关联等范式来减少数据的重复。这一过程有一定的成本效益,故而它主导了当时的数据库思维。
很多人都把定义行、列模式视作使用数据库的必要负担。不过,在很多方面来看,关系数据库仍然需要开发者和数据结构设计者将数据结构预处理以便于数据库更好的处理。
文件备选方案 (The Document Alternative)
不过随着科技的进步,系统也不再仅仅是用作管理文档。文档逐渐以互联网的通用格式(Json格式)出现,并且出现了像MongoDB这样的能够原生支持文档格式能够将其以文档形式高效存储、查询和操作的数据库。
以一个存储“物品”的数据库为例。关系型数据库可能会将“物品”的诸如名字、描述、价格这类原始属性存放至表“things”中,然后将其他属性,如颜色、大小、制造商、质地等放入单独的表内。故而将一个“物品”的数据写入数据库会需要将其主要的属性写入“things”表,然后找到其他表中对应的属性,并将这些属性与这个“物品”建立引用、关联;如果对应的属性不存在,则还需先创建这部分数据。当查找“物品”的必要属性的时候,可以直接通过“things”表查询。而查找其所有数据的时候则需要将其所有的属性与关联表进行连接,进行多次查找,已拼凑完整的信息。并且为了加快查找速度,每张表都需要添加对应的索引。以上就是关系型数据库的方式。
换一个视角来看,像MongoDB这样的文档型数据库会将所有的这些信息保存在一个文档中。当这类数据库进行查询的拆解、解析的时候,可以在一个文档中查到相关的信息,并且也可以通过创建索引的方式来进行查询的加速。通过使用文档型数据库,你并不需要将数据从其他表中通过引用等方式进行关联(相信你也不希望这样做)。重要的是我们可以仅仅查询一个文档就获取到“物品”相关的所有信息,这些信息都完整的保存在一个”物品”表中。
从文档到对象(From Documents to Objects)
现代的软件开发过程中,通常会将事物抽象为对象结构。我们将一辆车通过其车身风格、颜色、高时速、发动机尺寸和前任车主等信息进行建模。与文档类似,这些数据通常是一组不适合分割成多个数据结构的数据。与文档相比,对象通常也是可以有与之关联的代码,这些关联通过应用程序自行维护。
就关系型数据库而言,通常会使用ORM(对象关系映射器)的镜像和 subtle smoke能力进行创建和维护。ORM会将我们在数据库中精心拆解的行和列进行融合、转换为对象。如果不使用ORM,应用开发者需要自行编写查询语句并转换为对象。ORM通过这种方式为开发者节省了很多时间,但是通常这也伴随着性能的损耗与手动的关联查询。
反观文档型数据库,不需要经过上述的数据分解过程,所以也不需要经过数据重新组合,只需要通过数据库进行文档查询并且直接通过应用服务处理对象的方式进行处理返回的结果即可。通过文档型数据库,我们在不使用ORM的情况下,只需要在程序中组织要写入的字段、调整数组、建立对应的内嵌对象,通过上述的一系列操作后,将这个对象当做一条文档写入数据库即可,简洁高效。就的数据结构的变动而言,我们仅需要在应用程序中对数据结构进行变动而不需要像传统关系型数据库那样的建立新的表、新的关联关系。
文档是数据的直观结构,可以非常好的映射并为动态对象中或者使用对象的开发语言提供服务。如果你希望进一步了解如何对你的数据结构进行文档建模,非常建议你观看我们的MongoDB数据模型设计系列文章,《[Building with Patterns](https://www.mongodb.com/blog/post/building-with-patterns-the-polymorphic-pattern)》
原文链接:https://www.mongodb.com/blog/post/five-minute-mongodb-why-documents
译者:周李洋
Teambition运维总监
MongoDB中文社区组委会成员