当我接近这个时,我试图对这两种技术进行比较,我想知道你们是否已经有过处理任何一种或两种技术的经验?在处理类似的用例时,我主要对性能数字感兴趣 .
同意Marko所说的一切,人们可以更进一步,并认为在图数据库世界中,本地索引可以(甚至应该)替换全局索引 . 在我看来,图形数据模型的最大优势在于它允许您将数据模型编码到图形拓扑中,在灵活性,易于演化和性能方面获得定性优势 . 考虑到这一点,我认为Neo4j中的标签实际上会减损这一切;将标签重新划分为一个节点,其中相邻边指向具有该标签的源,这更符合“架构是图形”的理念 .
当然,如果您的引擎缺少本地索引,我们又回到了超级节点问题 . 但是如果你确实拥有它们(我认为某些东西应该被称为图形数据库),你可以轻松地将标签转换为节点 L ,并为那些顶点创建指向该节点的关系 . 希望标有 L
L
v -[L]-> L
意思是 v 标签为 L . 现在,如果你希望Titan中的这个行为像Neo4j标签,只需使 -[L]-> 关系为"manyToOne"(参见Titan cardinality constraints)并创建一个以顶点为中心的索引 . 这种模式让您可以获得标签等所有功能;您可以
v
-[L]->
有效地将其用作与该标签相关的属性的命名空间
在一个标签内对元素进行排序
容易标记嵌套而不会损失性能(只需使用复合键)
将标签 L 的声明与如何使用标记的元素分开
这两个概念之间的区别在于全局索引和本地索引之间的差异 .
据我了解, Neo4j 顶点标签允许您通过"categories"顶点分解索引空间 . 这样, O(log(|V|)) 查找现在是 O(log(|V|/c)) ,其中 c 是您在顶点集上的类别/标签数量(方程式)假设每个类别中的顶点数量相等 . 因此,顶点标签有助于全局索引调用,因为它是 V 的函数 .
O(log(|V|))
O(log(|V|/c))
c
V
接下来, Titan 的以顶点为中心的索引对顶点的入射边进行排序和索引 . 通过入射到顶点的标签/属性查找特定边的成本是 O(log(inc(v))) ,其中 inc(v) 是设置为顶点 v 的入射边的大小 . 因此,以顶点为中心的索引是局部索引,因为这是 v 的函数 .
O(log(inc(v)))
inc(v)
据我了解, Neo4j 不支持以顶点为中心的索引 . 你看到这个概念目前在 Titan , OrientDB 和 TinkerGraph (......和RDF存储也以这种方式排序 - 通过spog配对) . 接下来,所有已知的图形数据库都支持全局索引,(我相信只有 Neo4j 和 OrientDB ),通过标签的概念支持顶点集分区 .
再次,假设我的假设在 Neo4j 中使用顶点标签是正确的,我们讨论的是两种不同的用例 - 全局与本地索引 . 从超级节点问题的角度来看,全局索引不会平息遍历大顶点的问题,而这是本地顶点中心索引的唯一目的 .
您可以在这里阅读有关超级节点问题和以顶点为中心的索引:http://thinkaurelius.com/2012/10/25/a-solution-to-the-supernode-problem/
标签可以提供一些设计模式,通过对图表进行去密化来提高性能 . 例如:它们消除了对类型节点的需求,这通常会变得非常密集 . 标签可以选择与唯一索引相关联 . 在这里,索引属性的能力并不新鲜,但能够唯一地约束它 . 如果您以前在应用程序中工作,则可以通过让数据库处理此问题来获得性能提升 . (这样做当然要方便得多 . )最后,如果你没有为标签分配一个唯一的索引,它仍然会被索引,以帮助某些类型的查询的性能(例如“给我所有的有标签的节点“)
尽管如此,虽然标签在某些情况下可能对性能有所帮助,但它们在易于使用的基础上更多地介绍了它们 . 我们刚刚开始使用Neo4j 2.1,它专门解决密集节点性能(我知道你一直在等待的东西),以及其他性能和可扩展性改进......包括删除(出于所有实际目的消除)大小上限 .
菲利普
3 回答
同意Marko所说的一切,人们可以更进一步,并认为在图数据库世界中,本地索引可以(甚至应该)替换全局索引 . 在我看来,图形数据模型的最大优势在于它允许您将数据模型编码到图形拓扑中,在灵活性,易于演化和性能方面获得定性优势 . 考虑到这一点,我认为Neo4j中的标签实际上会减损这一切;将标签重新划分为一个节点,其中相邻边指向具有该标签的源,这更符合“架构是图形”的理念 .
当然,如果您的引擎缺少本地索引,我们又回到了超级节点问题 . 但是如果你确实拥有它们(我认为某些东西应该被称为图形数据库),你可以轻松地将标签转换为节点
L
,并为那些顶点创建指向该节点的关系 . 希望标有L
v -[L]-> L
意思是
v
标签为L
. 现在,如果你希望Titan中的这个行为像Neo4j标签,只需使-[L]->
关系为"manyToOne"(参见Titan cardinality constraints)并创建一个以顶点为中心的索引 . 这种模式让您可以获得标签等所有功能;您可以有效地将其用作与该标签相关的属性的命名空间
在一个标签内对元素进行排序
容易标记嵌套而不会损失性能(只需使用复合键)
将标签
L
的声明与如何使用标记的元素分开这两个概念之间的区别在于全局索引和本地索引之间的差异 .
据我了解, Neo4j 顶点标签允许您通过"categories"顶点分解索引空间 . 这样,
O(log(|V|))
查找现在是O(log(|V|/c))
,其中c
是您在顶点集上的类别/标签数量(方程式)假设每个类别中的顶点数量相等 . 因此,顶点标签有助于全局索引调用,因为它是V
的函数 .接下来, Titan 的以顶点为中心的索引对顶点的入射边进行排序和索引 . 通过入射到顶点的标签/属性查找特定边的成本是
O(log(inc(v)))
,其中inc(v)
是设置为顶点v
的入射边的大小 . 因此,以顶点为中心的索引是局部索引,因为这是v
的函数 .据我了解, Neo4j 不支持以顶点为中心的索引 . 你看到这个概念目前在 Titan , OrientDB 和 TinkerGraph (......和RDF存储也以这种方式排序 - 通过spog配对) . 接下来,所有已知的图形数据库都支持全局索引,(我相信只有 Neo4j 和 OrientDB ),通过标签的概念支持顶点集分区 .
再次,假设我的假设在 Neo4j 中使用顶点标签是正确的,我们讨论的是两种不同的用例 - 全局与本地索引 . 从超级节点问题的角度来看,全局索引不会平息遍历大顶点的问题,而这是本地顶点中心索引的唯一目的 .
您可以在这里阅读有关超级节点问题和以顶点为中心的索引:
http://thinkaurelius.com/2012/10/25/a-solution-to-the-supernode-problem/
标签可以提供一些设计模式,通过对图表进行去密化来提高性能 . 例如:它们消除了对类型节点的需求,这通常会变得非常密集 . 标签可以选择与唯一索引相关联 . 在这里,索引属性的能力并不新鲜,但能够唯一地约束它 . 如果您以前在应用程序中工作,则可以通过让数据库处理此问题来获得性能提升 . (这样做当然要方便得多 . )最后,如果你没有为标签分配一个唯一的索引,它仍然会被索引,以帮助某些类型的查询的性能(例如“给我所有的有标签的节点“)
尽管如此,虽然标签在某些情况下可能对性能有所帮助,但它们在易于使用的基础上更多地介绍了它们 . 我们刚刚开始使用Neo4j 2.1,它专门解决密集节点性能(我知道你一直在等待的东西),以及其他性能和可扩展性改进......包括删除(出于所有实际目的消除)大小上限 .
菲利普