IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PostgreSQL Discussion :

[pl/pgsql] pb gestion d'arborescence


Sujet :

PostgreSQL

  1. #1
    Membre du Club
    Inscrit en
    Janvier 2006
    Messages
    71
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 71
    Points : 64
    Points
    64
    Par défaut [pl/pgsql] pb gestion d'arborescence
    Bonjour à tous,

    Je dispose d’une structure hiérarchique, ce qu’on appelle vulgairement un arbre, modélisé par une table dont chaque enregistrement possède un champ « père » qui est une référence à l’id du noeud père dans l’arbre (la racine de l’arbre à ce champ à NULL).

    Je me suis cassé la tête pour écrire une fonction en pl/pgsql qui retourne toutes les feuilles correspondant à un noeud donné (en entrée : un id, en sortie : un set of records). Ma méthode a consisté à écrire une fonction principale « enfants » qui crée une table auxiliaire puis qui appelle une fonction « enfants_aux » qui s’occupe de la récursivité proprement dite (et qui fait des INSERT dans la table créée précédemment). Après avoir retourné tous les éléments de la table auxiliaire, la fonction principale détuit la table auxiliaire.

    En plus d’être lourde, cette méthode est aussi insatisfaisante parce que je suis obligé de recharger ma fonction avant chaque appel (je travaille avec pgAdmin III), sinon j’ai une réponse cryptique du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ERROR:  relation with OID 18610 does not exist
    CONTEXT:  PL/pgSQL function "enfants" line 7 at for over select rows
    Savez-vous pourquoi je récupère ce message ?
    Y a t-il mieux pour gérer la récursivité ?

    Merci à tous pour vos suggestions

    Sakalam
    Marre des blogs trop chiadés ?
    http://blog-de-m.over-blog.com/
    Enfin, un vrai blog de merde (d'un copain) !

  2. #2
    Expert éminent
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Points : 7 103
    Points
    7 103
    Par défaut
    Bonjour,

    je peux te suggérer la solution que j'ai retenue pour un cas similaire (ce n'était pas avec une base de données mais ça devrait fonctionner). Plutôt qu'un OID servant d'ID pour chacune des feuilles, utilise un ID alphanumérique composé des rangs successifs qu'occupe le noeud dans le sous-arbre dont le parent du noeud est la racine (pas facile de donner une définition récursive).

    Par exemple, le noeud avec l'ID '010305' désigne le 5ème noeud fils du 3ème noeud fils du 1er noeud de l'arbre sous la racine.

    Retrouver tous les descendants d'un noeud devient trivial : il suffit de rechercher les noeuds dont les ID commencent par l'ID de ce noeud, et de faire un tri alpha sur le résultat.

    Les opérations d'insertion et de suppression de noeuds devraient être un peu plus complexes, mais je pense que c'est jouable.
    FAQ XML
    ------------
    « Le moyen le plus sûr de cacher aux autres les limites de son savoir est de ne jamais les dépasser »
    Giacomo Leopardi

  3. #3
    Membre du Club
    Inscrit en
    Janvier 2006
    Messages
    71
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 71
    Points : 64
    Points
    64
    Par défaut
    Effectivement c'est une solution classique bien que pas très élégante (on internalise la structure de l'arbre). Comme tu le dis toi-même il y a des problèmes de mise à jour (notamment si toute une branche change de père, ce qui pourrait arriver) et même tout simplement de création des index.

    Malgré tous ces inconvénients, je m'y résoudrai peut-être finalement !

    Merci en tous cas

    Sakalam
    Marre des blogs trop chiadés ?
    http://blog-de-m.over-blog.com/
    Enfin, un vrai blog de merde (d'un copain) !

  4. #4
    Expert éminent
    Avatar de GrandFather
    Inscrit en
    Mai 2004
    Messages
    4 587
    Détails du profil
    Informations personnelles :
    Âge : 54

    Informations forums :
    Inscription : Mai 2004
    Messages : 4 587
    Points : 7 103
    Points
    7 103
    Par défaut
    Citation Envoyé par Sakalam
    Malgré tous ces inconvénients, je m'y résoudrai peut-être finalement !
    Je pense qu'implémenter une structure arborescente dans la structure linéaire qu'est une table de base de données entraîne de toutes façons des compromis inévitables... A moins d'utiliser une base de données XML consultable par XPath ou XQuery.

    Quant aux indexes, il va falloir sans doute par des indexes fonctionnels (indexes générés par une fonction utilisateur).

    Si tu trouves une solution plus satisfaisante, n'hésite pas à la poster, je pense que ça intéressera du monde (moi y compris)
    FAQ XML
    ------------
    « Le moyen le plus sûr de cacher aux autres les limites de son savoir est de ne jamais les dépasser »
    Giacomo Leopardi

  5. #5
    Membre du Club
    Inscrit en
    Janvier 2006
    Messages
    71
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 71
    Points : 64
    Points
    64
    Par défaut
    En dehors du fait que la gestion des arbres reste un problème général délicat, j'ai trouvé la réponse à ma question d'origine (enfin je crois). Je l'ai trouvée sur le site de la communauté française de PG.

    Je vous ce point précis de la FAQ tel quel car cela peut être utile à certains d'entre vous :

    4.26) Pourquoi ne puis-je pas
    créer/supprimer des tables temporaires dans les fonctions
    PL/PgSQL de façon stable ?

    PL/PgSQL cache le contenu des fonctions et un effet de bord
    malheureux est que si une fonction PL/PgSQL accède à
    une table temporaire, que cette table est ensuite supprimée
    et recréée, et que la fonction est appelée de
    nouveau, la fonction échouera car le contenu de la fonction
    cachée pointera toujours vers l'ancienne table temporaire.
    La solution revient à utiliser EXECUTE pour
    l'accès aux tables temporaires avec PL/PgSQL. Ceci obligera
    l'analyse de la requête à chaque fois.
    Amicalement

    Sakalam
    Marre des blogs trop chiadés ?
    http://blog-de-m.over-blog.com/
    Enfin, un vrai blog de merde (d'un copain) !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2010] Gestion d'arborescence Macro
    Par Manouchk dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 21/05/2013, 18h31
  2. gestion d'arborescence de documents
    Par hypothese dans le forum Collection et Stream
    Réponses: 2
    Dernier message: 15/05/2009, 12h21
  3. Java et gestion d'arborescence
    Par Grumphette dans le forum API standards et tierces
    Réponses: 4
    Dernier message: 18/09/2008, 20h15
  4. Gestion d'arborescence intervallaire
    Par booth dans le forum Langage SQL
    Réponses: 1
    Dernier message: 19/05/2006, 15h25
  5. Gestion de l'arborescence sur un serveur distant
    Par Seth77 dans le forum Langage
    Réponses: 5
    Dernier message: 13/03/2006, 17h30

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo