使用Neo4j执行任意查询

时间:2014-04-02 19:34:01

标签: database performance neo4j graph-databases

我正在阅读Neo4J发表的一篇论文(前一段时间):http://dist.neo4j.org/neo-technology-introduction.pdf

在第二页到最后一页缺点部分指出Neo4J不适合任意查询。

假设我有具有以下属性的用户节点: NAME,AGE,GENDER

以下关系: LIKE(指向Sports,Technology等NODE)和FRIEND(指向另一个用户)。

Neo4J在查询类似的内容时效率不高:

找到LIKE Sports,Tech,& LYS的FRIENDS(给定节点)读的是OVER_THE_AGE 21。

因此,您必须首先找到USER1的FRIEND边缘,然后找到朋友的LIKE边缘,并确定该节点是否被称为Sports,您必须确定给定朋友的年龄属性是否为> 21.

这是一个糟糕的数据模型吗?特别是对于图形数据库? LIKE关系的原因是,如果您想找到所有喜欢运动的人。

对此更好的数据库选择是什么? Redis,Cassandra,HBase,PostgreSQL?为什么?

有没有人有关于此的经验数据?

1 个答案:

答案 0 :(得分:23)

这是关于图数据库性质的一般性问题。希望其中一个neo4j开发者会跳进这里,但这是我的理解。

您可以将任何数据库视为"自然索引"以某种方式。在关系数据库中,当您在存储中查找记录时,通常下一条记录将紧挨着存储在其中。我们可以将其称为自然指数"因为如果您想要做的是扫描一堆记录,那么关系结构只是从根本上设置,以使其表现非常好。

另一方面,图表数据库通常由关系自然索引。 (Neo4J开发人员,如果需要根据neo4j在磁盘上存储的方式进行改进,请跳入其中)。这意味着通常,图形数据库可以非常快速地遍历关系,但在批量/批量查询上执行效果较差。

现在,我们只讨论相对表现。这是RDBMS样式查询的一个示例。我希望MySQL能够在这个问题上吹走neo4j的性能:

MATCH n WHERE n.name='Abe' RETURN n;

请注意,这根本不利用任何关系,并强制数据库扫描所有节点。您可以通过将其缩小到某个标签或通过索引名称来改进这一点,但通常情况下,如果您有一个MySQL表,那么人们就会#34;用"名称"对于这样的查询,RDBMS会对这些查询产生影响,并且图表的效果会不太好。

好的,这就是缺点。什么是好处?我们来看看这个查询:

MATCH n-[r:foo|bar*..5]->m RETURN m;

这是一个完全不同的野兽。查询的实际操作是匹配n和m之间的可变长度路径。我们如何在关系中这样做?我们可能会设置一个"节点"和"边缘"表,然后在它们之间添加PK / FK关系。然后,您可以编写一个SQL查询,以递归方式连接两个表来遍历" path"。相信我,我已经在SQL中尝试了这一点,它需要向导级技能来表达1到5个跃点之间的""该查询的一部分。此外,RDMBS将在此查询中像狗一样执行,因为它不是非常有选择性,并且递归查询非常昂贵,执行所有这些重复连接。

在这样的查询中,neo4j将会踢RDBMS的屁股。

所以 - 关于任意查询的问题 - 世界上任何系统都不擅长任意查询,也就是说,所有查询。系统有优点和缺点。 Neo4J 可以执行任意查询,但是对于某些类的查询,它不能保证它会比某些替代查询更好。但这种观察是一般性的 - 对于MySQL,MongoDB以及您选择的任何其他内容也是如此。

好的,所以底线和观察结果:

  1. 图形数据库在RDMBS(及其他)表现不佳的一类查询中表现良好。
  2. 图像数据库没有针对质量/批量查询的高性能进行调整,例如我提供的示例。他们可以做到这一点,你可以调整他们的表现以改善那里的东西,但他们永远不会像RDBMS那样好。
  3. 这是因为他们从根本上如何布局,他们如何思考/存储数据。
  4. 那你该怎么办?如果您的问题包含很多关系/路径遍历类型问题,那么图表就是一个巨大的胜利! (即,您的数据是图表,遍历关系对您很重要)。如果您的问题包括扫描大量对象,那么关系模型可能更适合。
  5. 在力量方面使用工具。不要像关系数据库那样使用neo4j,或者如果你试图用螺丝刀敲打钉子,它的表现也差不多。 :)