第2章 数据模型与查询语言

概述

大多数应用程序是通过一层一层叠加数据模型来构建的。每一层都面临的关键问题是:如何将其用下一层来表示?

复杂的应用程序可能会有更多的中间层,例如基于API来构建上层API,但是基本思想相同:每层都通过提供一个简洁的数据模型来隐藏下层的复杂性。这些抽象机制使得不同的人群可以高效协作,例如数据厂商的工程师和使用数据库的应用程序开发人员一起合作。

关系模型与文档模型

在20世纪70年代和80年代初期,网络模型和层次模型是两个主要的选择,但最终关系模型主宰了这个领域。对象数据库曾在20世纪80年代后期和90年代初期起起伏伏。XML数据库则出现在21世纪初,但也仅限于利基市场。

关系模型的每个竞争者都曾聒噪一时,可惜无一持久。随着计算机变得越来越强大和网络化,服务目的日益多样化,关系数据库超出了它们最初的商业数据处理范围,顺利推广到了各种各样的用例(在线发布、论坛、社交网络、电子商务、游戏、saas)。

NoSQL的诞生

进人21世纪,NoSQL成为推翻关系模式主导地位的又一个竞争者。它最初只是作为一个吸引人眼球的Twitter标签频频出现在2009年的开源、分布式以及非关系数据库的见面会上。现在很多新兴的数据库系统总是会打上NoSQL的标签,而其含义也已经被逆向重新解释为“不仅仅是SQL”:

采用NoSQL数据库有以下几个驱动因素,包括:

  • 比关系数据库更好的扩展性需求,包括支持超大数据集或超高写人吞吐量。
  • 普遍偏爱免费和开源软件而不是商数据库产品。
  • 关系模型不能很好地支持一些特定的查询操作。
  • 对关系模式一些限制性感到沮丧,渴望更具动态和表达力的数据模型。

不同的应用程序有不同的需求,某个用例的最佳的技术选择未必适合另一个用例。因此,在可预见的将来,关系数据库可能仍将继续与各种非关系数据存储一起使用,这种思路有时也被称为混合持久化

对象-关系不匹配

现在大多数应用开发都采用面向对象的编程语言,由于兼容性问题,普遍对SQL数据模型存在抱怨:如果数据存储在关系表中,那么应用层代码中的对象与表、行和列的数据库模型之间需要一个笨拙的转换层。模型之间的脱离有时被称为阻抗失谐

引入关系映射(ORM)框架来解决应用层代码和数据库模型之间的转换,例如: Hibernate(Nhibernate),iBatis,mybatis,EclipseLink,JFinal。

以简历这样的数据结构为例子,介绍不同模型之间的区别:

数据的表现形式:

简历原始信息

简历关系模式表示

简历一对多树状结构(用户简历到用户的职位、教育历史和联系信息的一对多关系),也称层次模型

简历多对多关系表示:

网络模型由一个称为数据系统语言会议(Conference on Data System Languages,CODASYL)的委员会进行标准化,并由多个不同的数据库厂商实施,它也被称为 CODASYL模型。

CODASYL模型是层次模型的推广。在层次模型的树结构中,每个记录只有一个父结点;而在网络模型中,一个记录可能有多个父结点。例如,“北京地区"可能有 一个记录,居住在该地区的每个用户都链接指向它。从而支持对多对一和多对多的关系进行建模。

在20世纪70年代,尽管手动路径选择能够最有效地利用当时非常有限的硬件资源,但最大的问题在于它们使查询和更新数据库变得异常复杂而没有灵活性。无论是层次模型还是网络模型,如果脱离数据的访问路径,那么将寸步难行。它也支持改变访问路径,但随之需要大量的手写数据库查询代码,重新实现处理新的访问路径。总之,对应用程序的数据模型进行更改是一件非常困难的事情。

关系模型

