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

ASP.NET Discussion :

Nested set - Treeview


Sujet :

ASP.NET

  1. #1
    Rédacteur
    Avatar de Erakis
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2003
    Messages
    523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 523
    Points : 233
    Points
    233
    Par défaut Nested set - Treeview
    Bonjour à tous,

    Je ne sais pas trop si ce post devrait aller dans SQL Server ou ici... Enfin je me risque quand meme.

    J'ai une base de données qui contient une table avec des données hierarchiques "Nested set". Dans le style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    ID       Nom            left          right
    ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
    1        A1              1             14
    2        A1.1            2              5
    3        A1.1.1          3              4
    4        A1.2            6             13
    5        A1.2.1          7             10
    6        A1.2.1.1        8              9
    7        A1.2.2         11             12
    Ce qui donne à peu près ceci (A = Activité):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
                            A1
         -----------------------------------
        |                                  |
      A1.1                       ------- A1.2-------
        |                        |                 |
     A1.1.1                    1.2.1             1.2.2
                                 |
                              1.2.1.1

    J'aimerais afficher la même chose, mais en utilisant un treeview ou un treegrid ou sinon une table html avec des expend/collapse row.

    Habituellement, dans une table de type "Adjacency" on utilise la colone "Parent ID". Dans ce cas-ci, il n'y en a pas. Et la seule façon que j'ai pu trouver pour déterminer le parent d'un noeud est une sous requête dans un WHERE. Je trouve cela on ne peu trop gourmand. Si je dois sortir une activité qui possède 50 sous-activités, alors la sous-requête sera exécuter 50 fois !

    Est-ce que quelqu'un, à déjà afficher des données hierarchique en utilisant une table "Nested set" ?

    J'aimerais beaucoup lire vos suggestions
    Merci à tous

  2. #2
    Expert éminent sénior

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Points : 12 465
    Points
    12 465
    Par défaut
    Salut,

    Citation Envoyé par Erakis Voir le message
    Habituellement, dans une table de type "Adjacency" on utilise la colone "Parent ID". Dans ce cas-ci, il n'y en a pas. Et la seule façon que j'ai pu trouver pour déterminer le parent d'un noeud est une sous requête dans un WHERE. Je trouve cela on ne peu trop gourmand. Si je dois sortir une activité qui possède 50 sous-activités, alors la sous-requête sera exécuter 50 fois !

    Personnellement, je suis en plein dedans aussi.

    Ma suggestion, elle est toute simple, ajoute une colonne ParentID à la table, et base-toi dessus

    Si tu ne peux pas, fais l'inverse, plutot que de chercher à determiner les parents d'un noeud, cherche ses descendants, commence par A1, et cherches tous les elements dont le nom commence par "A1.%" et qui ne commencent pas par "AI.%.%"

    etc... etc...

    mais franchement, dans ta situation, j'insisterais sur le besoin de normalisation de la table, et sur le fait que tu n'aurais que des impacts positifs

  3. #3
    Rédacteur
    Avatar de Erakis
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2003
    Messages
    523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 523
    Points : 233
    Points
    233
    Par défaut
    Hummm, rajouter une colonne "ParentID" sera couteux en temps de developpement pour le projet. Il y a beaucoup de requêtes liées à cette table et beaucoup de tables reliés à celle-ci. Et pour rendre la chose plus complex, j'ai une autre colonne qui contient un numéro d'arbre (TreeRank). Puisqu'il peut y avoir plusieurs arbres. Exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Projet 1 :
        - A1.
        - A2.
           - A2.1
           - A2.2
              - A2.3.1
        - A3.
    Projet 2 :
        - A1.
    Ici l'activité du projet 1 A1 possède le TreeRank 1 pour le projet 1.

    L'activité du projet 1 A2 possède le TreeRank 2 pour le projet 1.

    L'activité du projet 1 A2 possède le TreeRank 1 pour le projet 2.

    Ainsi de suite...

    Malheureusement, je ne peux pas faire des recherches par A1. A1.1, A1.2, etc... Puisque les activités possèdent des noms autres que ceux-ci. Ces noms étaient seulement pour bien expliquer mon post. Autrement, cela aurait été plus simple, car ce système aurait été un "Adjacency" basé sur un WBS, d'où j'aurais pu utiliser un LIKE A1.% avec un LEFT JOIN pour récupérer les parent de chaque noeuds.

    Juste pour être sûr, par normalisation, vous entendez l'ajout de la colonne "ParentID" ?

    J'ai trouvé cet article sur CodeProjet Tree_Traversal, lui aussi propose d'ajouter le "Parent ID". J'hésite toujours à faire ce genre d'ajout, puisqu'entre nous, c'est une colonne qui ajoute une données qui peut être déduite autrement. Donc, du doublons autrement dit. Chose qu'on nous éduques à ne pas faire à l'école et dans les livres

    Je sais que c'est plutot un question de base données, mais comment définiriez-vous votre ou vos index de tables ? Sanchant que j'utilise très souvent les champs "actLeft" et "actRight", voilà ce que j'ai actuellement comme index sur cette table :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    CREATE NONCLUSTERED INDEX [IX_Activite_Projet_TreeRank_Left_Right] ON Activite
    (
       [actProjetCode] ASC,
       [actTreeRank] ASC,
       [actLeft] ASC,
       [actRight] ASC
    )
    Devrais-je aussi ajouter l'index suivante, sachant que j'utiliserai aussi le ParentCode pour l'affichage dans mon TreeView ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    CREATE NONCLUSTERED INDEX [IX_Activite_Projet_TreeRank_Left_Right] ON Activite
    (
       [actProjetCode] ASC,
       [actTreeRank] ASC,
       [actParentCode] ASC,
    )
    Merci

  4. #4
    Expert éminent sénior

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Points : 12 465
    Points
    12 465
    Par défaut
    J'ai trouvé cet article sur CodeProjet Tree_Traversal, lui aussi propose d'ajouter le "Parent ID". J'hésite toujours à faire ce genre d'ajout, puisqu'entre nous, c'est une colonne qui ajoute une données qui peut être déduite autrement. Donc, du doublons autrement dit. Chose qu'on nous éduques à ne pas faire à l'école et dans les livres
    Je dois admettre que je ne vois pas vraiment quelle est ta structure de base, comment tu retrouves tes parents et compagnie (table annexe, autre ???)

    Si tu te bases sur une "bête" forme normale, tes données de relations entre champs ne devraient pas être implicites, dans le sens ou une donnée non clef doit dépendre directement d'une clef (à partir de la 3NF, si je me rappelle bien), donc, "déduire" une clef est en soit une violation de la forme normale...

    Hummm, rajouter une colonne "ParentID" sera couteux en temps de developpement pour le projet. Il y a beaucoup de requêtes liées à cette table et beaucoup de tables reliés à celle-ci.
    Pour quelle raison ?

    Ajouter une colonne ne t'oblige pas a mettre a jour tout ton code, surtout si ce n'est pas une colonne fonctionnelle.

    Dans le pire des cas, tu dois traiter cette colonne pour les nouveaux developpement, et eventuellement modifier les regles d'insertion dans tes tables (peut etre qu'un trigger peut suffire)

    Et pour rendre la chose plus complex, j'ai une autre colonne qui contient un numéro d'arbre (TreeRank).
    La, je suis perdu...Dans la même table, ou dans une autre ?

    Si ce que tu as, c'est une table d'intersection entre n arbres et m nœuds, il te suffit de modifier la table d'intersection pour ajouter l'identifiant du parent

    Dans le cas contraire, je prends peur...

    Si tu as possibilité d'expliciter un peu ton modèle de données, j'y verrais plus clair

  5. #5
    Rédacteur
    Avatar de Erakis
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2003
    Messages
    523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 523
    Points : 233
    Points
    233
    Par défaut
    Je vais donc essayer de clarifier ma structure.

    J'ai donc 2 tables majeurs relié à ma question :
    - Projets
    - Activités

    Un projet peut contenir 0 à n activités.
    Une activités peut contenir 0 à n sous-activités. D'où le besoin d'une hiérarchie.

    Voici la déclaration minimum de la table Projets
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    proCode
    proNom
    proDescription
    proCode = Numéro unique du projet
    proNom = Nom du projet
    proDescription = Description du projet

    Déclaration minimum de la table Activités
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    actCode
    actProjetCode
    actTreeRank
    actLeft
    actright
    actCode = Numéro unique de l'activité
    actProjetCode = Numéro du projet dans lequel l'activité réside.
    actTreeRank = Comme un projet peut avoir plusieurs activités racine, chacune de ceux-ci représente donc un arbre. Donc, pour le projet 1 on pourrait avoir l'activité A1 qui aurait un TreeRank = 1, l'activité A1.1 avec un TreeRank = 1 puisqu'elle est dans l'arbre de A1. Et avoir une activité A2 qui aurait un TreeRank = 2, puisqu'elle est à la racine et débute donc un nouvel arbre sous ce projet 1.
    actLeft = Numérotation gauche du noeud de l'activité
    actRight = Numérotation droite du noeud de l'activité

    Voici la clé primaire sur ma table Activité :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    CREATE NONCLUSTERED INDEX [IX_Activite_Projet_TreeRank_Left_Right] ON Activite
    (
       [actProjetCode] ASC,
       [actTreeRank] ASC,
       [actLeft] ASC,
       [actRight] ASC
    )
    Si j'ai bien compris ce que vous m'avez dit, le fait que je calcul le champs "ParentCode" d'une activité entre en violation de la forme normale ? Toutefois, le fait que la colonne "actLeft" et "actRight" me donne déjà la possibilité de trouvé le ParentCode, cela ne va-t-il pas à l'encontre de l'autre loi anti-doublons ?

    Le fait de rajouer la colonne ParentCode, implique beaucoup de travail, puisqu'il est actuellement possible sur mon site web de supprimer, modifier, ajouter, déplacer des activités. Donc chacune de ses procédures stockées devront être revisées. Certainnes autre procédures stockées quant à elle, avait droit à certainnes pirouettes acrobatique (Table temporaire, etc...) pour déduire ce fameux champs dont j'avais besoin pour créer un WBS dans des rapports.

    Au cas ou vous vous demanderiez ce qu'est un WBS (Work Breakdown Structure). Numéroter les activités comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Activite 1
        |
        - Activite 1.1
        - Activite 1.2
               |
               - Activite 1.2.1
        - Activite 1.3

  6. #6
    Expert éminent sénior

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Points : 12 465
    Points
    12 465
    Par défaut
    bon, je pense que j'ai été enduit d'erreur en regardant ton exemple initial.

    Ce que tu me dis, c'est que, pour chaque noeud de ton arbre, tu stockes le descendant immédiat à gauches et à droite ?

    Si c'est le cas, une solution de remplacement, c'est de n'afficher que le premier niveau, et de populer ton arbre au fur et a mesure, avec des appels ajax

    Mais bon, pour avoir bossé sur des WBS avant (sisisi, je savais ce que c'est), utiliser un parent id est encore la meilleure solution

  7. #7
    Rédacteur
    Avatar de Erakis
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2003
    Messages
    523
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Octobre 2003
    Messages : 523
    Points : 233
    Points
    233
    Par défaut
    Peu importe la solution que je vais choisir, j'avais l'intention de populer ma grille côté client avec des appels Ajax. Donc, lorsqu'on expend et collapse des lignes. . Toutefois, je ne sais pas trop comment m'y prendre. Est-ce que j'envois une command via un objet XmlRequest, et le serveur me retourne les informations sous forme XML, qu'ensuite je dois parser et ajouter sous forme de TR, TD, etc... à ma table HTML côté client ?

    Donc, si j'ajoute un champs ParentCode, on s'entend pour dire que cela sera de la duplication de données qui peut être déduite via les champs lft et rgt ? Mais, vous me conseillez toutefois d'ajouter cette colonne pour simplifier le travail et ajouter ainsi plus de flexibilité à ma structure ? Enfin bref, si c'est votre point de vue, c'est un peu le miens aussi. Donc, j'ai commencé à ajouter cette colonne hier soir. Toutefois, c'est beaucoup de travail et de vérification

Discussions similaires

  1. [1.x] Nested Set Behavior
    Par bilbonec dans le forum Symfony
    Réponses: 4
    Dernier message: 11/02/2011, 10h24
  2. [Doctrine] Comment bouger les noeud avec les Nested Set
    Par beachjf dans le forum PHP & Base de données
    Réponses: 0
    Dernier message: 10/02/2011, 21h31
  3. Réponses: 10
    Dernier message: 26/08/2010, 01h11
  4. Réponses: 1
    Dernier message: 23/08/2010, 11h10
  5. [1.x] Nested set avec jointure
    Par damiensan dans le forum Symfony
    Réponses: 4
    Dernier message: 21/05/2010, 14h21

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