如何用多个父母代表有向图?


8

http://dirtsimple.org/2010/11/simplest-way-to-do-tree-based-queries.html提供了一种用于从闭包表中插入和删除的算法。

除了节点可能具有多个父节点外,我想对类似的数据结构进行建模。

鉴于:

图#1

如果我们删除,[B, C]我期望最终得到:

图#2

如果我们删除节点,B我期望最终会得到:

图#3

但是,如果使用作者的算法删除链接或节点,则会注意到它标记[D, C, 1]为删除,这是不可取的。

到目前为止我尝试过的

我尝试通过添加一references列来适应原始数据结构,该列指示在两个节点之间有多少种行进方式。在上面的例子中,你可以从旅行AC要么通过B或通过D。这个想法本来是要B删除的,从A到的路径C会保留,引用计数从2减少到1。从理论上讲这很好,但是我不知道如何使实现正常工作,现在我想知道是否这是有可能的(数据结构可能没有足够的信息来确定要删除的行)。

我在问什么

您将如何调整封闭表来支持多位家长?您会推荐哪些替代数据结构?https://stackoverflow.com/q/4048151/14731包含此类数据结构的详尽列表,但尚不清楚哪个数据结构支持(或最适合)多个父级。


那么,您尝试了什么?那references列是什么?
ypercubeᵀᴹ

我不相信有人在您的方案中使用闭包表。闭包表对许多基于树的应用程序很有用,但是这个问题暗示了DAG(有向无环图)的限制要少得多。这是一个适合硕士论文的主题,就像涉及数据库的许多事情一样,最佳解决方案将在很大程度上取决于您确切的特定用例。可能会帮助您开始使用。
Avarkx 2014年

哪个分贝软件?
尼尔·麦圭根

@ NeilMcGuigan,H2和PostgreSQL,尽管显然我更喜欢与数据库无关的解决方案。
吉利2014年

Answers:


3

通常创建一个节点表和一个关系表。有向图不是真正的分层结构,它们可以具有循环,这会使查询更加困难。但是,如果您将DAG视为广义树(即,允许多个父级但仍严格分层的树),而将有向图看作是广义DAG(即,像DAG但非严格分层的树),则事情会变得容易得多。

因此,对于一个非常简单的PostgreSQL解决方案,我们可以执行以下操作:

CREATE TABLE node (
    id serial primary key,
    payload jsonb not null
);

CREATE TABLE relationship (
    id serial primary key,
    relationship_type text not null,
    from_node int references node(id) not null,
    to_node int references node(id) not null,
    payload jsonb not null
);

然后,您可以查询如下内容:

with recursive dg as (
    select n.id as node_id, null::Int as parent, array[n.id] as path
      from node n
    union all
    select to_node, from_node, path || to_node
      FROM relationship
      JOIN dg on dg.node_id = from_node AND NOT from_node = ANY(path)
)
select * from dg;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.