《数据密集型应用系统设计》笔记二:第二章 数据模型与查询语言

孤人 提交于 2019-12-20 06:54:20

1.数据模型

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

1. 观察现实世界,通过构建对象或数据结构,以及操作这些数据结构的API来对其建模。
2. 采用通用数据模型,存储这些数据结构。
3. 数据库工程师决定用何种内存、磁盘或网络的字节格式来表示上述数据。
4. 更下层,硬件工程师考虑如何用电流、磁场、光脉冲等来表示字节。

基本思想相同:每层都通过提供一个简洁的数据模型来隐藏下层的复杂性。这种抽象机制使得不同的人群可以高效协作。

2.关系模型与非关系模型

关于NoSQL的介绍,与SQL的对比,没有比这个介绍更准确详细了,请参照菜鸟教程:NoSQL简介

本书中主要介绍和研究的非关系模型是:文档模型、图模型,对应的代表数据库是文档数据库(MongoDB)和图数据库(Neo4j)。

2.1 关系模型、文档模型与图模型

三个模型的总体比较如下:

特性比较 关系模型 文档模型 图模型
数据类型 高度组织化结构化数据 JSON或XML的文档型数据 图结构数据
查询语言 结构化查询语言(SQL) 非结构化查询语言(独有) 非结构化查询语言(Cypher等)
模式与联结 写时模式。数据和关系都存储在单独的表中,支持多表联结 无模式(或称作读时模式),不支持多表联结。联结的工作其实从数据库转移到了应用层,通过对数据库进行多次查询来模拟联结 无模式(或称作读时模式),不支持多表联结。联结的工作其实从数据库转移到了应用层,通过对数据库进行多次查询来模拟联结
规则 ACID,强一致性 CAP定理,弱一致性 CAP定理,弱一致性
优势 简便易学的SQL,强一致性,多表联结、多对一、多对多的表达比较简洁易懂 模式灵活性易于进行模式演变,局部性带来较好的查询性能,比较适合一对多 模型最贴近真实世界,支持百亿甚至千亿量级规模的巨型图的高效关系运算。由于图数据库模型的每个节点都直接包含一个关系列表,在定义时已经预先保存了关系,从而使得图数据库可以提供比关系型数据库高几个数量级的性能。对于复杂连接的查询,可能只有图数据库能达到响应要求。
劣势 格式要求严格,写时模式导致可扩展性太差。多表联结虽然操作简单,但是实际上是通过外键约束来实现,这种操作是“计算密集型”的,并且操作次数将是表中记录的指数级别,需要消耗大量的资源,性能太差。 查询定义语言不够标准,并且查询性能不高 需要预先定义好属性图结构,可能需要对整个图做大量计算。图遍历步数不能太深,超过三步性能就会急剧下降,这显然无法满足现实需求。

2.2 层次模型的局限与演化

层次模型:一对多,每个记录只有一个父节点。层次模型支持多对多有些困难,而且不支持联结。为了解决层次模型的局限性,提出了多种解决方案,最著名的就是:关系模型和网络模型。

网络模型:一个记录可能有多个父节点。在网络模型中,记录之间的链接不是外键,而更像是编程语言中的指针(会存储在磁盘上)。访问记录的唯一方法是选择一条始于记录的路径,并沿着相关链接依次访问。这被称为访问路径。访问路径像是遍历列表,从链表的开头,一次查看一个记录,直到找到所需的记录。由于网络模型,一个记录可能有多个父节点,则遍历非常缓慢复杂,所以性能非常差。而手动路径选择需要大量的手写数据库查询代码,更是复杂而没有灵活性,最终导致了网络模型的失败。

关系模型:相比之下,关系模型所做的就简单多了,它只定义了所有数据的格式:关系(表)知识元组(行)的集合。没有复杂的嵌套结构,也没有复杂的访问路径。在关系数据库中,查询优化器自动决定以何种顺序执行查询,以及使用哪些索引。这些选择实际上等价于“访问路径”,最大的区别在于他们是由查询优化器自动生成的,而不是由应用开发人员所维护,开发人员只需懂的SQL即可,不必了解底层实现,极大降低了学习成本。这也是最终SQL称霸数据库领域的原因。

