将MySQL和Neo4j一起使用是一个好主意吗?

时间:2010-03-29 23:16:06

标签: architecture mysql hierarchical-data neo4j graph-databases

我将使用许多类似的项目(数百万)创建一个应用程序,我想将它们存储在MySQL数据库中,因为我想做大量的统计信息并搜索特定列的特定值。 / p>

但与此同时,我将存储所有项目之间的关系,这些项目在许多连接的二叉树结构(传递闭包)中相关,而关系数据库并不擅长这种结构,所以我会喜欢在Neo4j中存储所有关系,这些关系对这类数据有很好的表现。

我的计划是除了MySQL数据库中的关系以及存储在Neo4j数据库中的item_id的所有关系之外的所有数据。当我想查找树时,我首先在Neo4j中搜索树中的所有item_id:s,然后在MySQL数据库中搜索查询中的所有指定项,如下所示:

SELECT * FROM items WHERE item_id = 45 OR item_id = 345435 OR item_id = 343 OR item_id = 78 OR item_id = 4522 OR item_id = 676 OR item_id = 443 OR item_id = 4255 OR item_id = 4345

这是个好主意,还是我错了?之前我没有使用过图形数据库。有没有更好的方法解决我的问题?在这种情况下,MySQL查询将如何执行?

4 个答案:

答案 0 :(得分:26)

很少有人想到这个:

我会尝试对Neo4j域模型进行建模,以包含图中每个节点的属性。通过将数据分成两个不同的数据存储,您可能会限制一些您可能想要执行的操作。

我想这取决于你将如何处理你的图表。例如,如果要查找连接到特定节点的所有节点,其属性(即名称,年龄等等)是特定值,您首先必须在MySQL数据库中找到正确的节点ID然后进入Neo4j的?当你在Neo4j中做到这一切时,这看起来似乎很慢而且过于复杂。所以问题是:在遍历图表时是否需要节点的属性?

您的数据会更改还是静态?通过拥有两个独立的数据存储,这将使问题复杂化。

虽然使用MySQL数据库生成统计信息可能比在Neo4j中执行所有操作更容易,但遍历图形以查找满足已定义条件的所有节点所需的代码并不过分。这些统计数据应该会推动您的解决方案。

我不能评论MySQL查询的性能来选择节点ID。我想这取决于您需要选择多少个节点以及索引策略。我同意在遍历图表时的性能方面。

这是一篇很好的文章:MySQL vs. Neo4j on a Large-Scale Graph Traversal在这种情况下,当他们说大,他们只意味着一百万个顶点/节点和四百万个边。所以它甚至不是特别密集的图形。

答案 1 :(得分:11)

关系数据库可以处理图结构。他们中的一些甚至可以适度地处理它们(就像关系数据库一样优雅!)。

关系数据库中常规图处理的关键是recursive common table expression(RCTE),它基本上允许您通过组合查询来迭代地(不递归地,尽管名称)扩展对一组行的查询。选择一组根行和一个查询,该查询定义到目前为止所选行的邻居。语法有点笨拙,但它是通用且强大的。

PostgreSQL,Firebird,SQL Server以及DB2中显然支持RCTE。 Oracle有一个不同但等价的结构;我读过最新版本支持适当的RCTE。 MySQL不支持RCTE。如果你没有和MySQL结合,我会建议你考虑使用PostgreSQL,它基本上是一个更好的数据库。

然而,听起来你不需要支持一般图形,只需要树木。在这种情况下,您可以选择更具体的选项。

一个是经典而非心灵弯曲nested sets

更简单的方法是存储每行的路径:这是一个表示行在树中的位置的字符串,并且具有以下属性:节点的路径是任何子节点的路径的前缀,这使得你非常有效地做了关于祖先的各种查询(“节点A是节点B的子节点?”,“什么是节点A和节点B的最低共同祖先?”等)。例如,您可以通过从根运行树来构造行的路径,并使用斜杠连接在路上遇到的行的ID。这很容易构建,但如果重新排列树,则需要注意维护。使用路径列,您只需添加and path like '23/%'即可将查询限制为给定树,其中23是根ID。

因此,尽管图形数据库可能是存储和查询图形数据的最佳方式,但它并不是唯一的选择,我建议您权衡使用一个数据库的优势与将所有数据放在一个数据库中的优势数据库中。

答案 2 :(得分:6)

我主要使用Binary Nerd,但想添加变体。您可以将实时数据存储在Neo4j中,然后提取统计/报告所需的数据并放入MySQL。对于搜索,如果符合您的需要,我会选择Neo4j-Lucene integration

答案 3 :(得分:4)

您可以使用IN:

改进查询
SELECT *
FROM items
WHERE item_id IN (45, 345435, 343, 78, 4522, 676, 443, 4255, 4345)

关系数据库在存储树结构方面也不是很糟糕。当然,MySQL缺少一些可以使其更容易的功能,但大多数其他数据库都支持它。 Oracle有CONNECT BY。大多数主流RDBMS都有某种形式的递归查询 - MySQL是一个值得注意的例外。也许您可以看看PostgreSQL,看看它是否符合您的需求?