数据密集型系统设计(2)

 

  • 第二章--数据模型与查询语言

    • 关系模型文档模型

      • 概览

        • SQL:数据被组织成关系(relations),在SQL中称为表(table),其中每个关系都是元组(tuples)的无序集合(在SQL中称为行)

        • 网络模型和层次模型

        • XML数据库

      • NoSQL:“不仅仅是SQL”。混合持久化:关系数据库和非关系数据存储一起使用

        • 比关系数据库更好的扩展性需求

        • 免费开源

        • 关系模型不能很好的支持一些特定的查询操作

        • 对关系模式一些限制性感到沮丧,渴望更具动态和表达力的数据模型

      • 对象-关系不匹配

        • 数据存储在关系表中,那么应用层代码中的对象和表、行和列的数据库模型之间需要一个笨拙的转换层。模型之间的脱离有时被称为阻抗失谐。ActiveRecord和Hibernate这样的对象-关系映射(ORM)框架减少了此转换层所需要的样板代码量。

        • 自包含的文档(document),使用面向文档的数据库,相比多表SQL具有更好的局部性。

      • 多对一和多对多的关系

        • 使用id的好处:即使ID标识的信息发生了变化,它也可以保持不变。任何对人类有意义的东西都可能在将来某个时刻发生变更。如果这些信息被复制,那么所有的冗余副本也都需要更新。这会导致更多写入开销,并且存在数据不一致的风险(信息的一些副本被更新,而其他副本未更新)。消除这种重复正是数据库规范化的核心思想。

        • 数据规范化需要表达多对一的关系,不很适合文档模型。需要在程序代码中,通过对数据库进行多次查询来模拟联结。而关系数据库支持联结操作,可以很方便的通过id来引用其他表中的行

        • 补充:RethinkDB支持联结,MongoDB不支持联结,CouchDB只有预先声明的视图支持联结(写书的时间)

      • 文档数据库是否在重演历史

        • 概览

          • 层次模型:将所有数据表示为嵌套在记录中的记录(树)

            • 优点:和文档数据库类似,IMS(Information Management System)可以很好地支持一对多关系

            • 局限:支持多对多关系有些困难,不支持联结,开发人员必须决定是复制(反规范化)多芬数据,还是手动解析记录之间的引用

          • 为了解决层次模型的局限性,提出了关系模型(relational model,后来演变成SQL,被广泛接受)和网络模型(network model,最初有很多拥趸,最终被人们遗忘)

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

          • 层次模型中一个记录只有一个父结点,而网络模型中一个记录可能有多个父结点

          • 网络模型中,记录之间链接不是外键,更像指针(存储在磁盘上)。访问记录的唯一方法是选择一条始于跟记录的路径,并沿着相关链接依次访问。这条链接链条也因此被称为访问路径。最简单的情况下访问路径像是遍历链表。但是由于多对多关系,存在多条不同的路径通向相同的记录,会像是在一个n维数据空间中进行遍历。

        • 关系模型:定义所有数据的格式:关系(表)只是元组(行)的集合。

          • 查询优化器自动决定以何种顺序执行查询,以及使用哪些索引,不需要由开发人员维护

        • 文档数据库的比较

          • 文档数据库是某种方式的层次模型:即在其父记录中保存了嵌套记录(一对多关系),而不是存储在单独的表中

          • 在表示多对一和多对多的关系时,关系数据库和文档数据库并没有根本的不同:相关项都由唯一的标志符引用,该标识符在关系模型中被称为外键,在文档模型中被称为文档引用。标志符可以通过联结操作(数据服务器中)或相关后续查询来解析(应用程序中)

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

        • 概览

          • 文档数据模型的主要优点是模式灵活性(读时隐性),由于局部性而带来较好的性能,对于某些应用来说,它更接近于应用程序所使用的结构

          • 关系模型则强在联结操作、多对一和多对多关系更简洁的表达上

        • 哪种数据模型的应用代码更简单:应用数据有类似文档结构则文档模型;关系模型倾向于数据分解,可胜任高度联结数据;图模型对于高度联结数据最为自然

      • 文档模式中的模式灵活性

        • 文档数据库:读时模式(数据的结构是隐式的,只有在读取时才解释)

        • 关系数据库:写时模式(模式显式,数据库确保数据写入时必须遵循)

      • 查询的数据局部性

        • 局部性优势仅适用于同时访问文档大部分内容场景

        • 将相关数据归位一组的局部性想法并不仅见于文档模型。eg.Google的Spanner数据库在关系数据模型中提供了相同的局部性,支持模式声明某些表的行应该在父表内交错(嵌套)。Oracle支持类似的操作,称为"多表索引集群表"特性,Bigtable数据模型(用于Cassandra和HBase)中的列族概念类似

      • 文档数据库与关系数据库的融合

        • 融合关系与文档模型是未来数据库发展的一条很好的途径

    • 数据查询语言

      • 概览

        • 声明式查询语言:SQL

        • 命令式查询语言:IMS、CODASYL

        • 声明式语言适合于并行执行。现在CPU主要通过增加核,而不是通过比之前更高的时钟频率来提升速度。而命令式代码由于指定了特定的执行顺序,很难在多核和多台机器上并行化。声明式语言则对于并行执行更为友好,他们仅指定了结果所满足的模式。

      • Web上的声明式查询(例子)

      • MapReduce查询

        • MapReduce是一种编程模型,用于在许多机器上批量处理海量数据,兴起于Google

        • MapReduce既不是声明式查询语言,也不是一个完全命令式的查询API,而是介于两者之间:查询的逻辑用代码片段来表示,这些代码片段可以被处理框架重复的调用。它主要基于许多函数式编程语言中的map(也称为collect)和reduce(也称为fold或inject)函数

        • 例子,MongoDB

          db.observations.mapReduce(
          function map(){
          var year = this.observationTimestamp.getFullYear();
          var month = this.observationTimestamp.getMonth() + 1;
          emit(year + "-" + month, this.numAnimals);
           },
           function reduce(key, values) {
          return Array.sum(values);
           },
           {
          query: {family: "Sharks"},
          out: "monthlySharkReport"
           }
          );

          每个文档都会调用map函数,从而产生emit(键值对,键相同)。随后,reduce函数将被调用。最终返回会经过一个过滤器匹配而返回最后结果

        • SQL:MapReduce操作pipeline实现

        • MongoDB V2.2:聚合管道

    • 图状数据模型

      • 概览

        • 多对多关系是不同数据模型之间的重要区别特种。如果数据大多是一对多关系(树结构模型)或者记录之间没有关系,那么文档模型是最合适的。关系模型能够处理简单的多对多关系,但是随着数据关联越来越复杂,将数据建模转化为图模型会更加自然

        • 图由两种对象组成:顶点(也称为结点或实体)和边(也称为关系或弧)

        • 属性图模型:property graph,以Neo4j、Titan和InfiniteGraph为代表

        • 三元存储模型:triple-store,以Datomic、AllegroGraph等为代表

        • 三种声明式查询语言:Cypher、SPARQL和Datalog

        • 命令式图查询语言:Gremlin

        • 图处理框架:Pregel

      • 属性图

        • 顶点

          • 唯一的标识符

          • 出边的集合

          • 入边的集合

          • 属性的集合(键-值对)

          • 唯一的标志符

          • 边开始的顶点(尾部顶点)

          • 边结束的顶点(头部顶点)

          • 描述两个顶点间关系类型的标签

          • 属性的集合(键-值对)

      • C ypher查询语言

        • Cypher是一种用于属性图的声明式查询语言,最早为Neo4j图形数据库而创建

          MATCH
          (person) -[:BORN_IN]-> () -[:WITHIN*0..]-> (us:Location {name:'United States'}),
          (person) -[:LIVES_IN]-> () -[:WITHIN*0..]-> (eu:Location {name:'Europe'})
          RETURN person.name
      • SQL中的图查询:需采用递归,且需要分成多个SQL才能得到如上的结果

      • 三元存储与SPARQL:

        • 概览

          • 三元存储模式几乎等同于属性图模型,只是使用不同的名词描述了相同的思想

          • 在三元存储中,所有信息都以非常简单的三部分形式存储(主体,谓语,客体).eg. (吉姆,喜欢, 香蕉)

          • 三元组的主体相当于图中的顶点。而客体则是以下两种之一

            • 原始数据类型中的值。在这种情况下,三元组的谓语和客体分别相当于主体(顶点)属性中的键和值

            • 图中的另一个顶点。eg.(lucy, marriedTo, alain)

          • Turtlel可以认为是Notation3(N3)的一个子集

            @prefix : <urn:example:>.
            _:lucy  a :Person; :name  "lucy";               :bornIn _:idaho.
            _:idaho a :Location; :name "Idaho";             :type "state";  :within _:usa.
            _:usa a :Location; :name "United States";     :type "Country"; :within _:namerica.
            _:namerica a :Location; :name "North America"; :type "Continent".
        • 语义网

          • 三元存储数据模型其实完全独立于语义网。例如,Datomic是一个三元存储,它与语义网没有任何关系

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

        • RDF数据模型

          <rdf:RDF xmlns="urn:example:"
             xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
           <Location rdf:nodeID="idaho"
             <name>Idaho</name>
          <type>state</type>
          <within>
          <Location rdf:nodeID="usa"
                 <name>United States</name>
                 <type>country</type>
                 <within>
                   <Location rdf:nodeID="namerica"
                     <name>North America</name>
                     <type>continent</type>
          </Location>
          </within>
          </Location>
          </within>
          </Location>

           <Person rdf:nodeID="lucy">
               <name>Lucy</name>
               <bornIn rdf:nodeID="idaho"/>
           </Person>
          </rdf:RDF>
        • SPARQL查询语言

          • SPARQL是一种采用RDF数据模型的三环存储查询语言,名字是SPARQL Protocol And RDF Query Language的缩写。它比Cypher更早,并且由于Cypher的模式匹配是借用SPARQL的,所以二者看起来非常相似

            PREFIX : <urn:example:>

            SELECT ?personName WHERE {
            ?person :name ?personName.
            ?person :bornIn / :within* / :name "United States".
            ?person :livesIn / :within* / :name "Europe".
            }

            /** ----------- **/
            (person) -[:BORN_IN]-> () -[:WITHIN*0..]-> (location) #Cypher
            ?person :bornIn / :within* ?location. #SPARQL
          • 图数据库和网络模型的比较(图数据库完胜)

      • Datalog基础

        • Datalog是比SPARQL或Cypher更为古老的语言

        • Datamic系统的查询语言采用了Datalog,Cascalog是用于查询Hadoop大数据集的Datalog实现

        • Datalog的数据模型类似于三元存储模式,但更为通用一些。它采用“谓语(主体,客体)”的表达方式

        • 有点像是面向过程编程的思路,三元组(主语,谓语,客体)则更像是面向对象编程的思路

          within_recursive(Location, Name) :- name(Location, Name). /* 规则 1 */

          within_recursive(Location, Name) :- within(Location, Via), /* 规则 2 */
          within_recursive(Via, Name).
           
          migrated(Name, BornIn, LivingIn) :- name(Person, Name), /* 规则 3*/
          born_in(Person, BornLoc),
          within_recursive(BornLoc, BornIn),
          lives_in(Person, LivingLoc),
          within_recursive(LivingLoc, LivingIn).

          ?- migrated(who, 'United States', 'Europe').
          /* Who = 'Lucy'. */
posted @ 2022-03-28 00:56  orangeScc  阅读(237)  评论(0编辑  收藏  举报