【问题标题】:Neo4j how to avoid supernodesNeo4j如何避免超级节点
【发布时间】:2015-08-05 13:02:25
【问题描述】:
在我的 Neo4j 项目中,我有代表用户角色和权限的 Role 和 Permission 实体。系统中的每个User 都与适当的角色和权限集有关系。
我认为Role 和Permission 是某种超级节点,从性能的角度来看,它们将来可能会成为一个令人头疼的问题。
这种情况的最佳做法是什么?如何重新实现Role 和Permission 以避免超级节点可能出现的问题?
【问题讨论】:
标签:
neo4j
cypher
spring-data-neo4j
graph-databases
【解决方案1】:
您是否打算根据角色进行一些聚合/大规模查询(即计算特定角色的人数,列出他们)?
如果没有,并且您只想检查特定用户是否具有某些角色,那么在我看来,它应该不会导致难以维护的重要性能问题(因为您将遍历图表的某些关系,忽略绝大多数您的“超级节点”的多个关系)。我会保持简单的设计(“过早的优化是万恶之源”;)),一旦发现问题(在内部,关系存储在类似链表的结构中,因此在超级节点上找到合适的可能需要时间,即使您将搜索限制为某种关系类型),使用元节点方法拆分角色节点也应该完成这项工作(在Learning Neo4j 中有描述)
如果是,您有问题。这可能是 RDBMS 更好的领域...使用元节点可能无济于事,因为您仍然需要处理所有这些节点以列出/计算所有用户...因此将数据缓存在单独的存储中可能是简直是最好的主意...
【解决方案2】:
我将假设您只是将 Neo4j 用作权限查找数据源(例如 hasPermission(current_user, 'permission_string')),而不是绑定到对其他实体的任何查询。这很好,特别是如果您有分层访问模式。如果这不是真的,那么这可能不适用,最好能更清楚地了解您的实体是什么样子。
由于您可能会在整个应用程序中使用权限,并且如果它们的大小和范围会增长,那么使用内存存储或 Redis 等某种形式的缓存可能会提高性能,例如例子。
为每个用户生成每个权限状态的非规范化缓存甚至可能是有意义的。因此,您将评估可能基于分层角色/权限的规则,并得出“用户 X 具有权限 Y”的列表。然后,每当您更改用户或权限时,您都会为该实体重新生成缓存,如果您更改角色,您将为所有关联的用户和权限重新生成缓存。
我也不知道我是否会将此建议仅应用于 Neo4j。如果您谈论的是简单的键/值查找,那么在性能关键的情况下,许多通用数据库将是矫枉过正。