文档数据库可以认为是某种方式的层次模型(一对多关系)。

其实在表示多对一和多对多关系时,关系数据库和文档数据库并没有根本的不同:相关项都是由唯一的标识符引用,该标识符在关系模型中被称为外键,而在文档数据库中被称为文档引用
外键标识符可以在查询时通过联结操作来解析;文档引用标识符可以在查询时通过相关后续的多次查询来解析。

2.3 文档数据库的模式灵活性与数据局部性

读时模式 VS 写时模式

文档数据库有时被称为无模式,其实更准确来说应该是“读时模式”,即数据结构是隐式的,只有在读取时才解释。读时模式类似于编程语言中的动态(运行时)类型检查。

关系数据库被称为"写时模式",模式是显式的,数据在写入时必须严格按照数据格式要求。写时模式类似于静态(编译时)类型检查。

文档数据库因为是读时模式,具有模式灵活性,可扩展性更强。

数据局部性的优缺点

优势:如果应用程序需要频繁访问整个文档或文档大部分内容,则文档数据库的数据局部性相对于关系数据库的多表联结具有性能优势,只需检索一次而无需像关系型数据库一样进行多次索引来检索所有数据。

局限性:只访问一部分时则无优势很浪费。文档更新时,通常会重写整个文档,很耗费性能。通常建议文档应该尽量小且避免写入时增加文档大小,使用原地覆盖更新。

2.4 MapReduce查询

MapReduce是一种编程模型,用于在许多机器上批量处理海量数据。一些NoSQL存储系统(如MongoDB 和CouchDB)支持有限的MapReduce方式在大量文档上执行只读查询。

MapReduce既不是声明式查询语言,也不是一个完全命令式的查询API,而是介于两者之间:查询的逻辑用代码片段来表示,而这些代码片段可以被处理框架重复地调用。

MapReduce查询有两个限制:

  1. map和reduce函数对可执行的操作有限制,必须是纯函数。不能执行额外的数据库查询,也不能有任何副作用。
  2. 可用性限制。必须编写两个函数:map和reduce函数,这两个函数必须在逻辑上密切协调,这通常比编写单个查询更难。

3. 图模型

如果数据大多是一对多关系(树结构模型),或者记录之间没有关系,那么文档模型是最合适的。
对于多对多关系,关系模型能够处理简单的多对多关系,但是真实世界的多对多关系是想当复杂的,随着数据之间的关联越来越复杂,图模型将是更加直观和有效的方法。

图数据库是专门为处理高度连接的数据而建立的。它有三个关键优势:
(1)扩展性高:图中可以显示一些传统关系模式难以表达的东西。并且图有利于演化,向应用程序添加功能时,图可以容易地扩展以适应数据结构的不断变化。
(2)性能好:对于密集的数据关系处理,图数据库将性能提升了几个数量级。在传统数据库中,随着关系的数量和深度的增加,关系查询将会停止。
(3)敏捷:使用图数据库开发完全符合当今灵活的,测试驱动的开发实践。

本书中讨论了图模型中的属性图模型(property graph,以Neo4j、Titan为代表)和三元存储模型(triple-store,以Datamic、AllegroGraph为代表)

3.1 属性图模型和Cypher查询语言

代表的就是经典的图数据库Neo4j,有兴趣的可以参考清华大学张织老师的《Neo4j权威指南》,关于Neo4j和查询语言Cypher,介绍的非常详尽。

属性图的基本概念

  1. 一个属性图是由顶点(vertex),边(edge),标签(label),关系类型(type of relation)和属性(property)组成的有向图。
  2. 顶点也被称为节点(node),边也被称为关系(relation)。在图形中,节点和关系是最重要的实体。所有节点都是独立存在的,通过标签来分组,相同标签的节点属于一个分组(集合);关系通过关系类型来分组,类型相同的关系属于同一个集合。
  3. 节点可有零个,一个或多个标签,但关系有且仅有一个关系类型。
  4. 关系是有向的,关系的两端是起始节点和结束节点,通过有向的箭头来标识方向,节点之间的双向关系通过两个方向相反的关系来标识。
  5. 属性是一个键值对,每个节点或关系可以有一个或多个属性;属性值可以是标量类型或者标量类型的列表。

3.2 三元存储模型与SPARQL查询语言

