0%

数据模型与查询语言

关系模型与文档模型

支持文档数据模型的主要论点是模式灵活,对于某些应用来说,它更接近与应用程序所使用的数据结构。关系模型则强在联结操作、多对一和多对多关系更简介的表达上,与文档模型抗衡。

文档数据库在处理一对多的关系有很大优势,可以直接把记录记在一个文档中,但是在处理多对一,多对多的关系时相比于关系数据库则稍逊一些,因为在多对一、多对多的查询下,通常需要联结(join)多张数据库来查询,而一般文档数据库对联结操作的支持很差。有些文档数据库甚至本身都不支持联结,必须在应用程序代码中,通过对数据的多次查询来模拟联结。

如果应用数据具有类似文档的结构(即一对多关系,通常一次加载整个树),那么使用文档数据库更为合适。但是如果应用程序中经常使用多对多关系,那么关系系数据库是一个很好的选择。通常,我们无法一概而论那种数据模型的应用代码更简单。这主要取决于数据项之间的关系模型。有时候使用文档模型是最合适的,有时候用关系模型会更好,有些时候还可以使用图模型。

对象关系不匹配

目前大多数应用开发都采用面向对象的编程语言,如果数据存储在关系表中,那么应用层代码中的对象与表、行和列的数据库模型之间需要一个笨拙的转换层。一般在开发中会使用对象-关系映射(ORM)框架来减少此层转换之间的代码量,但是ORM框架并不能完全隐藏两个模型之间的差异。

文档数据库的数据局部性

文档通常存储编码为JSON、XML或其二进制变体(如MongoDB的BSON)的连续字符串。如果应用程序需要频繁访问整个文档,则存储局部性具有性能优势。局部性优势仅适用需要同时访问文档的大部分内容的场景,,如果应用只是访问其中的一小部分,那对于大型文档数据来讲就有些浪费。对文档进行更新时,通常会重写整个文档,而只有修改量不改变原文档大小时,原地覆盖更新才更有效。因此,通常建议文档应该尽量小且避免写入时增加文档大小。这些性能方面的不利因此大大限制了文档数据库的适用场景。

数据查询语言

在关系模型被提出的最初时期,就出现两总查询数据的方法:声明式查询和命令式查询。命令式查询需要告诉计算机如何以特定的顺序来执行查询操作,一次查询基本上对应一段查询代码。而对于声明式查询语言(如SQL或关系代数),则只需要指定所需的数据模式,结果需满足什么条件,以及如何转换数据(例如,排序、分组和聚合),而不需要指明如何实现这一目标。数据库系统的查询优化器会决定采用那种索引和联结,以及用何种顺序来执行查询的各个语句。另外声明式查询语言对外隐藏了数据引擎的很多实现细节,这样数据库能够在不改变查询语句的情况下提高性能。

MapReduce

MapReduce是一种编程模型,用于在许多机器上批量处理海量数据。MapReduce既不是声明式查询语言,也不是一个完全命令式的查询API,而是介于两者之间:查询的逻辑用代码片段表示,这些代码片段可以被处理框架重复地调用。它主要基于许多函数式编程中的map和reduce函数,map函数用于对每一条数据进行过滤筛选,reduce用于对过滤出来的记录进行相关操作。不同数据库对MapReduce的执行实现都不同。

图数据模型

在处理多对多关系时,关系模型能够处理简单的多对多关系,但是随着数据之间的关联越来越复杂,将数据建模转换为图模型会更加自然

图由两种对象组成:顶点(也称为实体)和边(也称为关系),很多著名的算法都可以在图数据上运行,例如PageRank算法。

图的不同顶点存储的数据可以是相同类型对象,也可以是不同类型对象,同理对于边来说,不同边可以表示相同的关系,也可以表示不同的关系。这就是图数据模型强大的地方。

例如,Facebook维护了一个包含许多不同类型的顶点与边的大图:顶点包括人、地点、事件、签到和用户的评论;边表示哪些人是彼此的朋友,签到发生在哪些位置,谁评论了哪个帖子,谁参与了哪个事件等

属性图

在属性图模型中,每个顶点包括:

  • 唯一的标识符
  • 出边的集合
  • 入边的集合
  • 属性的集合(键-值对)

每个边包括

  • 唯一的标识符
  • 边开始的节点
  • 边结束的节点
  • 描述两个顶点间关系的标签
  • 属性的集合(键-值对)

// TODO: 在实际使用了图数据之后在补充一下,目前只做基础了解,知道哪些场景适用图模型即可。

小结

文档模型、关系模型和图模型如今都有广泛的应用,而且在各自的目标领域都足够优秀。我们观察到,一个模型可以用另外一个模型来模拟,但是处理起来很笨拙。这就是为什么不同的系统用于不同的目的,而不是一个万能的解决方法。

文档数据库和图数据库有一个共同点,那就是它们通常不会对存储的数据强加某个模式,这可以使应用程序更容易适应不断变化的需求。但是,应用程序很可能仍然假定数据具有一定的结构,之过失模式是显示(写时强制)还是隐式(读时处理)的问题。

对于每个数据模型,都有自己的查询语言或框架。