【问题标题】:neo4j example - graph vs relational conceptsneo4j 示例 - 图与关系概念
【发布时间】:2014-10-15 20:29:51
【问题描述】:

在我对关系型 mySQL 进行了一些研究之前,但我也不认为自己是该领域的专家。我发现了以下关于数据库设计的问题12,但我想知道您对我的问题的看法。我想创建自己的示例数据集,我可以在其上测试我的 Cypher 查询。我想到的一个领域是类似于面向音乐听众的社交网络的数据集,比如 LastFM。

所以我的第一个想法是创建两种类型的节点 Bands 和 Persons:

(nir:Band   { name: "Nirvana", town: "Seatle", country: "USA",  genere: "Grunge" })
(dgr:Person { name: "Dave Grohl", born: 1969, instrument: "drums" })

作为一个人,我还创建了我的社交网络的用户(不是乐队成员)。我有以下几种关系:

(dgr)-[:IS_MEMBER_OF {from: 1987, to: 1994} ]->(nir)
(user1)-[:IS_FRIEND_OF]->(user6)
(user1)-[:LIKES]->(nir)

然后我意识到这个概念至少有三个我现在可以看到的限制:

  1. 乐队只能按一种流派分类
  2. 乐队只能来自一个城镇/国家
  3. 乐队成员只能在他曾经参加过的所有乐队中演奏一种乐器

为了解决前两个问题,我首先想到了一些类似于数组的数据类型(从 Python 等中已知)。在这个数组中可以存储多个元素(多个流派或多个城镇和国家),但我在 neo4j 中没有找到关于数组的任何内容。然后我意识到所有这些限制都可以通过neo4j自然而然地解决,唯一需要的是稍微修改节点和关系:

(nir:Band   { name: "Nirvana" })
(foo:Band   { name: "Foo Fighters" })

(dgr:Person { name: "Dave Grohl", born: 1969 })

(grn:Genere { name: "Grunge" })
(rck:Genere { name: "Rock" })

(dgr)-[:IS_MEMBER_OF {from: 1987, to: 1994, instrument:"drums"} ]->(nir)
(dgr)-[:IS_MEMBER_OF {from: 1994, to: 1998, instrument:"drums"} ]->(foo)
(dgr)-[:IS_MEMBER_OF {from: 1998, to: 2014, instrument:"guitar"} ]->(foo)

(stl:Town    { name: "Seatle" })
(por:Town    { name: "Portland" })

(usa:Country { name: "USA" })

(stl)->[:IS_IN]->(usa)
(por)->[:IS_IN]->(usa)

(nir)->[:IS_FROM]->(stl)
(nir)->[:IS_FROM]->(por)

(nir)->[:PLAYS]->(grn)
(nir)->[:PLAYS]->(rck)

(user1)-[:IS_FRIEND_OF]->(user6)
(user1)-[:LIKES]->(nir)

最后是我的问题:

  1. 可以说我对上述限制感到满意,而且它 完全符合我的需求(乐队只能来自一个城镇等)。还是 最好有不同类型的节点(城镇、国家、流派) 提及?与创建完全不同的节点类型相比,使用现有节点中的属性是否有任何(性能)​​优势? 与具有代表例如的类型节点相关仪器或与未来观点完全不同的东西?
  2. 关系数据库中有一条规则,当你有 m:n 关系你将需要连接表。这也可以应用于 图形数据库,而不是连接表,而是创建新节点 类型是必需的(城镇、国家、流派)?

编辑回复@Michael Hunger

“你应该问问自己你想用它解决哪些查询/用例” 如果instrumentIS_MEMBER_OF 关系的成员,或者instrumentPerson 的成员,我仍然能够(也许Cypher 查询看起来更笨拙,我不知道)获得所需的数据,例如给我看看所有来自美国的乐队中演奏的鼓手。当然,我受到上述限制的限制(一个人只能演奏一种乐器等)。我的问题是,如果我知道这些限制(第一个提议的模式)并且我对它们感到满意,那么创建另一个(第二个提议的模式)数据库模型是否有意义。第二个提议的架构比第一个有什么好处吗?我现在可以看到的是,与第一个模式相比,第二个模式的扩展性很好,还有其他东西,例如性能吗?

“对于某些特定的用例,将乐队成员建模为节点可能会很有趣,然后您可以将它们连接到仪器节点、时间树(年->月->成员)或将它们放入顺序(与下一个关系)。” 您能否发布一些简单的 CYPHER 示例?我很难想象。

“图形数据库预先实现关系,并将它们与它们连接的节点一起存储” 这是否意味着从性能角度来看,以下两个基本相同?因为这两种关系都连接了节点。

CREATE (dgr:Person {name:"Dave Grohl", instrument: "drums"})-[:IS_MEMBER_OF]->(nir:Band {name:'Nirvana'})
CREATE (dgr:Person {name:"Dave Grohl"})-[:IS_MEMBER_OF {instrument: "drums"} ]->(nir:Band {name:'Nirvana'})

【问题讨论】:

  • 您的第二个解决方案肯定是朝着正确的方向发展。紧凑地表示这些复杂关系的能力是图数据库技术如此有用的原因。将尽可能多的信息转移到不同的节点和关系中绝对是要走的路。

标签: mysql database-design neo4j nosql


【解决方案1】:

你的第二个模特看起来真的很棒。你应该问问自己你想用它解决哪些查询/用例,如果它支持它们你就很好。

对于某些特定的用例,将乐队成员建模为节点可能会很有趣,然后您可以将它们连接到仪器节点、时间树(年->月->成员)或将它们按顺序排列(与下一个关系)。

关于您关于连接表的问题。

在不需要的图形数据库中,关系扮演了角色(但不是连接表的实现)。图数据库预先实现关系,并将它们它们连接的节点一起存储。因此,沿着该连接查询并不昂贵,因为它只是跟踪数据库中的现有记录。

因此,您也不需要技术主键和外键。唯一有意义的是索引用于查找实体的属性,例如:Person(name), :Band(name), 流派、国家和城镇都一样(如果你想按名字搜索的话)。

http://graphgen.neoxygen.io 是一个可以帮助您入门的好工具,它是一个示例图形生成器。

如果您有兴趣,我们还有一些关于音乐领域的数据集和文章:http://www.neo4j.org/misc/music(musicbrainz 数据集已过时,必须更新)。

【讨论】:

  • 非常感谢您的回复,很抱歉后来回复我差点忘记这个问题了。
猜你喜欢
  • 2013-07-07
  • 2021-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-31
相关资源
最近更新 更多