Comment représenter un graphique dirigé avec plusieurs parents?

8

http://dirtsimple.org/2010/11/simplest-way-to-do-tree-based-queries.html fournit un algorithme pour l'insertion et la suppression d'une table de fermeture.

Je voudrais modéliser une structure de données similaire, sauf que les nœuds peuvent avoir plusieurs parents.

Donné:

Graphique # 1

Si nous supprimons, [B, C]je m'attends à me retrouver avec:

Graphique # 2

et si nous supprimons le nœud, Bje m'attends à finir avec:

Graphique # 3

Cependant, si vous utilisez l'algorithme de l'auteur pour supprimer des liens ou des nœuds, vous remarquerez qu'il marque [D, C, 1]pour la suppression, ce qui n'est pas souhaitable.

Ce que j'ai essayé jusqu'à présent

J'ai essayé d'adapter la structure de données d'origine en ajoutant une referencescolonne qui indique le nombre de façons de voyager entre deux nœuds. Dans l'exemple ci-dessus, vous pouvez voyager de Aà Cà travers Bou à travers D. L'idée aurait été que lors de la Bsuppression, le chemin de Aà Cest conservé et le nombre de références diminue de 2 à 1. C'était sympa en théorie, mais je ne pouvais pas comprendre comment faire fonctionner l'implémentation et maintenant je me demande si c'est tout à fait possible (la structure de données peut ne pas contenir suffisamment d'informations pour déterminer les lignes à supprimer).

Ce que je demande

Comment adapteriez-vous les tables de fermeture pour soutenir plusieurs parents? Quelles structures de données alternatives recommanderiez-vous? https://stackoverflow.com/q/4048151/14731 contient une liste exaustive de ces structures de données, mais il n'est pas clair lesquelles prennent en charge (ou sont les meilleures pour) plusieurs parents.

Gili
la source
Alors, qu'as-tu essayé? Et quelle est la referencescolonne?
ypercubeᵀᴹ
Je ne crois pas qu'on pourrait adapter les tables de fermeture dans votre scénario. Les tables de fermeture sont bonnes pour de nombreuses applications basées sur des arbres, mais cette question fait allusion à un type de DAG (Directed Acyclic Graph) beaucoup moins restrictif. C'est un sujet qui pourrait convenir à une thèse de maîtrise et comme tant de choses en ce qui concerne les bases de données, une solution optimale dépendra fortement de votre cas d'utilisation précis et spécifique. Ceci ou cela pourrait vous aider à démarrer.
Avarkx
Quel logiciel db?
Neil McGuigan
@NeilMcGuigan, H2 et PostgreSQL bien que je préfère évidemment une solution agnostique DB.
Gili

Réponses:

3

Créez généralement une table de nœuds et une table de relations. Les graphiques dirigés ne sont pas vraiment hiérarchiques et peuvent avoir des boucles, ce qui rend les requêtes plus difficiles. Mais si vous considérez un DAG comme un arbre généralisé (c'est-à-dire un arbre qui autorise plusieurs parents mais est toujours strictement hiérarchique) et un graphique dirigé comme étant un DAG généralisé (c'est-à-dire comme un DAG mais pas strictement hiérarchique), les choses deviennent plus faciles.

Donc, pour une solution PostgreSQL très simple, nous pourrions faire quelque chose comme:

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
);

Ensuite, vous pouvez interroger quelque chose comme ceci:

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;
Chris Travers
la source