注:书本链接:GitHub - Vonng/ddia: 《Designing Data-Intensive Application》DDIA中文翻译
注:译者文本网站:简介 · ddia-cn
注:如有侵权,请联系删除
第二章 数据模型与查询语言
1、数据模型
(1) 、关系模型与文档模型
关系模型:现在最著名的数据模型可能是 SQL。它基于 Edgar Codd 在 1970 年提出的关系模型【1】:数据被组织成 关系(SQL 中称作 表),其中每个关系是 元组(SQL 中称作 行) 的无序集合。
不同的应用程序有不同的需求,一个用例的最佳技术选择可能不同于另一个用例的最佳技术选择。因此,在可预见的未来,关系数据库似乎可能会继续与各种非关系数据库一起使用 - 这种想法有时也被称为 混合持久化(polyglot persistence)。
(2)、对象不匹配
目前大多数应用程序开发都使用面向对象的编程语言来开发,这导致了对 SQL 数据模型的普遍批评:如果数据存储在关系表中,那么需要一个笨拙的转换层,处于应用程序代码中的对象和表,行,列的数据库模型之间。模型之间的不连贯有时被称为 阻抗不匹配(impedance mismatch)。
对象关系映射(ORM object-relational mapping)框架可以减少这个转换层所需的样板代码的数量,但是它们不能完全隐藏这两个模型之间的差异。
注:此处就是我们日常会提到的ORM,上面是产生的原因。
局部性(locality)
(3)、多对一和多对多关系
注:此处提出了一个 region_id
和 industry_id
是以 ID,而不是纯字符串 “Greater Seattle Area” 和 “Philanthropy” 的形式给出的"的问题。下面给出的理由值得思考,在实际研发过程中,确实存在该现象,身为研发需要考虑优化点。
存储 ID 还是文本字符串,这是个 副本(duplication) 问题。
使用 ID 的好处是,ID 对人类没有任何意义,因而永远不需要改变:ID 可以保持不变,即使它标识的信息发生变化。任何对人类有意义的东西都可能需要在将来某个时候改变 —— 如果这些信息被复制,所有的冗余副本都需要更新。这会导致写入开销,也存在不一致的风险(一些副本被更新了,还有些副本没有被更新)。去除此类重复是数据库 规范化(normalization) 的关键思想。
文中提出了文档模型一对多关系随着需求的怎加,数据的增加,会体现出多对多的关系,但是文档模型本身 关联 支持不好,引人思考。
(4)、文档数据库是否在重蹈覆辙
在多对多的关系和连接已常规用在关系数据库时,文档数据库和 NoSQL 重启了辩论:如何以最佳方式在数据库中表示多对多关系。那场辩论可比 NoSQL 古老得多,事实上,最早可以追溯到计算机化数据库系统。
20 世纪 70 年代最受欢迎的业务数据处理数据库是 IBM 的信息管理系统(IMS),最初是为了阿波罗太空计划的库存管理而开发的,并于 1968 年有了首次商业发布【13】。目前它仍在使用和维护,运行在 IBM 大型机的 OS/390 上【14】。
IMS 的设计中使用了一个相当简单的数据模型,称为 层次模型(hierarchical model),它与文档数据库使用的 JSON 模型有一些惊人的相似之处【2】。它将所有数据表示为嵌套在记录中的记录树,这很像 图 2-2 的 JSON 结构。
同文档数据库一样,IMS 能良好处理一对多的关系,但是很难应对多对多的关系,并且不支持连接。开发人员必须决定是否复制(非规范化)数据或手动解决从一个记录到另一个记录的引用。这些二十世纪六七十年代的问题与现在开发人员遇到的文档数据库问题非常相似【15】。
那时人们提出了各种不同的解决方案来解决层次模型的局限性。其中最突出的两个是 关系模型(relational model,它变成了 SQL,并统治了世界)和 网状模型(network model,最初很受关注,但最终变得冷门)。这两个阵营之间的 “大辩论” 在 70 年代持续了很久时间【2】。
在表示多对一和多对多的关系时,关系数据库和文档数据库并没有根本的不同:在这两种情况下,相关项目都被一个唯一的标识符引用,这个标识符在关系模型中被称为 外键,在文档模型中称为 文档引用。
(5)、关系型数据库与文档数据库在今日的对比
- 哪种数据模型更有助于简化应用代码?
支持文档数据模型的主要论据是架构灵活性,因局部性而拥有更好的性能,以及对于某些应用程序而言更接近于应用程序使用的数据结构。关系模型通过为连接提供更好的支持以及支持多对一和多对多的关系来反击。
我们没有办法说哪种数据模型更有助于简化应用代码,因为它取决于数据项之间的关系种类。对高度关联的数据而言,文档模型是极其糟糕的,关系模型是可以接受的,而选用图形模型是最自然的。
- 文档模型中的模式灵活性
文档数据库有时称为 无模式(schemaless),但这具有误导性,因为读取数据的代码通常假定某种结构 —— 即存在隐式模式,但不由数据库强制执行【20】。一个更精确的术语是 读时模式(即 schema-on-read,数据的结构是隐含的,只有在数据被读取时才被解释),相应的是 写时模式(即 schema-on-write,传统的关系数据库方法中,模式明确,且数据库确保所有的数据都符合其模式)
- 查询的数据局部性
如果应用程序经常需要访问整个文档(例如,将其渲染至网页),那么存储局部性会带来性能优势。
局部性仅仅适用于同时需要文档绝大部分内容的情况。即使只访问文档其中的一小部分,数据库通常需要加载整个文档,对于大型文档来说这种加载行为是很浪费的。
为了局部性而分组集合相关数据的想法并不局限于文档模型。例如,Google 的 Spanner 数据库在关系数据模型中提供了同样的局部性属性,允许模式声明一个表的行应该交错(嵌套)在父表内。Oracle 类似地允许使用一个称为 多表索引集群表(multi-table index cluster tables) 的类似特性。Bigtable 数据模型(用于 Cassandra 和 HBase)中的 列族(column-family) 概念与管理局部性的目的类似。
- 文档和关系数据库的融合
随着时间的推移,关系数据库和文档数据库似乎变得越来越相似,这是一件好事:数据模型相互补充 ,如果一个数据库能够处理类似文档的数据,并能够对其执行关系查询,那么应用程序就可以使用最符合其需求的功能组合。
2、数据查询语言
SQL 是一种 声明式 查询语言,而 IMS 和 CODASYL 使用 命令式 代码来查询数据库。
3、图数据模型
一个图由两种对象组成:顶点(vertices,也称为 节点,即 nodes,或 实体,即 entities),和 边(edges,也称为 关系,即 relationships,或 弧,即 arcs)。多种数据可以被建模为一个图形。
(1)、属性图
在属性图模型中,每个顶点(vertex)包括:
唯一的标识符
一组出边(outgoing edges)
一组入边(ingoing edges)
一组属性(键值对)
每条边(edge)包括:
唯一标识符
边的起点(尾部顶点,即 tail vertex)
边的终点(头部顶点,即 head vertex)
描述两个顶点之间关系类型的标签
一组属性(键值对)
(2)、Cypher 查询语言
(3)、SQL 中的图查询
递归公用表表达式(WITH RECURSIVE
语法)
(4)、三元组存储和 SPARQL
语义网
RDF 数据模型
SPARQL 查询语言
(5)、基础:Datalog
本章小结
数据模型是一个巨大的课题,在本章中,我们快速浏览了各种不同的模型。我们没有足够的篇幅来详述每个模型的细节,但是希望这个概述足以激起你的兴趣,以更多地了解最适合你的应用需求的模型。
在历史上,数据最开始被表示为一棵大树(层次数据模型),但是这不利于表示多对多的关系,所以发明了关系模型来解决这个问题。最近,开发人员发现一些应用程序也不适合采用关系模型。新的非关系型 “NoSQL” 数据存储分化为两个主要方向:
文档数据库 主要关注自我包含的数据文档,而且文档之间的关系非常稀少。
图形数据库 用于相反的场景:任意事物之间都可能存在潜在的关联。
这三种模型(文档,关系和图形)在今天都被广泛使用,并且在各自的领域都发挥很好。一个模型可以用另一个模型来模拟 —— 例如,图数据可以在关系数据库中表示 —— 但结果往往是糟糕的。这就是为什么我们有着针对不同目的的不同系统,而不是一个单一的万能解决方案。
文档数据库和图数据库有一个共同点,那就是它们通常不会将存储的数据强制约束为特定模式,这可以使应用程序更容易适应不断变化的需求。但是应用程序很可能仍会假定数据具有一定的结构;区别仅在于模式是明确的(写入时强制)还是隐含的(读取时处理)。
每个数据模型都具有各自的查询语言或框架,我们讨论了几个例子:SQL,MapReduce,MongoDB 的聚合管道,Cypher,SPARQL 和 Datalog。我们也谈到了 CSS 和 XSL/XPath,它们不是数据库查询语言,而包含有趣的相似之处。
虽然我们已经覆盖了很多层面,但仍然有许多数据模型没有提到。举几个简单的例子:
使用基因组数据的研究人员通常需要执行 序列相似性搜索,这意味着需要一个很长的字符串(代表一个 DNA 序列),并在一个拥有类似但不完全相同的字符串的大型数据库中寻找匹配。这里所描述的数据库都不能处理这种用法,这就是为什么研究人员编写了像 GenBank 这样的专门的基因组数据库软件的原因【48】。
粒子物理学家数十年来一直在进行大数据类型的大规模数据分析,像大型强子对撞机(LHC)这样的项目现在会处理数百 PB 的数据!在这样的规模下,需要定制解决方案来阻止硬件成本的失控【49】。
全文搜索 可以说是一种经常与数据库一起使用的数据模型。信息检索是一个很大的专业课题,我们不会在本书中详细介绍,但是我们将在第三章和第三部分中介绍搜索索引。
让我们暂时将其放在一边。在 下一章 中,我们将讨论在 实现 本章描述的数据模型时会遇到的一些权衡。