图数据库与传统数据库的对比分析:「一起学图数据库」系列第2篇

举报
且听风吟 发表于 2019/11/07 17:56:38 2019/11/07
【摘要】 本系列文章是《图数据库(第二版)》的读书笔记,内容大多为笔者消化原书内容之后的总结。针对复杂关系数据的存储,本文通过一些典型的例子,分析了图数据库与一些传统数据库/NoSQL数据库在实现上的不同点,从而说明了图数据库为何更擅长应对这类数据。

通过上篇文章我们已经知道,图是由「节点」和「联系」组成,我们可以将其称为关系(Relationships)数据。那么问题就来了,为什么我们非要选型图数据库存储?用关系型数据库、普通NoSQL数据库存储不可以吗?答案当然是可以的,但是图数据库应对这类数据存储更加专业,本文将通过一些典型的例子来说明这里的原因。

1. 关系型数据库难以应对复杂关系数据

关系型数据库建立在关系模型基础之上,简单来说就是指二维表格模型,因而一个关系型数据库就是由二维表以及与之相关的关系组成的一个数据组织。


关系通常在建模阶段定义,作为连接表的方式,常见的就是依赖外键建立连接。但是随着离群数据(离群值指在数据中有一个或几个数值与其他数值相比差异较大)的增多,数据的宏观结构会越发的复杂和不规整,关系模型将造成大量表连结、稀疏行和非空逻辑检查,这会导致性能急剧恶化,并使得已有的数据库难以应对业务需求的变化。


1.1 电商系统中的关系数据

下图是一个电商系统部分表设计,包含用户表 User订单表 Order订单-商品表 LineItem商品表 Product四个表:


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1

图1:关系型数据库中的关系


我们不妨先分析下,这种表结构的设计是否合理?用户表和商品表毋庸置疑,一个主键,其它是详细信息,没有额外关联。但是,订单表需要考虑,为啥还要拆出一个订单-商品表?仔细考虑下,订单需要的主要信息是订单ID、下单用户、商品数量、总金额、下单时间、订单状态等信息,而具体买了什么商品并不是很重要,所以就需要拆分出一张订单-商品的关联表。订单-商品表可以有一个主键(没有实际用途),也可以不要主键。


在我们认定表结构设计没有问题的情况下,我们考虑如何支持下面几个查询:


查询1:查询用户XXX买了什么需要关联几张表?


image.png


查询2:某个商品被哪些人买了要怎么查询?

  

image.png


由上面的两个SQL查询可以推断,在大数据量和复杂的购买关系场景下,关系型数据库的表现并不会很好。除此,还存在业务数据和外键数据混杂、外键约束增加额外成本、稀疏表的空值需要额外检查等问题。


1.2 社交关系中的关系数据

640?wxfrom=5&wx_lazy=1&wx_co=1

图2:关系型数据库中对朋友关系的建模


640?wxfrom=5&wx_lazy=1&wx_co=1


查询1:查询Bob的朋友?


image.png

1573120478992208.jpg

查询2:Bob是谁的朋友?


image.png

1573120505387641.jpg

查询3:Alice的朋友的朋友们?


image.png


640?wxfrom=5&wx_lazy=1&wx_co=1


通过上面的三个查询示例,我们看到只是查询三度(层)人脉关系的时候,SQL语句已经开始非常复杂,而查询过程的复杂度也变得很高、查询效率开始恶化,那么当问题延伸到第四、第五度甚至第六关系时呢?


2. NoSQL数据库也缺乏对关系数据的支持

NoSQL数据库有很多种,常见的主要有如下几种分类:

- 键值数据库(Redis、Memcached)

- 文档数据库(MongoDB、CouchDB)

- 宽列数据库(Cassandra、HBase)

- 图数据库(Neo4J、OrientDB)


这部分内容主要针对前三种NoSQL数据库,因为前三种数据库存储的都是无关联的值/文档/列,因此很难将它们直接用于存储关系数据/图数据。这里容易引起歧义,需要分清这里主要是指很难用于直接存储关系数据,并不是不能存储,因为上一篇文章我们讲过图的存储分原生和非原生,非原生的就是存储在NoSQL数据库中,比如Titan。


对于这几种NoSQL数据库来说,一种广为认知的支持关系数据存储的策略就是添加外键,但是这样又需要在应用层连结聚合数据,也会增加额外的代价。


2.1 电商系统中的关系数据

下图是一个电商系统中的聚合存储模型,通过Key-Value表示数据之间的关系:

640?wxfrom=5&wx_lazy=1&wx_co=1

图3:聚合存储模型中的关系数据


