《设计数据密集型应用》读书笔记-第二章:数据模型与查询语言
关系模型与文档模型
SQL基于Edgar Codd在1970年提出的关系模型:数据被组织成关系(SQL中称作表),其中每个关系是元组(SQL中称作行)的无序集合。
采用NoSQL的几个原因:
- 需要比关系数据库更好的可伸缩性,包括非常大的数据集或非常高的写入吞吐量;
- 相比商业数据库产品,免费和开源软件更受偏爱;
- 关系模型不能很好地支持一些特殊的查询操作;
- 受挫于关系模型的限制性,渴望一种更具多动态性与表现力的数据模型。
混合持久化(polyglot persistence) -> 关系数据库与非关系数据库混合使用。
在关系模型中,程序的对象和数据库之间需要中间件进行转换,两者之间的不连贯现象被称为阻抗不匹配(impedance mismatch)。对象关系映射(ORM object-relation)框架只能够减少中间件代码的数量,但不能够隐藏两者之间的差异。文档模型如JSON模型具有良好的局部性(locality),能够减少应用程序代码与数据库模型之间的阻抗不匹配。
文档模型查询的数据局部性
文档通常以单个连续字符串形式进行存储,编码为 JSON、XML 或其二进制变体(如 MongoDB 的 BSON)。如果应用程序经常需要访问整个文档(例如,将其渲染至网页),那么存储局部性会带来性能优势。
局部性仅仅适用于同时需要文档绝大部分内容的情况。对于大型文档来说,更新文档通常需要整个重写。只有不改变文档大小的修改才可以容易地原地执行。因此,通常建议保持相对小的文档,并避免增加文档大小的写入。
如何选择模型?
文档数据库 的应用场景是:数据通常是自我包含的,而且文档之间的关系非常稀少。(如一对多关系树,通常一次性加载整个树)。
图形数据库 用于相反的场景:任意事物都可能与任何事物相关联。
关系模型 随意。
查询语言
- SQL 声明式查询语言
- IMS 和 CODASYL 命令式代码来查询数据库
- Web 上的声明式查询
- MapReduce 查询的逻辑用代码片段来表示,这些代码片段会被处理框架重复性调用。它基于 map(也称为 collect)和 reduce(也称为 fold 或 inject)函数,两个函数存在于许多函数式编程语言中。
图数据模型
一个图由两种对象组成:顶点(vertices,也称为 节点,即 nodes,或 实体,即 entities),和 边(edges,也称为 关系,即 relationships,或 弧,即 arcs)。多种数据可以被建模为一个图形。典型的例子包括:
-
社交图谱
顶点是人,边指示哪些人彼此认识。
-
网络图谱
顶点是网页,边缘表示指向其他页面的 HTML 链接。
-
公路或铁路网络
顶点是交叉路口,边线代表它们之间的道路或铁路线。
属性图
在属性图模型中,每个顶点(vertex)包括:
唯一的标识符
- 一组出边(outgoing edges)
- 一组入边(ingoing edges)
- 一组属性(键值对)
每条边(edge)包括:
- 唯一标识符
- 边的起点(尾部顶点,即 tail vertex)
- 边的终点(头部顶点,即 head vertex)
- 描述两个顶点之间关系类型的标签
- 一组属性(键值对)
可以将图存储看作由两个关系表组成:一个存储顶点,另一个存储边。
图数据库查询语言
- Cypher 是属性图的声明式查询语言,为 Neo4j 图形数据库而发明。
- SQL 中的图查询
- SPARQL 是一种用于三元组存储的面向 RDF 数据模型的查询语言
在三元组存储中,所有信息都以非常简单的三部分表示形式存储(主语,谓语,宾语)。
《设计数据密集型应用》读书笔记-第二章:数据模型与查询语言