54

我将制作一个包含许多类似项目(数百万)的应用程序,并且我想将它们存储在 MySQL 数据库中,因为我想做很多统计数据并搜索特定列的特定值。

但同时,我将存储所有项目之间的关系,它们在许多连接的二叉树状结构(传递闭包)中相关,而关系数据库不擅长这种结构,所以我想存储Neo4j 中所有对此类数据都有良好性能的关系。

我的计划是将除了 MySQL 数据库中的关系和所有关系之外的所有数据都item_id存储在 Neo4j 数据库中。当我想查找一棵树时,我首先在 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

4 回答 4

30

对此的一些想法:

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

我想这取决于您将使用图表做什么。例如,如果您想查找连接到特定节点的所有节点,其属性(即名称、年龄……等等)是特定值,您是否首先必须在 MySQL 数据库中找到正确的节点 ID,然后进入新4j?当您可以在 Neo4j 中完成所有这些操作时,这似乎很慢而且过于复杂。那么问题来了:遍历图的时候需要节点的属性吗?

您的数据会改变还是静态的?拥有两个独立的数据存储会使事情复杂化。

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

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

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

于 2010-03-29T23:58:55.600 回答
12

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

关系数据库中通用图形处理的关键是递归公用表表达式(RCTE),它基本上允许您通过组合选择根集的查询迭代地(不是递归地,尽管有名称)在一组行上展开查询的行数和一个查询,该查询定义了迄今为止选择的行的邻居。语法有点笨拙,但它通用且功能强大。

RCTE 在 PostgreSQL、Firebird、SQL Server 和 DB2 中都受支持。Oracle 有一个不同但等效的结构。我读过最新版本支持适当的 RCTE。MySQL 不支持 RCTE。如果你不喜欢 MySQL,我会敦促你考虑使用 PostgreSQL,它基本上是一个更好的数据库。

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

一个是经典但相当令人费解的嵌套集

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

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

于 2012-08-08T17:47:02.593 回答
6

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

于 2010-03-30T08:30:06.110 回答
4

您可以使用 IN 改进查询:

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

关系数据库不擅长存储树结构也不完全正确。当然 MySQL 缺少一些使它更容易的功能,但大多数其他数据库都很好地支持它。甲骨文有CONNECT BY. 大多数主流 RDBMS 都有某种形式的递归查询 - MySQL 是一个明显的例外。也许您可以看一下 PostgreSQL,看看它是否满足您的需求?

于 2010-03-29T23:29:29.220 回答