《图数据库(第2版)》——2.1 关系型数据库缺少联系

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
简介:

本节书摘来自异步社区出版社《图数据库(第2版)》一书中的第2章,第2.1节,作者:【美】Ian Robinson(伊恩•罗宾逊) , Jim Webber(吉姆•韦伯) , Emil Eifrem(埃米尔•艾弗雷姆),更多章节内容可以访问云栖社区“异步社区”公众号查看。

2.1 关系型数据库缺少联系

数十年来,开发者试图使用关系型数据库处理关联的、半结构化的数据集。关系型数据库设计之初是为了处理纸质表格以及表格化结构—有些方面关系型数据库做得非常好—它们试图对这种实际中的特殊联系进行建模。然而讽刺的是,关系型数据库在处理联系上做得却并不好。

联系确实存在于关系型数据库自身的术语中,但只出现在建模阶段,作为连接表的手段。前面章节在对关联数据的讨论中曾经提到,我们经常需要对连接实体的联系进行语义的区分,并为其定义权重。关联关系什么也做不了。更糟糕的是,随着离群数据(outlier data)的成倍地增加,数据集的宏观结构会越发复杂和不规整,关系模型将造成大量表连接、稀疏行和非空检查逻辑。关系世界中连通性的增强都将转化为连接操作的增加,这会阻碍性能,并使已有的数据库难以响应变化的业务需求。

图2-1展示了一个以客户为中心的、事务型应用程序存储顾客订单的关系模式(relational schema)。

这种模式的设计对该应用程序产生了很大影响,使有些查询非常简单,而有些异常困难。

表连接增加了偶发复杂性,使得业务数据与外键元数据混杂起来。
外键约束增加了额外的开发与维护成本,而目的仅仅是为了让数据库工作
带有空值列的稀疏表在代码中需要额外检查,尽管模式本身提供了相关支持。
仅因为想要查看客户买了什么就需要好几个昂贵的连接。
反向查询(reciprocal query)代价更高。查询“某个客户买了哪些商品?”比查询“有哪些客户买了某个商品?”的代价相对要低,而这是推荐系统的基础。对于这样的需求,可以引入索引,然而即使引入索引,随着递归程度的增加,诸如“有哪些买这个商品的客户也买了那个商品?”这样的递归问题的查询代价变得异常高昂。
image

关系型数据库在强关联领域表现也很挣扎。让我们通过社交网络领域中的一些或是简单或是不那么简单的查询来理解关系型数据库中关联查询的成本吧。

图2-2展示了一个记录朋友关系的简单的连接表设计。

image

回答“谁是Bob的朋友?”这个问题很简单,如示例2-1所示。

示例2-1 Bob的朋友

SELECT p1.Person
FROM Person p1 JOIN PersonFriend
  ON PersonFriend.FriendID = p1.ID
JOIN Person p2
  ON PersonFriend.PersonID = p2.ID
WHERE p2.Person = 'Bob'

基于这个示例数据,答案是AliceZach。这不是一个代价高昂或困难的查询,因为它使用了WHERE Person.person='Bob',使得返回的行数是可预期的和有限的。

朋友关系不总是自反关系(reflexive relationship),因此在示例2-2中,需要回答示例2-1的反向查询:“Bob是谁的朋友?”

示例2-2 Bob是谁的朋友

SELECT p1.Person
FROM Person p1 JOIN PersonFriend
  ON PersonFriend.PersonID = p1.ID
JOIN Person p2
  ON PersonFriend.FriendID = p2.ID
WHERE p2.Person = 'Bob'

这个查询的答案是Alice,很遗憾Zach不认为Bob是他的朋友。这个反向查询在实现上也很简单,但是数据库端的花销就略微大些了,因为所有的数据行都在表PersonFreiend中。

我们可以加入索引,然而仍会涉及代价高昂的中间层。当问题是“谁是我的朋友的朋友?”时就更麻烦了。SQL的层级结构使用了递归连接,使得查询语法和计算都更加复杂,如示例2-3所示。(有些关系型数据库提供这种查询的语法糖。例如,Oracle提供了函数CONNECT BY,它可以简化查询语句,但并不能降低底层的计算复杂度。)

