我想知道在Nneo4J的电影数据库中建立[:RATED]
关系的哪种方法更好?我可以想到以下两种方法:
方法1感觉更直接,并且在某种程度上设计在学术上更正确。
但是,方法1需要n (:Movie)
个节点。有人可能会说方法2看起来更自然,因为图表只能包含一个特定电影的(:Movie)
节点("矩阵"在这种情况下),无论是否有人评价它都可以存在。但是我觉得在[:RATED]
关系上存储评级值不太舒服。从纯粹的设计角度看是否正确?
如果我们正在处理不代表实体的节点,那该怎么办?例如,一堆汽车在上面的图像中替换用户并且意外更换了#34; The Matrix"。在这种情况下,(:Accident)
节点默认情况下可能不存在,但仅在发生事故时创建。两辆不同车型所面临的事故也是(:Accident)
的不同实例,并且有很多与之相关的属性,如时间,地点等。在这种情况下,每次为每辆车创建单独的(:Accident)
节点更具设计意义。遇到意外并将其属性与之关联,而不是单个(:Accident)
,并且具有与从(:Car)
到(:Accident)
的关系相关联的属性。但是它会创建很多(:Accident)
个节点。从设计角度和绩效角度来看,这种场景的最佳方法是什么?
汇总:
答案 0 :(得分:2)
通常,您选择使用的任何方法都应该适合您的用例和查询。
鉴于您的示例,使用一个Matrix:Movie节点的方法2,考虑到跟踪电影评级的用例,是完美的设计。这与您可以在Neo4j中加载的电影图表中使用的方法相同。尝试一下,并注意图表将是混乱的,如果有多个单独的:电影节点,每个单独的关系到:电影,将很难查询。
您将注意到,在方法1中,每个Matrix:Movie节点之间绝对没有任何不同。这是一个强有力的指标,您应该将事物建模为单个节点而不是多个节点。如果您使用多个节点进行相同的操作,查询也会更加困难,因为数据库不能再使用单个节点作为电影根据其关系获取数据的起点。您对电影本身的查询也会变得稍微复杂一些,因为您需要在按名称匹配电影时添加LIMIT 1
,否则查询将匹配所有多个Matrix电影,这些电影可能有数千个或更多取决于有多少评级。
即使您可能用于此模型的其他一些查询将使用类似的Cypher,甚至是相同的Cypher查询,但您将通过此数据模型不必要地影响数据库操作。考虑平均评级查询。使用单个Matrix:Movie节点,只需匹配单个:Movie节点(通过索引或唯一名称),然后取其所有关系的平均值。使用多个Matrix:Movie节点,您的匹配将匹配数千(或更多)冗余节点,并且对于所有这些节点,它将需要拉出这些关系并将它们平均在一起。这是你需要做的大量db分数。
另外,请记住在将此方法用于其他用例时使用此方法的难度。例如,考虑我们是否必须将您的数据模型更改为包含actor和director,类似于您可以在neo4j中导入的影片db。如果我们为每部电影的每个评级都有多个节点,那么我们在创建演员和导演之间的关系以及他们工作的电影时会使用哪个节点?使用这种数据模型,没有很好的选择来有效或清晰地建模这种数据。
考虑到你的第二种情况,有必要制作一个新的:事故节点,每次事故,每个节点的事故细节。如果您的数据库中的两辆或多辆汽车涉及同一事故,那么使用相同的事故节点来表示事故,并将多辆汽车的关系与他们所涉及的同一事故联系起来是有意义的。复制有关同一事故实例的数据,并清楚地模拟事故中的参与者以及与事故相关的任何其他相关数据。您可以随时存储汽车与事故之间关系的特定车辆事故数据,例如持续损坏,以及汽车驾驶员是否发现故障。
在这个数据模型中应该清楚的是,应该有单独的:事故节点(除非,如上所述,它是多辆车的同一事故),因为事故之间的数据会有所不同,并要求你在单独的节点中捕获它们。这与您的电影数据模型有很大不同,因为数据完全相同,因此使用多个:同一电影的电影节点没有意义。
至于在关系中存储数据,这又取决于您的数据模型以及最有意义的内容。对于评级,将评级与电影的关系存储起来对我来说很好。
在某些情况下,您可以考虑创建中间节点以在节点上存储数据而不是关系。考虑一个就业图,其中包括:Person和:Company节点。您可以简单地使用:节点之间的WORKS_AT关系对此进行建模,但是您需要在关系上存储有关就业的数据,例如hireDate,salary,jobTitle等。这可能很好......但您可以随时将其提取到它自己的节点,a:就业节点:a:Person和a:公司,用于保存该数据。这可以让我们为这些属性编制索引,从而更容易查询:a:公司按雇佣日期的顺序,例如,如果数据存在于关系中,则效率不高,因为您可以' t关系属性的索引。
修改
关于节点的基数,何时使用单个节点实例与多个节点实例,当你回答问题时,通常最好回答这个问题;这对于这个数据模型是否合乎逻辑&#34 34;和"查询这些数据是否简单有效?"
您提出的两种情况,对于Matrix:电影节点和:事故节点,每个都展示了相反的情况。
单个Matrix:Movie节点是有意义的,我认为找到需要多个Matrix节点副本的用例可能是一个延伸。
但是,如果你不得不模拟黑客帝国的电影放映,那么可能会要求:显示节点,其中有几个(每个时间和每个影院),但所有节点都引用相同的矩阵:电影节点。它是同一部电影,但它有多个放映。
对于:事故,使用多个事故是有意义的:事故节点,每个节点代表一个特定的事故实例。在许多情况下,将只有一个:与单个相关联的汽车:事故节点,一个驱动程序崩溃到某些东西而不涉及其他驱动程序。在其他情况下,当它发生多车碰撞时,会有几辆汽车同时发生:事故,所以您将拥有:事故节点,其中包含时间,地点和详细信息,以及与之相关的汽车:那个特别的意外。
虽然可以使用单个:事故节点来处理所有事故,并且详细了解这些关系,但您很快就会遇到一些您可能需要的查询问题。使。例如,您如何知道哪些事故是多车事故,涉及哪些车?我们必须检查单个的所有关系:事故节点,即使这样,我们也必须做额外的逻辑来计算关联。如果我们想订购怎么办:按日期发生的事故?我们不能在关系属性上使用索引,因此我们必须再次触及所有关系并检查它们的属性并对它们进行排序。如果我们想根据最接近事故的城市指明位置,以便快速查找某些城市的事故怎么办?同样,我们不能在关系属性上使用索引来快速查找。如果我们已经拥有:城市节点,我们无法在相关的城市节点和崩溃关系之间建立关系,您需要一个节点。
我可以列出更多案例,但很明显,多个事件:每次事故都需要事故节点(同样,共享节点:参与相同的汽车:事故)。
这是其中一种情况,即使您在考虑数据模型是否有意义时错过了它,考虑您想要进行的查询类型及其效率,应该会推动您更好地建模您的data ...在这种情况下,使用multiple:Accident nodes。