在图3中,我们确实看到了一些属性值引用了数据库中其它聚合数据,然而将这些引用转化为可索引的结构需要一定的代价,因为聚合数据之间的联系并非数据模型中的一等公民--多数聚合存储只是以内嵌映射结构的方式装饰在聚合数据之内。相反,应用程序使用数据库时必须从这种扁平的、无关联的数据结构中建立起关系。我们还必须确保应用程序能够随着数据的变化更新或者删除外部聚合数据。假如不这样做,存储将积累无用的引用,从而破坏数据的质量和查询性能。


这种方案还有另外一个弱点:由于没有反向指针(外部聚合引用的指针不是自反的),数据库丧失了反向维度的查询能力。比如上图中,想要知道谁买了某种商品(基于购买历史做商品推荐),就是一个代价高昂的操作。想要处理这类问题,我们需要导出数据集,并在外部计算框架(如Hadoop)上运行计算来获取结果;或者只能回过头来将外部聚合引用反向插入,随后才能查询结果。但是无论哪种方法,都需要通过一种间接的方式来支持。


2.2 社交关系中的关系数据

640?wxfrom=5&wx_lazy=1&wx_co=1

图4:小型社交网络的聚合存储模型


图4是一个基于文档实现的聚合存储的小型社交网络。通过这种结构,我们可以很明显的找到用户的直接朋友(查询Bob的朋友),不需要进行全表扫描。但是当我们回到 "Bob是谁的朋友"这样的问题时,就必须要进行全表扫描。当然我们可以通过添加属性friend_by,来表示入度关系(friends表示出度关系),但是这样又增加了数据维护成本和存储成本。


当需要查询"Alice的朋友的朋友们",或者查询第四度甚至更深的人脉关系时,这种开销就更大了。


3. 图数据库拥抱关系数据

通过上面的介绍,我们知道了在关系型数据中,关联关系通常以外键存在;在NoSQL数据库中,关联关系通常以键值对存在;而在图的世界中,这些数据天然以关系形式存在。


3.1 电商系统中的关系数据

640?wxfrom=5&wx_lazy=1&wx_co=1

图5. 电商系统的图数据库建模


首先,我们将用户的购买历史建模为关系数据。这在图中很简单,只需要将用户和订单链接起来,再将订单和商品链接起来,然后再将订单链接为购买历史。图5中,我们可以看到用户已经订购(PLACED)的所有订单,同时很容易推出每个订单包含(CONTAINS)哪些商品。通过MOST_RECENT可以找到用户最近的订单,随后沿着PREVIOUS可以回溯到更早的订单。


3.2 社交关系中的关系数据

640?wxfrom=5&wx_lazy=1&wx_co=1

图6:小型社交网络的图数据库建模


图6的社交网络中包含了朋友、恋人/单恋、同事/老板、婚姻等关系,规模上潜在朋友关系已经达到六度。图模型的灵活性,使得我们可以增加额外的节点和新的联系,同时不影响现有的社交网络,也不用做数据迁移。


图中的关系,自然的形成了路径。查询图或者遍历图都涉及路径查询。由于从根本上说,数据模型是面向路径的,多数基于路径的图数据库的操作都与数据模型本身呈现高度一致性,所以图数据库极为高效。


下图是利用RDBMS以及Neo4j执行多度关系查询测试的对比结果:

640?wxfrom=5&wx_lazy=1&wx_co=1

可以看出来,在支持到5度关系查询时,涉及到的结果集约为80万条,Neo4j依然能够在2秒左右的时间返回,而此时,RDBMS都无法正常完成查询。


4. 总结

本文通过列举了几个典型的例子,讨论了传统关系型数据库、普通NoSQL技术以及图数据库针对关系数据处理的不同实现方案,以及在支持一些复杂关系查询时的不同表现,从而让读者能够理解图数据库是一类应对复杂关系数据存储的专业数据库。


精彩文章推荐

图数据库相关文章:

「一起学图数据库」系列之图数据库概述

从扩线查询能力分析图数据库Titan的设计改进点

《一条数据的HBase之旅》系列连载文章:

简明HBase入门教程-开篇

简明HBase入门教程-Write全流程

简明HBase入门教程-Flush与Compaction

《OpenTSDB技术原理》系列连载文章:

OpenTSDB原理系列-元数据模型

OpenTSDB原理系列-TSDB数据表设计

OpenTSDB原理系列-线程模型

OpenTSDB原理系列-读取流程

其它精彩文章:

从HBase中移除WAL?3D XPoint技术带来的变革

号称十倍性能于Cassandra的ScyllaDB,究竟祭出了哪些技术"利器"?

NewSQL是否是NoSQL的取代者?

阅读开源项目源码的建议姿势


本文转载自微信公众号【Nosql漫谈】。

原文链接:https://mp.weixin.qq.com/s/2kxQje2c9Yirwn0akLg0aA

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。