cde*_*zaq 11 database-design neo4j graph-databases titan
我刚刚进入图形数据库,我似乎一直在遇到一个问题,决定使用"索引节点"还是"索引属性"来跟踪"节点类型"之类的事情.由于到目前为止我没有真正的经验,我没有任何信息可以作出决定,这两种方法似乎同样有效.
因此,问题是:两种方法之间的权衡是什么,以及规模(即节点数量)如何影响决策?
对于示例场景,我们假设有两种类型的"事物":User
并且Product
,用户节点和产品节点之间的边缘并不重要,但我们关心的是我们是否需要type: User
和type: Product
每个节点上的属性或者,如果我们希望每个节点分别具有指向User
节点和Product
节点的边缘.
在哪种情况下哪种方法更好?
注意:我特别关注Neo4j和Titan,但我认为这也会更普遍地应用.
小智 18
首先,您需要问自己:顶点/节点的类型是否需要编入索引?即你需要按类型检索顶点/节点,比如说,从图中检索所有"用户"顶点,还是需要回答查询,首先检索给定类型的所有顶点然后过滤/处理这些顶点?
如果这个问题的答案是肯定的,那么我建议你将类型存储为索引的字符串属性.或者,如果您使用基于jvm的语言进行开发,则可以定义类型枚举,并将其用作属性类型,以进行更多类型安全和自动错误检查.Titan支持任意用户定义的类/枚举作为属性类型,并将为低内存占用而压缩它们.
但是,这种方法的缺点是,由于您正在构建低选择性指数,因此无法扩展.这意味着可能会有很多类型为'user'或'product'的顶点,并且所有顶点都需要分别与'user'或'product'的索引条目相关联.这使得维护和查询这个索引非常昂贵且难以扩展(想象一下facebook有一个'类型'索引:'photo'条目下面会有数十亿个顶点).如果您(还)不关心缩放,那么这可以工作.
如果问题的答案为否,那么我建议将类型建模为图中的顶点/节点.即,具有"用户"顶点和"产品"顶点以及从每个用户到"用户"顶点标记为"类型"的边缘等.
这种方法的优点是您可以使用图形来建模数据,而不是在数据库之外使用字符串值来表示关键的类型信息.在构建应用程序时,图形数据库将成为其核心组件并持续很长时间.随着编程语言和开发人员的不断变化,您不希望数据建模和类型信息与他们一起使用,并且面临一个问题:"SPECIAL_USER是什么意思?" 相反,有一个SPECIAL_USER顶点并向其添加起源信息,即创建此类型的人员,它代表什么以及简短描述 - 所有这些都在数据库中.
这种方法的一个问题是,随着应用程序的扩展,"用户"和"产品"顶点会有很多边缘事件.换句话说,您正在创建创建缩放问题的超级节点.这就是Titan引入单向边缘概念的原因.单向边缘就像网络上的链接:起始顶点指向另一个顶点,但该顶点不知道边缘.由于您不希望从"用户"顶点遍历到所有用户顶点,因此除了获得可伸缩性和性能之外,您不会失去任何东西.