示例2-3 Alice的朋友的朋友们

SELECT p1.Person AS PERSON, p2.Person AS FRIEND_OF_FRIEND
FROM PersonFriend pf1 JOIN Person p1
  ON pf1.PersonID = p1.ID
JOIN PersonFriend pf2
  ON pf2.PersonID = pf1.FriendID
JOIN Person p2
  ON pf2.FriendID = p2.ID
WHERE p1.Person = 'Alice' AND pf2.FriendID <> p1.ID

即使只是处理Alice的朋友的朋友们,而非深入Alice的整个社交网络,这个查询计算也很复杂。当我们试图探究社交网络时,问题则更复杂,代价也更高。虽然“谁是我的朋友的朋友们?”这样的问题还是可能在合理的时间内通过查询得到答案,但是当查询延伸到第4度、第5度或第6度的朋友关系时,由于递归的连表查询使此时的时间空间复杂度非常高,从而使查询的效率严重恶化。

无论试图在关系型数据库中对关联建模还是查询,结果都与我们的愿望完全不同。除了之前指出的查询和计算复杂度以外,我们还得去处理模式(schema)这个双刃剑。很多时候,模式被证明太死板、太脆弱。死板表现在:我们需要在创建稀疏表的同时在代码中处理异常情况—一切只是因为没有一个能够容纳我们所用到的各类数据的通用的模式。这在增加了耦合度的同时也摧毁了其貌似存在的凝聚力。脆弱表现在:当应用程序发生变化时,需要增加额外的工作从一个模式迁移到另一个模式。

相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
相关文章
|
22天前
|
关系型数据库 分布式数据库 数据库
阿里云瑶池数据库训练营权益:PolarDB开发者大会主题资料开放下载!
阿里云瑶池数据库训练营权益:PolarDB开发者大会主题资料开放下载!
|
26天前
|
存储 DataWorks 监控
DataWorks,一个 polar db 有上万个数据库,解决方案
DataWorks,一个 polar db 有上万个数据库,解决方案
|
30天前
|
人工智能 运维 关系型数据库
媒体声音|PolarDB再升级:欢迎来到云数据库 x AI新时代
让个人开发者和企业用户都可以像“搭积木”一样开发和管理数据库
媒体声音|PolarDB再升级:欢迎来到云数据库 x AI新时代
|
1天前
|
SQL 关系型数据库 分布式数据库
|
16天前
|
SQL 存储 关系型数据库
MySQL技能完整学习列表——1、数据库基础概念——1、关系型数据库(Relational Database)
MySQL技能完整学习列表——1、数据库基础概念——1、关系型数据库(Relational Database)
18 0
|
17天前
|
关系型数据库 分布式数据库 数据库
PolarDB for PostgreSQL报错问题之psql连接数据库报错如何解决
PolarDB for PostgreSQL是基于PostgreSQL开发的一款云原生关系型数据库服务,它提供了高性能、高可用性和弹性扩展的特性;本合集将围绕PolarDB(pg)的部署、管理和优化提供指导,以及常见问题的排查和解决办法。
|
22天前
|
SQL 算法 JavaScript
【数据库SQL server】关系型数据库的基本知识
【数据库SQL server】关系型数据库的基本知识
82 0
|
22天前
|
Cloud Native 关系型数据库 分布式数据库
2024最新一期中国数据库流行榜公布:阿里云PolarDB登顶
PolarDB登顶国产数据库流行榜,持续引领云原生数据库创新
2024最新一期中国数据库流行榜公布:阿里云PolarDB登顶
|
22天前
|
Cloud Native 关系型数据库 分布式数据库
|
23天前
|
存储 NoSQL 关系型数据库
面试题14: 关系型数据库和非关系型数据库的区别
面试题14: 关系型数据库和非关系型数据库的区别

热门文章

最新文章