Performance Neo4j数据建模:私有节点、丰富关系、锁
使用的版本:带Spring-data的Neo4j 3.0.6-POJO映射的Neo4j 4.2.0.M1 我试图选择如何使用neo4j建模数据,并比较不同解决方案的优缺点 要求:Performance Neo4j数据建模:私有节点、丰富关系、锁,performance,neo4j,scalability,data-modeling,spring-data-neo4j-4,Performance,Neo4j,Scalability,Data Modeling,Spring Data Neo4j 4,使用的版本:带Spring-data的Neo4j 3.0.6-POJO映射的Neo4j 4.2.0.M1 我试图选择如何使用neo4j建模数据,并比较不同解决方案的优缺点 要求: 电影具有元数据的动态列表(元数据有3个属性:“键”、“值”、“区域设置”)。电影的元数据数量事先不知道,可能的密钥也不知道。它们必须与其他电影技术属性分开,因为它们是本地化的,并且被视为业务数据 元数据归电影所有,并始终从电影中访问。它们不能与其他电影共享 必须能够对元数据值进行快速获取查询 电影元数据示例: Mo
- 电影具有元数据的动态列表(元数据有3个属性:“键”、“值”、“区域设置”)。电影的元数据数量事先不知道,可能的密钥也不知道。它们必须与其他电影技术属性分开,因为它们是本地化的,并且被视为业务数据
- 元数据归电影所有,并始终从电影中访问。它们不能与其他电影共享
- 必须能够对元数据值进行快速获取查询
Movie metadata
locale 'en_GB':
title: 'Jurassic Park'
description: 'description in english'
locale 'fr_FR':
description: 'description en francais'
locale 'none':
actor: 'Jeff Goldblum'
解决方案A
- 每个元数据一个节点(每个节点有3个属性:“键”、“值”、“区域设置”)
- 缺点:私有概念有待实施(由于spring-data-neo4j/neo4j ogm不支持,删除需要手动管理的元数据孤立节点)
- 每个区域设置一个唯一的节点(带有1个属性:“locale”)(例如:“en_GB”)
- 元数据为丰富关系(具有两个关系属性:“键”、“值”)
- 缺点:要创建关系,必须在区域设置节点上设置一个锁
电影
节点的属性(无需使用键和值)。这是最简单的方法,它避免了锁定问题,并最小化了所需的节点和关系的数量。您可以随时向节点自由添加更多属性。这种方法还允许您为特定的Movie
属性添加索引,这些属性在开始查询时需要快速访问
例如:
CREATE (m:Movie {id: 123, title: 'Men in black', director: 'Barry Sonnenfeld'});
MATCH (m:Movie {id: 123})
OPTIONAL MATCH p=(m)-->()
DELETE p;
[更新]
如果需要将“元数据”与“数据”清晰地分开,并且还需要能够本地化元数据(包括区域设置
属性的规范),则可以将每个电影
节点与每个区域设置的单个元数据
节点关联。元数据
节点将直接包含特定电影
节点的单个区域设置的所有元数据属性
密码可用于执行“级联删除”。例如:
CREATE (m:Movie {id: 123, title: 'Men in black', director: 'Barry Sonnenfeld'});
MATCH (m:Movie {id: 123})
OPTIONAL MATCH p=(m)-->()
DELETE p;
您可以直接将“元数据”存储为每个电影
节点的属性(无需诉诸键
和值
)。这是最简单的方法,它避免了锁定问题,并最小化了所需的节点和关系的数量。您可以随时向节点自由添加更多属性。这种方法还允许您为特定的Movie
属性添加索引,这些属性在开始查询时需要快速访问
例如:
CREATE (m:Movie {id: 123, title: 'Men in black', director: 'Barry Sonnenfeld'});
MATCH (m:Movie {id: 123})
OPTIONAL MATCH p=(m)-->()
DELETE p;
[更新]
如果需要将“元数据”与“数据”清晰地分开,并且还需要能够本地化元数据(包括区域设置
属性的规范),则可以将每个电影
节点与每个区域设置的单个元数据
节点关联。元数据
节点将直接包含特定电影
节点的单个区域设置的所有元数据属性
密码可用于执行“级联删除”。例如:
CREATE (m:Movie {id: 123, title: 'Men in black', director: 'Barry Sonnenfeld'});
MATCH (m:Movie {id: 123})
OPTIONAL MATCH p=(m)-->()
DELETE p;
tl,dr:使用方法A。不要使用孤立的:Locale
节点,除了定期清理之外,它们对查询性能没有影响
您的方法“A”是迄今为止更好的解决方案。您确实需要将该数据移出:Movie
节点,这是正确的,因为它必须是嵌套映射或映射列表,节点属性不支持这两者。对于存储,您可以将它们转换为列表映射,但这将非常难以查询,更不用说快速查询了。您对“孤立”节点的关注是不实际的;它对查询性能和数据大小的影响很小(如果有的话),而且在任何情况下都非常容易定期清理以减轻您的负担
MATCH (x:Locale) WHERE NOT (x) <- [:METADATA] - () DETACH DELETE x
MATCH(x:Locale)WHERE NOT(x)tl,dr:使用方法A。不要使用孤立的:Locale
节点,除了定期清理之外,它们对查询性能没有影响
您的方法“A”是迄今为止更好的解决方案。您确实需要将该数据移出:Movie
节点,这是正确的,因为它必须是嵌套映射或映射列表,节点属性不支持这两者。对于存储,您可以将它们转换为列表映射,但这将非常难以查询,更不用说快速查询了。您对“孤立”节点的关注是不实际的;它对查询性能和数据大小的影响很小(如果有的话),而且在任何情况下都非常容易定期清理以减轻您的负担
MATCH (x:Locale) WHERE NOT (x) <- [:METADATA] - () DETACH DELETE x
MATCH(x:Locale)WHERE NOT(x)进一步了解元数据会有所帮助。每个用户是否都有自己关于电影的元数据,或者它不是特定于用户的?有什么原因不能将元数据作为属性存储在电影节点上吗?是否有一些元数据的作用类似于标记(意味着您可以从元数据查询到电影)?或者,您是否只从电影中访问元数据,而不是直接访问元数据?不,元数据不是特定于用户的。但是它们是本地化的(我没有提到这一点是为了简化)。我认为在电影节点上存储元数据的唯一方法是insi