Dawn's Blogs

分享技术 记录成长

0%

数据密集型应用系统设计 (1) 数据模型与查询语言

常见数据模型

关系模型

关系模型是最常见,也是最著名的数据模型,SQL 就是基于关系模型的。

ORM 映射

关系型数据模型和编程语言对象之间是不匹配的,需要一个转换层,即对象关系映射(ORM)。

1
2
3
数据库中的一个表 <---> 一个类
表中的一条数据 <---> 类的一个对象
表中的一个列 <---> 类中的一个字段(field)

一对多的关系

在个人简历中,在工作经历一栏可能会有多个工作经历,并且可能有多段教育经历等一对多的关系。

这样的一对多关系,关系模型可以采用多种方式表示:

  • 在关系模型中,可以将工作经历、教育经历等放在单独的数据表中,并且使用外键引用。
  • 如果关系型数据库支持结构化的 Json(MySQL、PostgreSQL)或者 XML(Oracle、SQL Server、PostgreSQL)数据格式,可以将这些多值数据存储在一个属性内,并且支持查询和索引。
  • 将工作经历、教育经历编码为 Json 或者 XML 格式,存储在关系型数据库的文本列中,由应用程序解释其结构和内容。

文档模型

使用文档型数据库,就可以天然的解决关系模型中的一对多问题。并且文档型数据库在读取一对多关系的数据上,具有更好的局部性。如果在关系模型中读取一份简历,要么执行多个查询,要么进行多表联结查询。而在文档型数据库中,所有的信息都在一个地方,一次查询就已经足够了。

但是,文档型数据库通常不支持数据联结操作,只能在应用层通过多次查询来模拟联结。

多对一和多对多的关系

在表示多对一多对多的关系时,关系数据库和文档数据库的思想并没有根本的不同:相关项都由唯一的标识符引用

  • 关系模型中,这个唯一标识符为外键
  • 文档模型中,被称为文档引用

如果存在多对多关系,那么文档模型就不太适用了。

  • 可以通过反范式化来减少联结,但是需要在应用层做出额外的工作去保证数据的一致性
  • 也可以在应用层执行多次查询来模拟联结,但是这通常比数据库内的专用代码慢,使得文档型数据库应用程序代码复、性能差

灵活的模式

文档型数据库不会强制约束数据的模式,但是读取数据的代码通常定义了数据的结构。

  • 文档型数据库是读时模式(数据结构是隐式的,读取时由应用解释)
  • 关系型数据库的写时模式(模式是显式的,数据库确保写入的数据都遵循)

文档型数据库的这种灵活的模式,对于需要频繁变更的数据结构是十分友好的。而关系型数据库中,则需要改变表结构,在变更时无法读取和写入数据。但是当记录的结构稳定时,模式是记录和确保这种数据结构的有效机制。

图模型

关系模型可以描述简单的多对多关系,但是复杂的多对多关系,使用图模型会更加自然。

图模型的实现方式包括属性图模型和三元存储模型。

图数据库和文档数据库有一个共同点,就是它们都不会强制约束数据的模式。

属性图模型

属性图模型中,每一个顶点包括:

  • 唯一的标识符。
  • 入边集合。
  • 出边集合。
  • 属性集合。

每一条边包括:

  • 唯一的标识符。
  • 头部顶点。
  • 尾部顶点。
  • 描述两个顶点之间关系类型的标签。
  • 属性集合。

Neo4j 就是一种图数据库,它基于属性图模型,使用的查询语言为 Cypher。

可以利用关系模型,通过建立一个顶点表和一个边表,去描述属性图。

三元存储模型

三元存储模型,利用三元组存储图。三元组由主体、谓语、客体组成。

  • 主体相当于图的顶点。
  • 谓语可以表示边(关系),也可以表示属性。
  • 客体可以是字面量也可以是图中的另一个顶点。

数据查询语言

SQL 是一种声明式查询语言,只需要指定所需要的数据模式,不需要指定如何实现这一目标。

数据库的查询优化器会决定如何优化查询过程,所以比命令式查询语言更加简洁易用。