将n个节点连接到单个节点的最佳方法?

Riv*_*diz 9 architecture database-design neo4j graph-databases orientdb

我正在为我正在构建的应用程序建模图形,我有n个用户连接到n个用户,我也有n个帖子可以被n个用户喜欢.所以对于给定的用户,结构看起来像这样, 在此输入图像描述

如果用户喜欢数百个Post节点,它将为节点生成100条边(realtionships),当post为n时,边也将为n.因此,一个用户将连接到n个用户和n个帖子以及n个未来的节点类型.

因此,使用中间节点从而减少给定节点的边缘,这看起来像这样,

在此输入图像描述

如果用户有一个名为Collection的中间节点,它将连接到like,因为这是一个属性图,我可以向中间节点添加一个属性,使其行为类似于来自用户的连接(类似于Likes. username = User.username)

这将类似于这个问题(图形数据库建模:我应该使用一个集合节点来避免许多依赖于节点)

我的想法是

这种中间连接节点的方式可以将垃圾与主节点隔离,从而可以加速自定义算法.

我的问题,

  1. 对此进行扩展的最佳解决方案是什么?
  2. 为什么我要考虑这个解决方案呢?

Lui*_*ila 8

该解决方案将具有优点和缺点.

主要缺点是遍历操作将更加昂贵,即.在找到帖子之前,您必须遍历另一个节点.

优点如下:

  • 添加新"喜欢"时,用户节点上的争用较少,即.用户@version不会增加,因此您可以在并发中对User进行更新,而不会出现版本冲突
  • 能够向"喜欢"节点添加信息.您也可以单独使用边缘,但您必须复制所有边缘的信息.
  • 一个较小的用户,特别是低于嵌入式/树的ridbag阈值http://orientdb.com/docs/2.2.x/RidBag.html只要考虑使用二进制协议,当你有一个树RidBag时,它就不会被序列化立即到客户端,但你会有一个迭代器,所以获取单个用户的开销不会很大.另一方面,使用HTTP协议,您将获得具有顶点的所有边缘RID,因此在这种情况下,您将使用第二种方法节省大量带宽和计算时间.

关于您的问题,最佳解决方案是更适合您的工作负载的解决方案:如果您对用户进行了大量更新,第二个解决方案将为您提供直接的优势; 如果您经常单独取用用户,第二种解决方案也会带来优势; 另一方面,如果您的主要关注点是快速遍历,那么第二种解决方案将不是很合适.


Bru*_*res 6

根据非常好的书Neo4j(由Rik Van Bruggen提供,可在Neo4j的网站上下载),您的问题被称为"密集节点"或"超级节点":具有太多连接的节点.

仍然根据书,超级节点

"成为图遍历的真正问题,因为图数据库管理系统必须评估该节点的所有连接关系,以确定图遍历的下一步.

Rik提出的解决方案非常接近您的解决方案(添加中间节点):它包括在用户和您喜欢的帖子之间添加"元"节点.这个元节点最多应该有一百个连接.如果当前元节点达到100个连接,则必须创建新的元节点并将其添加到层次结构中,根据图中的示例,显示流行艺术家和您的粉丝的示例:

密集节点

Neo4j团队一直在努力提高超级节点的性能,这可以在Github提交(例如)中看到,它改变了链接列表结构中节点的关系如何存储在磁盘上.

我相信最好的方法是让您的图表模型尽可能简单.您还没有密集节点问题,而过早优化可能会为您的模型增加一些不必要的复杂性.如果将来密集节点成为问题,您可以更准确地更改模型.简单起初是一个不错的选择.

您可以在以下链接中阅读有关图数据库中超级节点的更多信息: