Graph 如何在关系数据库中持久化图形数据结构?

Graph 如何在关系数据库中持久化图形数据结构?,graph,Graph,我考虑过创建一个顶点表和一个边表,但是在内存中构建图和遍历子图需要大量的查找吗?我希望避免过多的数据库读取。有没有其他方法可以持久化图形 旁注:我听说过Neo4j,但我的问题是如何在标准数据库中概念性地表示图形。不过,我对一些NoSQL解决方案持开放态度,比如mongodb。答案很不幸:您的考虑在每一点上都是完全正确的。必须将节点(顶点)存储在一个表中,以及引用FromNode和ToNode的边,才能将图形数据结构转换为关系数据结构。你也是对的,这会导致大量的查找,因为你不能将它划分成子图,而子

我考虑过创建一个顶点表和一个边表,但是在内存中构建图和遍历子图需要大量的查找吗?我希望避免过多的数据库读取。有没有其他方法可以持久化图形


旁注:我听说过Neo4j,但我的问题是如何在标准数据库中概念性地表示图形。不过,我对一些NoSQL解决方案持开放态度,比如mongodb。

答案很不幸:您的考虑在每一点上都是完全正确的。必须将节点(顶点)存储在一个表中,以及引用FromNode和ToNode的边,才能将图形数据结构转换为关系数据结构。你也是对的,这会导致大量的查找,因为你不能将它划分成子图,而子图可能会被立即查询。您必须从一个节点遍历到另一个节点,从一个节点遍历到另一个节点,以此类推(当SQL处理集合时,以递归方式)

重点是…

关系、面向图形、面向对象和基于文档是满足不同需求的不同类型的数据结构。这就是为什么会出现这么多不同的NoSQL数据库(大多数都是简单的文档存储),因为以关系方式组织大数据毫无意义

备选方案1-面向图形的数据库

但也有面向图形的NoSQL数据库,这使得图形数据模型成为一级公民,就像我现在正在玩的一样。它的优点是,尽管它将数据持久化为图形,但它仍然可以以关系的、甚至面向对象的或面向文档的方式使用(即,通过使用普通的旧SQL进行查询)。然而,这无疑是从中获取数据的最佳方式

备选方案2-在内存中使用图形


当涉及到快速路由时,路由框架如在内存中构建完整的图(数十亿个节点)。因为Graphhopper使用了GraphStore的MemoryMapped实现,它甚至可以在只需要一些MB内存的Android设备上运行。启动时,完整的图形从数据库读取到内存中,然后在那里进行路由,因此您无需查找数据库。

我遇到了同样的问题,决定最终采用以下结构,需要两个数据库查询,然后剩下的工作在内存中:

将节点存储在表中,并使用每个节点记录引用图形:

Table Nodes

id  | title | graph_id
---------------------
105 | node1 | 2
106 | node2 | 2
还将边存储在另一个表中,并再次引用这些边与每条边所属的图形:

Table Edges

id | from_node_id | to_node_id | graph_id
-----------------------------------------
1  | 105          | 106        | 2
2  | 106          | 105        | 2
使用一个查询获取所有节点,然后使用另一个查询获取所有边


现在,构建存储图形的首选方法(例如,邻接列表)并继续应用程序流程。

在前面的内容中添加MS SQL Server添加的事实

它遵循所描述的具有节点表的模式(应使用特殊的“作为节点”和“作为边”关键字创建)。

它还引入了新的MATCH关键字“支持模式匹配和通过图进行遍历”,如下所示(在下面的示例中,friend是edge表的名称):


还有一套非常好的文章。

为了给你提供有价值的建议,我需要你方提供更多信息。我们讨论了多少个节点和多少个关系?我想是几十亿个节点。就像我说的,这主要是概念性的,但我很好奇如何扩展大量的记录。我想我脑子里有非常大的图形。不是开源的,但它正是你想要的:新的Aster 6.0在关系数据库中带有图形引擎——它被称为SQL-GR,旨在对存储在关系表中的图形(在Aster中)使用现有的和新的函数:以节点表和边缘表表示。我了解到diaspora确实使用RDBMS进行图形化,但不确定要使其支持庞大的基础(如70%的facebook)需要什么硬件要求,或者甚至可能需要什么硬件要求。+1顺便说一句:“图形数据库”和“关系数据库”之间真正的唯一区别是查找的实现。如果节点表中引用的边列表是通过直接指针到达的,则可以将其称为graph DB,尽管数据仍然可以组织在表中!因此,如果这种查找是log(n)per edge list或甚至per edge,那么人们称之为“关系数据库”,遍历图的成本相当高(与存储是否映射或内存或其他情况无关)。@Karussell值得注意的是,大多数SQL数据库都支持基于哈希的索引,其中边/顶点查找是O(1),就像图形数据库一样。O(log(n))查询时间通常与基于B树的索引相关联,这些索引通常在数据排序很重要时使用(对于边/顶点ID通常不相关)。您可能是对的。与直接指针相比,基于散列的索引仍然有开销(空间和时间)。但可能DBs使用的技术非常相似,只是营销宣传使他们看起来非常不同:)
SELECT Person2.name AS FriendName
FROM Person Person1, friend, Person Person2
WHERE MATCH(Person1-(friend)->Person2)
AND Person1.name = 'Alice';