写在前面
从去年找工作结束之后,就一直没有再写博文了,不知不觉已经过去大半年了T_T。鸟哥也从学校正式步入职场,开始了新的旅程~~。最近工作中由于要用到图数据库相关的东西,网上这方面的资料较少而且质量也不是很好,因此决定自己写一套有用的博文。
鸟哥带你学图数据库之Neo4j系列将会对Neo4j进行全面的介绍,系列的第一篇文章打算先简单介绍一下图数据库概念,与传统数据库的区别还有体系结构等内容,让大家从整体上先了解图数据库。(这部分内容主要是从《Neo4j实战》整理出来的)
概念
在计算机科学中,图形常常被用于表示特定的数据结构,如组织层级结构、社交网络以及处理流程等。在软件的设计阶段,结构、流程甚至算法也经常使用图形来表示。面向对象结构的计算机系统也是以继承、组成和对象成员作为图形建模的。
但是,在涉及到数据保存的时候,开发人员往往不使用图形的方式,而是试图将数据装进关系型表格中,并对其结构规范化和再规范化,一直到它看上去完全不是它应该表示的东西的样子。如果能用数据的自然形式表示数据,使数据的映射更加直观生动,免去那些从数据引擎上存取数据的大量重复的数据转换过程,那样岂不是更好吗?
现在有了图数据库就可以实现上述的过程了,图形数据库使用图形模型将数据作为图形存储,图形数据库由顶点和边构成,顶点和边这两个图形可以构建任何的图形。
关系型数据库 VS 图数据库
假如我们想表示用户和他的朋友之间的关系,使用传统关系型数据库通常会这样表示
如果你想要查找某用户的朋友的朋友,你必须对表t_user_friend中的所有数据做一个join操作,然后丢弃你不再感兴趣的所有行。对于一个小的数据集,这将不会是一个大的问题。但是,如果这个社交网络不断发展壮大,你可能开始遇到一些严重的性能问题。
关系数据库和Neo4j图形数据库的重要区别是数据查询。在Neo4j图形数据库中,没有表和列的概念,也没有基于SQL的select和join命令。那么Neo4j如何查询图形数据库呢?
答案是像所有的图形数据库一样,Neo4j借用图论的强大数学概念,并作为一个强大和高效率的引擎用于查询数据。这个概念就是图形遍历,图形遍历是使Neo4j具有强大处理大型图形数据的主要工具之一。
为什么图数据库的查询效率能够这么高?
我们分析查询过程就会发现,为了查询深度5的所有关系,MySQL将对t_user_friend表执行笛卡儿积运算5次,那将产生500005个记录,其中只有1000个是有用的,其他的都被丢弃。Neo4j则只访问数据库中的节点,当没有更多的节点可访问时,它将停止遍历。
Neo4j在NoSQL领域的地位
NoSQL,泛指非关系型的数据库。随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。
目前主流的NoSQL主要分为四个大类:
- 主键值存储
主键值存储代表了最简单,但却非常强大的处理大量并发访问数据的方法。缓存是一种典型的主键值技术。主键值存储允许使用非常简单的结构存储数据,这些数据常常在内存中,甚至在高并发环境下的高速访问。 - 列族存储
列族存储是将类似的值(或列)作为一组一起存储在同一列族中(例如,用户数据或有关书籍的信息)。 - 面向文档存储
很多实际问题(如内容管理系统、用户注册数据以及CRM数据)的需求看上去像一个文件的数据结构。面向文档的数据库正好提供了这样的一个地方,用以存储简单的,然而是高效的,无架构的文档数据。本文档模型中使用的数据结构,可以使你添加自包含的文件和关联关系到该文档的数据中。 -
图形(Graph)
图形数据库使用图形模型将数据作为图形存储,图形数据库由顶点和边构成,顶点和边这两个图形可以构建任何的图形。
Neo4j是一个开源的、高性能的NOSQL图形数据库。
Neo4j主要组件
下面我们以一个人与电影关系的例子来讲解Neo4j的主要组件
- 节点(Nodes)
节点通常用来表示一个实体以及实体包含的属性。上图中的实体就包含了以下属性(property)
- 关系(Relationships)
节点之间的关系是图数据库的关键特性,因为它们允许查找相关数据。一个关系连接两个节点,并保证有一个有效的源节点和目标节点。
关系的节点可以被组织成任意结构,使图看起来像表,树,图,或复合实体 —— 其中任何一种可以被组合成更复杂的,丰富的互联结构。
下面是一个ACTED_IN关系,以“汤姆·汉克斯”为源节点连接目标节点“阿甘”。
关系具有方向,我们观察到,Tom Hanks 节点有一个outgoing的关系,而Forrest Gump 节点有一个incoming的关系。
属性(Properties)
属性是名称(或键)为字符串的命名值。支持的属性值有:
Numeric
String
Boolean
上述任何一个值的列表标签(Labels)
标签是一种命名的图结构,用于将节点分组为集合;所有标记为同一标签的节点属于同一集合。许多数据库查询可以使用这些集合而不是整个图形,从而使查询更容易编写,执行起来更高效。一个节点可以标记为任意数量的标签,包括无标签,使标签成为图的可选添加项。
标签通常被用于定义的约束和建立索引。例如,代表用户的所有节点都可以用标签标记:用户。这样的地方,你可以问Neo4j只有在您的用户节点执行操作,如查找具有给定名称的所有用户。
在我们的示例中,我们将添加个人(:Person)和电影(:Movie)标签到我们的图表中。
为了举例说明节点如何可能有多个标签,让我们向汤姆·汉克斯节点添加一个演员(:Actor)标签。
- 遍历(Traversal)
遍历表示如何查询一个图形,从起始节点导航到相关节点,找到诸如“我的朋友喜欢哪些我还没拥有的音乐”这样的问题的答案,或者“如果这个电源关闭,哪些Web服务会受到影响?”
如果我们想在这个小示例数据库找到汤姆·汉克斯主演的电影,遍历将从汤姆·汉克斯节点开始跟随任何:ACTED_IN关系连接的节点,然后在阿甘这个节点结束(见虚线):
- 路径(Paths)
在前面的示例中,可以将返回结果作为路径返回:
上面的路径有一个长度。最短路径长度为零 - 就是它只包含一个节点没有关系,如下图所示。
路径长度为1的例子如下:
索引(Indexes)
一旦你指定了索引,Neo4j会确保你的索引保持更新你的图形的演变。通过新索引属性查找节点的任何操作都将看到显著的性能提升。
Neo4j不会自动更新索引,这意味着,当您第一次创建索引时,操作立即返回。但是修改它时,结果不会实时返回。只有当索引被设置为自动索引是,才会实时地返回结果。
如果索引出现问题,结果可能会处于失败状态。当它失败了,它不会被用来加快查询速度。你可以删除并重新创建索引,或者查看日志,查找失败的原因。约束(Constraints)
Neo4j可以帮助保持你的数据清洗。它使用约束。约束允许您指定数据应该是什么样子的规则。任何违反这些规则的改变将被拒绝。
小结
这篇博文主要介绍了图数据库概念、与传统数据库的区别以及Neo4j主要的组件这些内容,让大家从整体上了解了图数据库,至于是否要使用图数据库还是要根据项目的具体需求来决定的。下一篇博文主要介绍Neo4j的查询语言Cypher。