neo4j示例 - 图形与关系概念

时间:2014-10-15 20:29:52

标签: mysql database-design neo4j nosql

在我使用关系式mySQL之前,我并没有把自己视为这个领域的大师。我发现了关于数据库设计的以下问题1 2,但我想知道您对我的问题的看法。我想创建自己的示例数据集,我可以在其上测试我的Cypher查询。我想到的一个领域是数据集,它类似于面向音乐听众的社交网络,如LastFM。

所以我的第一个想法是创建两种类型的节点Bands and 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. 乐队成员只能在他曾经是
  4. 成员的所有乐队中的一个乐器上演奏

    为了解决前两个问题,我首先考虑了一些类似于数组的数据类型(从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时,关系数据库中有规则 关系你需要加入表。这也可以应用 图形数据库但不是连接表创建新节点 类型是必需的(城镇,国家,类型)?
    3. 编辑回复@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'})
      

1 个答案:

答案 0 :(得分:1)

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

对于某些特定的用例,将波段成员资格建模为节点可能会很有趣,然后您可以将它们连接到仪器节点,时间树(年 - >月 - >成员资格)或将它们放入订单(有下一个关系)。

关于你关于联接表的问题。

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

因此,您也不需要技术主键和外键。唯一有意义的是索引您用来查找实体的属性,例如:人(姓名),:乐队(名称),类型,国家和城镇相同(如果您想按名称搜索它们)。

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

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