【发布时间】: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)
然后我意识到这个概念至少有三个我现在可以看到的限制:
- 乐队只能按一种流派分类
- 乐队只能来自一个城镇/国家
- 乐队成员只能在他曾经参加过的所有乐队中演奏一种乐器
为了解决前两个问题,我首先想到了一些类似于数组的数据类型(从 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)
最后是我的问题:
- 可以说我对上述限制感到满意,而且它 完全符合我的需求(乐队只能来自一个城镇等)。还是 最好有不同类型的节点(城镇、国家、流派) 提及?与创建完全不同的节点类型相比,使用现有节点中的属性是否有任何(性能)优势? 与具有代表例如的类型节点相关仪器或与未来观点完全不同的东西?
- 关系数据库中有一条规则,当你有 m:n 关系你将需要连接表。这也可以应用于 图形数据库,而不是连接表,而是创建新节点 类型是必需的(城镇、国家、流派)?
编辑回复@Michael Hunger
“你应该问问自己你想用它解决哪些查询/用例”
如果instrument 是IS_MEMBER_OF 关系的成员,或者instrument 是Person 的成员,我仍然能够(也许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