Neo4j 如何避免超级节点
Neo4j how to avoid supernodes
在我的 Neo4j 项目中,我有 Role
和 Permission
代表用户角色和权限的实体。系统中的每个 User
都与适当的角色和权限集有关系。
我认为Role
和Permission
是某种超级节点,从性能的角度来看,将来可能会成为一个主要问题。
这种情况的最佳做法是什么?如何重新实现 Role
和 Permission
以避免超级节点可能出现的问题?
我假设您只是将 Neo4j 用作权限查找数据源(如 hasPermission(current_user, 'permission_string')
),而不是绑定到对其他实体的任何查询。这很好,特别是如果您有分层访问模式。如果这不是真的,那么这可能不适用,最好能更清楚地了解您的实体是什么样的。
由于您可能会在整个应用程序中使用权限,如果它们的大小和范围会增加,那么使用某种形式的缓存(如内存存储或 Redis)可能对性能有意义,例如。
为每个用户生成每个权限状态的非规范化缓存甚至可能有意义。因此,您将评估可能基于分层 roles/permissions 的规则,并得出 "User X has permission Y" 的列表。然后,每当您更改用户或权限时,您都会为该实体重新生成缓存,如果您更改角色,您将为所有关联的用户和权限重新生成缓存。
我也不知道我是否会将此建议仅应用于 Neo4j。如果您谈论的是简单的 key/value 查找,那么在性能关键的情况下,许多通用数据库就显得过大了。
您是否打算根据角色进行一些 aggregate/mass 查询(即计算特定角色的人数,列出他们)?
如果不是,并且您只是想检查特定用户是否具有特定角色,那么以我的拙见,它不应该导致难以维护、重要的性能问题(因为您将遍历图形的某些关系,忽略"supernodes" 的绝大多数多重关系)。我会保持简单的设计( "premature optimization is the root of all evil" ;) ),一旦发现问题(在内部,关系存储在类似链表的结构中,因此即使您限制搜索,找到合适的关系也可能需要在超级节点上花费时间到某种关系类型),使用元节点方法拆分角色节点应该可以完成这项工作(在 Learning Neo4j 中有描述)
如果是,说明你有问题。这可能是 RDBMS 更好的领域......使用元节点可能无济于事,因为你仍然需要处理所有这些给 list/count 所有用户......所以将该数据缓存在一个单独的存储中可能只是最好的主意...
在我的 Neo4j 项目中,我有 Role
和 Permission
代表用户角色和权限的实体。系统中的每个 User
都与适当的角色和权限集有关系。
我认为Role
和Permission
是某种超级节点,从性能的角度来看,将来可能会成为一个主要问题。
这种情况的最佳做法是什么?如何重新实现 Role
和 Permission
以避免超级节点可能出现的问题?
我假设您只是将 Neo4j 用作权限查找数据源(如 hasPermission(current_user, 'permission_string')
),而不是绑定到对其他实体的任何查询。这很好,特别是如果您有分层访问模式。如果这不是真的,那么这可能不适用,最好能更清楚地了解您的实体是什么样的。
由于您可能会在整个应用程序中使用权限,如果它们的大小和范围会增加,那么使用某种形式的缓存(如内存存储或 Redis)可能对性能有意义,例如。
为每个用户生成每个权限状态的非规范化缓存甚至可能有意义。因此,您将评估可能基于分层 roles/permissions 的规则,并得出 "User X has permission Y" 的列表。然后,每当您更改用户或权限时,您都会为该实体重新生成缓存,如果您更改角色,您将为所有关联的用户和权限重新生成缓存。
我也不知道我是否会将此建议仅应用于 Neo4j。如果您谈论的是简单的 key/value 查找,那么在性能关键的情况下,许多通用数据库就显得过大了。
您是否打算根据角色进行一些 aggregate/mass 查询(即计算特定角色的人数,列出他们)?
如果不是,并且您只是想检查特定用户是否具有特定角色,那么以我的拙见,它不应该导致难以维护、重要的性能问题(因为您将遍历图形的某些关系,忽略"supernodes" 的绝大多数多重关系)。我会保持简单的设计( "premature optimization is the root of all evil" ;) ),一旦发现问题(在内部,关系存储在类似链表的结构中,因此即使您限制搜索,找到合适的关系也可能需要在超级节点上花费时间到某种关系类型),使用元节点方法拆分角色节点应该可以完成这项工作(在 Learning Neo4j 中有描述)
如果是,说明你有问题。这可能是 RDBMS 更好的领域......使用元节点可能无济于事,因为你仍然需要处理所有这些给 list/count 所有用户......所以将该数据缓存在一个单独的存储中可能只是最好的主意...