三元存储模型其实就是RDF数据模型。

RDF数据模型

  1. RDF的由来。

    从语义网到RDF。
    语义网从本质上讲来源于一个简单而合理的想法:网站通常将信息以文字和图片方式发布给人类阅读。那么,为什么不考虑将信息发布为机器可读的格式给计算机阅读呢? ————资源描述框架(Resource Description Eramework ,RDF)就是这样一种机制,它让不同网站以一致的格式发布数据,这样来自不同网站的数据自动合并成一个数据网络,一种互联网级别的包含所有数据的数据库。

  2. RDF的格式

    RDF是一个抽象的数据模型,它有很多种RDF数据序列格式:
    (1)Turtle
    (2)RDF/XML
    (3)N-Triples
    (4)RDFa
    (5)TRIG
    (6)Notation3(N3),Turtle可以认为是N3的一个子集。

  3. RDF的定义

(1)RDF使用web标识符来标志事物,并通过属性和属性值来描述资源。
(2)三元组:主、谓、客
资源(主体):是可拥有URI的任何事物。
属性(谓语):是拥有名称的资源,用来描述资源之间的关系。比如:author,homepage等,当然也可以用URI标识,这使得万维网环境下全局性的标识资源以及资源间联系成为可能。
属性值(客体):是某个属性的值——>第一种情况;是另一个资源——>第二种情况。
(3)陈述:资源、属性和属性值的组合可形成一个陈述,对应地,它们被称为陈述的主体、谓语、客体,表达成三元组结构。RDF图就是一个由RDF三元组构成的集合,RDF三元组可以看成是“节点——边——节点”的结构。这与万维网的图结构“文档——超链接——文档”相吻合。本质上,RDF图是节点和边均带有标签的有向图结构。

  1. RDF 与属性图的联系与区别
    三元存储模型(RDF)几乎等同于属性图模型,只是使用不同的名词描述了相同的思想。

联系(逻辑完全一致):RDF三元组结构,属性值第一种情况:对应属性图中顶点的定义。第二种情况:对应属性图中关系的定义。
区别(表达方法不同):RDF图和属性图定义的结构略有不同,属性图更加直观和简单。

SPARQL查询语言

SPARQL是一种采用RDF数据模型的三元存储查询语言。它比Cypher更早,并且由于Cypher的模式匹配是借用SPARQL的,两者看起来非常相似。

3.3 一阶谓词逻辑表示法与Datalog

Datalog的数据模型类似于三元存储模式,但更加通用一些,它采用一阶谓词逻辑:“谓语(主体,客体)”的表达方式而不是三元组(主体,谓语,客体)。

一阶谓词逻辑

一阶谓词逻辑表示法是一种重要的知识表示方法,它以数理逻辑为基础,是到目前为止能够表达人类思维活动规律的一种最精准形式语言。它与人类的自然语言比较接近,又可方便存储到计算机中去,并被计算机进行精确处理。因此,它是一种最早应用于人工智能中的表示方法。

Prolog语言

Prolog语言是以一阶谓词逻辑为理论基础的逻辑程序设计语言,是人工智能程序设计语言族中应用最广泛的一种。Prolog的基本语句有三种:事实,规则,目标。

事实:用来说明一个问题中已知的对象和它们之间的关系,如:儿子(王健林,王思聪),表明王健林的儿子是王思聪。
规则:用来描述事实之间的依赖关系,如:bird(x):——animal(x), has (x,feather),表示凡是动物且有羽毛的都是鸟。
目标:向Prolog询问的问题就是程序运行的目标,如:?——student(lucy)表示lucy是学生吗?

Datalog其实是Prolog的子集。

3.4 图数据库与网络模型的比较

特性比较 图数据库 网络模型
模式 无模式(读时模式) 写时模式
查询方法 既可以通过顶点的唯一ID直接引用,也可以使用索引查找 唯一方法是遍历访问路径
查询语言 声明式 命令式
记录方法 顶点和边不是有序的 记录是有序集合,数据库必须保持这种排序(很麻烦)
数据结构 属性图(顶点——边——顶点) 父节点——子节点

由对比可见,图数据库的网络模型从数据结构就决定了其根本不同,两者不可混为一谈。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!