Neo4J - 存储关系 vs 节点

4

我想知道将数据存储到关系或节点中是否有优缺点。

例如,如果我要将与讨论相关的评论存储到数据库中,是应该将评论数据存储在“评论”关系中,还是将其存储在通过单独关系与讨论相关的“评论”节点中。

1个回答

12

正确的数据模型取决于您需要进行的查询类型。您应该确定您的查询需求,然后确定一个符合以下标准的数据模型:

  1. 它允许您回答所有的查询,
  2. 它允许您的查询足够快速地完成,
  3. 它最小化了所需的DB存储。

在讨论评论的情况下,很可能您想要按时间顺序查询讨论线程。因此,您需要存储不仅评论被创建的时间,还需要存储评论之间的关系(因为讨论可能会产生不共享相同先前评论的不连续线程)。

让我们尝试一个简单的测试用例。假设有两个由相同初始评论(我们将其称为c1)引发的不连续线程:[c1, c3] 和 [c1, c2, c4]。并且假设,在这个简单的测试用例中,我们只对与主题相关的所有评论线程进行查询。

如果评论属性存储在节点中,则数据可能如下所示:

(u1:User {name: "A"})-[:MADE]->(c1:Comment {time:0, text: "Fee"})-[:ABOUT]->(s1:Subject {title: "Jack"})
(u2:User {name: "B"})-[:MADE]->(c2:Comment {time:1, text: "Fie"})-[:ABOUT]->(c1)
(u3:User {name: "C"})-[:MADE]->(c3:Comment {time:3, text: "Foe"})-[:ABOUT]->(c1)
(u4:User {name: "D"})-[:MADE]->(c4:Comment {time:9, text: "Fum"})-[:ABOUT]->(c2)

如果您将评论属性存储在关系中,您可能会尝试以下操作,但存在一个严重的缺陷。没有办法让一个关系直接指向另一个关系(就像我们在第2到4行尝试做的那样)。由于这个模型在neo4j中不合法,它无法满足上述任何标准。

(u1:User {name: "A"})-[c1:COMMENTED_ABOUT {time:0, text: "Fee"}]->(s1:Subject {title: "Jack"})
(u2:User {name: "B"})-[c2:COMMENTED_ABOUT {time:1, text: "Fie"}]->(c1)
(u3:User {name: "C"})-[c3:COMMENTED_ABOUT {time:3, text: "Foe"}]->(c1)
(u4:User {name: "D"})-[c4:COMMENTED_ABOUT {time:9, text: "Fum"}]->(c2)
因此,在我们简单的测试用例中,看起来将属性存储在节点中是唯一的选择。
以下是获取不相交线程路径的查询,包括每个评论者的用户(WHERE子句过滤掉部分线程):
MATCH p=(s:Subject)<-[:ABOUT*]-(c:Comment)<-[m:MADE]-(u:User)
WHERE NOT (c)<-[:ABOUT]-()
RETURN p

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接