在关系数据库中,查询优化器自动决定以何种顺序执行查询,以及使用哪些索引。这些选择实际上等价于“访问路径",但最大的区别在于它们是由查询优化器自动生成的,而不是由应用开发人员所维护,因此不用过多地考虑它们。

如果想用新的方式查询数据,只需声明一个新的索引,查询会自动使用最合适的索引。

关系数据库的查询优化器称得上是一个复杂的怪兽。关系模型的一个核心要点是:只需构建一次查询优化器,然后使用该数据库的所有应用程序都可以从中受益。如果没有查询优化器,那么为特定查询手动编写访问路径比编写通用优化器更容易,但从长远来看,通用解决方案更胜一筹。

关系数据库与文档数据库现状

文档数据模型:模式灵活,由于局部性而带来较好的性能。场景选择:例如应用数据具有类似文档的结构,一次加载整个树结构)。

关系模型:强在联结操作、多对一和多对多关系更简洁的表达上。场景选择:倾向于数据分解,将文档拆分成多个表(职位、教育、联结)。

注意事项:

  • 大多数关系数据库系统可以在几毫秒内执行ALTER TABLE语句。MySQL则需要注意,它执行ALTER TABLE时会把现在的整张表复制,因而当表很大时可能会需要几分钟甚至几小时的停机时间。

数据查询语言

  • 声明式查询语言:SQL

    • 适合于并行执行
  • 命令式查询语言:IMS和CODASYL

    • 指定特定的执行顺序

Web上的声明式查询

对于web浏览器的例子,使用声明式css样式表比用JavaScript命令式地操作样式好得多。类似地,在数据库中,像SQL这样的声明式查询语言比命令式查询APIs要好得多。

MapReduce查询

MapReduce是面向大数据并行处理的计算模型、框架和平台,它隐含了以下三层含义:

  1. MapReduce是一个基于集群的高性能并行计算平台。

  2. MapReduce是一个并行计算与运行软件框架。它提供了一个庞大但设计精良的并行计算软件框架,能自动完成计算任务的并行化处理,自动划分计算数据和计算任务,在集群节点上自动分配和执行任务以及收集计算结果,将数据分布存储、数据通信、容错处理等并行计算涉及到的很多系统底层的复杂细节交由系统负责处理,大大减少了软件开发人员的负担。

  3. MapReduce是一个并行程序设计模型与方法。它借助于函数式程序设计语言Lisp的设计思想,提供了一种简便的并行程序设计方法,用Map和Reduce两个函数编程实现基本的并行计算任务,提供了抽象的操作和并行编程接口,以简单方便地完成大规模数据的编程和计算处理。

总结:MapReduce是一个基于集群的计算平台,是一个简化分布式编程的计算框架,是一个将分布式计算抽象为Map和Reduce两个阶段的编程模型。核心思想:分而治之。

MapReduce计算模型

MapReduce计算模型主要由三个阶段构成:Map、shuffle、Reduce。

Map是映射,负责数据的过滤分法,将原始数据转化为键值对;Reduce是合并,将具有相同key值的value进行处理后再输出新的键值对作为最终结果。为了让Reduce可以并行处理Map的结果,必须对Map的输出进行一定的排序与分割,然后再交给对应的Reduce,而这个将Map输出进行进一步整理并交给Reduce的过程就是Shuffle。整个MR的大致过程如下:

详细内容参见: MapReduce原理 (opens new window)

图状数据模型

随着数据之间的关联越来越复杂,将数据建模转化为图模型会更加自然。

图由两种对象组成:顶点(也称为结点或实体)和边(也称为关系或弧)。很多数据可以建模为图。典型的例子包括:

  • 社交网络
    • 顶点是人,边指示哪些人彼此认识。
  • web图
    • 顶点是网页,边表示与其他页面的HTML链接。
  • 公路或铁路网
    • 顶点是交叉路口,边表示他们之间的公路或铁路线。

图结构数据的例子: