脚本宝典收集整理的这篇文章主要介绍了数据密集型系统设计(2),脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
第二章--数据模型与查询语言
关系模型
和文档模型
概览
NoSQL:“不仅仅是SQL”。混合持久化:关系数据库和非关系数据存储一起使用
比关系数据库更好的扩展性需求
免费开源
关系模型不能很好的支持一些特定的查询操作
对关系模式一些限制性感到沮丧,渴望更具动态和表达力的数据模型
对象-关系不匹配
数据存储在关系表中,那么应用层代码中的对象和表、行和列的数据库模型之间需要一个笨拙的转换层。模型之间的脱离有时被称为阻抗失谐。ActiveRecord和Hibernate这样的对象-关系映射(ORM)框架减少了此转换层所需要的样板代码量。
自包含的文档(document),使用面向文档的数据库,相比多表SQL具有更好的局部性。
多对一和多对多的关系
文档数据库是否在重演历史
概览
网络模型:网络模型由一个被称为数据系统语言会议(Conference on Data System Languages,CODASYL)的委员会进行标准化,并由多个不同的数据库厂商实施,它也被称为CODASYL模型。
关系模型:定义所有数据的格式:关系(表)只是元组(行)的集合。
查询优化器自动决定以何种顺序执行查询,以及使用哪些索引,不需要由开发人员维护
文档数据库的比较
文档数据库是某种方式的层次模型:即在其父记录中保存了嵌套记录(一对多关系),而不是存储在单独的表中
在表示多对一和多对多的关系时,关系数据库和文档数据库并没有根本的不同:相关项都由唯一的标志符引用,该标识符在关系模型中被称为外键
,在文档模型中被称为文档引用
。标志符可以通过联结操作(数据服务器中)或相关后续查询来解析(应用程序中)
关系数据库与文档数据库现状
概览
文档数据模型的主要优点是模式灵活性(读时隐性),由于局部性而带来较好的性能,对于某些应用来说,它更接近于应用程序所使用的结构
关系模型则强在联结操作、多对一和多对多关系更简洁的表达上
哪种数据模型的应用代码更简单:应用数据有类似文档结构则文档模型;关系模型倾向于数据分解,可胜任高度联结数据;图模型对于高度联结数据最为自然
文档模式中的模式灵活性
文档数据库:读时模式(数据的结构是隐式的,只有在读取时才解释)
关系数据库:写时模式(模式显式,数据库确保数据写入时必须遵循)
查询的数据局部性
文档数据库与关系数据库的融合
融合关系与文档模型是未来数据库发展的一条很好的途径
数据查询语言
概览
声明式查询语言: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查询语言
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".
语义网
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'. */
以上是脚本宝典为你收集整理的数据密集型系统设计(2)全部内容,希望文章能够帮你解决数据密集型系统设计(2)所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。