数据密集型系统设计(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)的一个子集
-
-
语义网
-
三元存储数据模型其实完全独立于语义网。例如,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'. */
-
-
-
本文来自博客园,作者:orangeScc,转载请注明原文链接:https://www.cnblogs.com/ashScc/p/16065376.html