3

场景:一个简单的地址簿,用户可以创建自己的联系人,并通过分组添加他们来组织他们。联系人可能有多个地址。图形数据库模式设计 - 这适合neo4j吗?

我创建了如下图: [架构设计] [1]

我想查询所有谁放置在X组的联系人和生活在Y国。

这种模式设计是否足够用于这些目的(我想使用neo4j数据库)?

回答

3

看起来像country的概念应该是图中的头等公民,因为您的查询取决于它。图模型设计通常会受到查询模式的影响。

因此,我建议每个国家都有一个节点标记为Country,并将Address节点与:LOCATED_IN节点连接到该国家。 (因此从地址节点中删除国家属性)。

与该改变您的查询一样简单:

MATCH (:Group{name:'family'})<-[:placed_in_group]-(contact)-[:lives-at]->()-[:LOCATED_IN]->(:Country{name:'US'}) 
RETURN contact 
+0

谢谢!我很感激。 – Moody 2015-04-01 08:30:01

+0

顺便说一下,斯蒂芬,你有没有任何机会对这种情况下的密集节点影响性能的统计数据进行任何比较?假设我有'Prop'属性(可能是索引)〜20K节点,我查询数据库只是为了找到所有具有'Prop'的节点,然后过滤具体的'Prop'值(可能的Prop值的数量是相当小的:我可以枚举它们全部(比如1000个可能的值))。如果我创建一个标签“Prop”并创建20K关系,它会是一个更好的设计吗?在性能方面更好的选择是什么? – tkroman 2015-04-02 12:33:20

+0

您需要注意,如果您将很多地址同时连接到同一个国家,则可能会遇到锁定问题。创建关系意味着锁定其开始和结束节点。不过,通过在全国各地设立几个“对接节点”,您可以轻松解决这个问题。该地址然后选择一个对接节点,例如通过对线程ID进行一致性散列 - 这可以防止锁定问题。在查询方面,我没有可用的测量。 – 2015-04-02 12:49:58

2

一种选择是具有地址的另一个节点的国家,由斯特凡的Armbruster指出。如果您不想更改数据结构,只需在Address的“国家/地区”字段中添加一个索引即可。那么你可以有一个查询

MATCH (:Group{name:'family'})<-[:placed_in_group]-(contact)-[:lives-at]->(:Address{country:'US'})

+0

谢谢。我欣赏小费! – Moody 2015-04-01 08:30:07