为什么neo4j或图形数据库中存在关系作为一个概念?

时间:2013-12-07 01:34:22

标签: neo4j graph-databases

我似乎无法就此发现任何讨论。我一直在想象一个无模式,基于节点和层次结构的数据库,有一天我觉得它不常存在太常识,所以我开始搜索并且neo4j大约是我想象的95%。

我没想到的是关系的概念。我不明白他们为什么有必要。它们似乎为以图形数据库为中心的所有主题增加了大量复杂性,但我不太明白它的好处是什么。关系似乎几乎完全像节点,除了更有限。

为了解释我的想法,我想象创办一家公司,所以我创造了自己作为我的第一个节点:

create (u:User { u.name:"mindreader"});
create (c:Company { c.name:"mindreader Corp"});

有一天我得到了一个客户,所以我把他的公司放到我的数据库中。

create (c:Company { c.name:"Customer Company"});
create (u:User { u.name:"Customer Employee1" });
create (u:User { u.name:"Customer Employee2"});

我决定将用户链接到他们的客户

match (u:User) where u.name =~ "Customer.*"
match (c:Company) where c.name =~ "Customer.*
create (u)-[:Employee]->(c);

match (u:User where name = "mindreader"
match (c:Company) where name =~ "mindreader.*"
create (u)-[:Employee]->(c);

然后我雇了一些人:

match (c:Company) where c.name =~ "mindreader.*"
create (u:User { name:"Employee1"})-[:Employee]->(c)
create (u:User { name:"Employee2"})-[:Employee]->(c);

有一天,他说他们需要知道我何时雇用员工。好:

match (c:Company)<-[r:Employee]-(u:User)
where name =~ "mindreader.*" and u.name =~ "Employee.*"
set r.hiredate = '2013-01-01';

然后hr回来说,嘿,我们需要知道公司里的哪个人招募了一名新员工,以便他们可以获得现金奖励。

现在我需要的是关系指向用户但不允许(:Hired_By关系:员工关系和用户之间)。我们可以有一个额外的关系:Hired_By,但如果:员工关系被删除,hired_by将保留,除非有人记得删除它。

我在neo4j中可以做的只是有一个

(u:User)-[:hiring_info]->(hire_info:HiringInfo)-[:hired_by]->(u:User)

在这种情况下,关系只会提供最少的信息,即名称。

我最初设想的是会有节点,然后节点的每个属性可以是数据类型,也可以是指向另一个节点的指针。就我而言,用户记录最终看起来像:

User {
  name: "Employee1"
  hiring_info: {
    hire_date: "2013-01-01"
    hired_by: u:User # -> would point to a user
  }
}

基本上它仍然是一个图表。节点彼此指向。关系的名称只是原始节点中的一个字段。要查询它,你只需要

match (u:User) where ... return u.name, u.hiring_info.hiring_date, u.hiring_info.hired_by.name

如果您需要相同类型的一对多关系,那么您将只有一组指向节点的指针。如果你引用了一个集合作为回报,你基本上会得到一个连接。如果删除hiring_info,它将删除指针。对其他节点的引用不必是节点顶层的无组织列表。此外,当我查询每个用户时,我将知道有关用户的所有信息,而无需查询用户本身及其所有关系。我知道他的名字,以及他在同一个查询中聘请了某人的事实。从数据库后端,我不确定会有多大改变。

我看到很多人问他们是否应该使用节点或关系来模拟这个或那个,偶尔人们会要求关系之间的关系。感觉就像XML问题,你想知道一些信息应该是它自己的标签还是只是一个属性的父标签。

查询引擎竭尽全力处理关系,因此拥有它们必定会有一些巨大的优势,但我无法看到它。

4 个答案:

答案 0 :(得分:3)

不同的数据库适用于不同的事物。你似乎在寻找一个noSQL数据库。

这是一个非常广泛的主题领域,所以我会给你简短的介绍。有一系列数据库模式,每个模式具有不同的用例。

  • NoSQL又称非关系型数据库:

    每个对象都是一个文档。您可以引用其他文档,但任何其他遍历意味着您正在进行另一个查询。您经常在数据之间没有关系的时候,并且通常只想查询一次并且有大量灵活存储的数据作为返回的文档注意:这些不是“节点”。节点有一个非常具体的定义,暗示有边缘。)

  • SQL aka关系数据库:

    这是桌面,这是外键和一对多关系发挥作用的地方。在这里,您有严格的模式和非常快速的查询。老实说,这应该用于您的用户示例。事物之间关系浅的少量数据(你不必按照关系超过1-2次才能进入相关条目)是这些数据优秀的地方。

  • 图表数据库:

    当关系是您尝试做的事情的关键时,请使用此选项。最常见的图形示例类似于社交图,您可以将不同的用户连接在一起,并且需要遵循许多步骤的关系。 (弄清楚两个人是否在4个深度内连接)

图形数据库中存在关系,因为这是图形数据库的整个概念。它并不适合您的应用程序,但公平地说,您可以在数据库的节点部分保留更多内容。通常,数据库的整个概念可以让您非常快速地查询大量数据。根据数据的内在结构,有不同的方法是有意义的。因此,不同类型的数据库。

在强连通图中,Neo4j在1000倍数据上比SQL数据库快1000倍。 NoSQL可能永远无法在强连接的图形场景中执行。

答案 1 :(得分:2)

了解我们现在正在构建的内容:http://vimeo.com/81206025

更新:为了回应mindreader的评论,我们在图片中添加了相关属性:enter image description here

答案 2 :(得分:1)

RDBM系统是表格式的,并且在表格中放置的信息多于关系。图形数据库将更多信息放在关系中。最后,你可以完成相同的目标。

但是,在关系中放入更多信息可以使查询更小更快。

以下是一个例子:

SQL versus Cypher queries

图形数据库也擅长存储人类可读的知识表示,以边缘(关系)为中心。如果所有信息都存储为边而不是节点,RDF会更进一步。这是处理谓词逻辑,命题演算和三元组的理想选择。

答案 3 :(得分:1)

也许正确的答案是对象数据库。

Objectivity/DB 现在支持全套图形数据库功能,允许您设计具有一对一、一对多、多对一和多对多引用的复杂模式属性。它具有将对象视为图形节点和边的语义。边可以只是从一个节点到另一个节点的引用属性,或者边可以作为位于两个节点之间的边对象存在。

enter image description here

一个边对象可以有任意数量的属性,并且可以引用其他对象,如下图所示。

enter image description here

能够将复杂对象从边上“悬挂”起来,这使得 Objectivity/DB 能够支持加权查询,其中边权重可以使用用户定义的权重计算器运算符来计算。权重计算器操作员可以根据边缘上的静态属性构建权重,或者通过向下挖掘连接到边缘的对象来构建权重。在上图中,我们可以创建一个边权重计算器,用于计算连接到 Call 边的 CallDetail 长度的总和。