1

Je ne sais plus si j'ai déjà posé la question (mais n'ai pas encore exactement trouvé l'accord idéal), mais je cherche une bonne méthodo pour gérer une arborescence.

Je vais également prendre quelques précautions pour ne pas trahir mon projet derrière grin

En gros, considérons la notion de dossiers dans des dossiers.

Exemple d'arborescence :
  • Dossier Kakao
    • Dossier Chocho
    • Dossier Colas
      • Dossier Portos
      • Dossier Aramis
      • Dossier Turlutte
    • Dossier Blibli
  • Dossier R
  • Dossier Blabla

Avec mySQL, je cherche un système qui me permettrait de créer un dossier dans n'importe quel dossier existant, y compris de niveau 0, un système permettant de requêter simplement un chemin, par exemple, pour avoir, sur requête du dossier Aramis, la réponse : Kakao => Colas => Aramis

J'ai envisagé ce type de définition de table :

DOSSIER
-----------------
doss_num (identifiant unique)
doss_nom
doss_profondeur
doss_chemin (varchar ou text, concatenant les identifiants précédents les uns à la suite des autres)

Exemple d'enregistrement avec l'arborescence ci dessus :

doss_num : 2864
doss_nom : "Aramis"
doss_profondeur : 2
doss_chemin : "32.164.2765"

L'objectif :
  • rapidité de requêtage (sachant que quand je requêterai un dossier de niveau > 0, il n'y aura pas besoin d'avoir connaissance d'autres dossiers de niveau 0)
  • possibilité de couper une branche, ainsi que tous ses dossiers enfants
  • éviter le mieux possible les doublons en cas d'affluence de requêtes de création

Je ne sais pas si c'est super clair. Mais je suis à l'écoute de vos éventuelles recommandations ou retours d'expérience sur le sujet.

Merci
avatar
Slammeur (qu'on voit danser, le long des golfes clairs).
Mon blog qui parle de jeux-vidéo

2

Alors deux suggestions :

- Oublie l'idée de "doss_chemin" avec les identifiants les uns à la suite des autres : c'est inexploitable en SQL et ça ne te permettra de mettre aucune contrainte de cohésion dans ta base. De façon générale, je te conseillerais de ne jamais essayer de faire rentrer des trucs complexes dans un champ "varchar" ou équivalent s'ils peuvent avoir une signification SQL (par exemple être un identifiant, auquel tu pourrais ajouter un index, ou au moins l'utiliser tel quel dans une requête)
- Je ne vois pas trop non plus à quoi sert "doss_profondeur", mais peut-être que c'est un cas d'utilisation dont tu as besoin

Pour ta requête, si la rapidité d'exécution est un critère important pour toi alors il va falloir faire au moins un sacrifice : limiter la profondeur maximum de l'arbre. Ça te permettra d'écrire une requête de ce genre :SELECT d1.doss_nom AS dossier1, d2.doss_nom AS dossier2, d3.doss_nom AS dossier3 -- etc, autant de dN que tu veux de niveaux de profondeur au maximum FROM dossiers AS d1 LEFT JOIN dossiers AS d2 ON d2.doss_parent = d1.doss_num LEFT JOIN dossiers AS d3 ON d3.doss_parent = d2.doss_num -- etc, cf. commentaire ci-dessus WHERE d1.doss_nom = 'Aramis'Si tu veux une requête récursive pour avoir autant de niveaux que tu le souhaites il y a peut-être moyen, mais ça devient plus compliqué. Cf. cette question Stack Overflow par exemple.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

3

T'es obligé d'avoir ces informations dans une base MySQL ? Parce qu'il y a quand-même des typologies de stockage beaucoup plus adaptées (XML, LDAP ou, tout simplement, le filesystem lui-même ^^).
avatar

4

La représentation relationale d'une arborescence est effectivement un champ parent_id, qui est null pour la ou les racines (soit tu as un dossier racine, soit tu traîtes les dossiers au premier niveau de l'arborescence comme les racines).
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

5

Pardon, j'ai remis les mains sur les quelques éléments que j'avais constitués...
KK & Zeph > Oui, la notion de "parent" est prise en compte et je l'avais envisagée (oublié de le mentionner, alors que c'est plutôt clé (étrangère, huhuhu)).
Zeph (./2) :
- Je ne vois pas trop non plus à quoi sert "doss_profondeur", mais peut-être que c'est un cas d'utilisation dont tu as besoin
Oui, c'est spécifique à un besoin.
Zeph (./2) :
limiter la profondeur maximum de l'arbre.
C'est impensable dans mon cas, ou alors très très loin, genre profondeur de plusieurs centaines (et encore, j'aimerais m'en passer).
Nil (./3) :
T'es obligé d'avoir ces informations dans une base MySQL ? Parce qu'il y a quand-même des typologies de stockage beaucoup plus adaptées (XML, LDAP ou, tout simplement, le filesystem lui-même ^^).
J'ai envisagé un stockage de ce type, en effet... mais j'aimerais m'en passer.




Chaque enregistrement "dossier" aura ses propres caractéristiques (dernier utilisateur ayant modifié (avec la date d'update), taille, une note de 1 à 5 etc...) et, même sur une arboresence de profondeur N+50 (par exemple), d'avoir la possibilité de tirer une moyenne de la note.

Je me pose la question des DELETE et de la récursivité, je crains une imbrication de 30 à 40 DELETE pour la suppression d'une branche avec 1 parent et 39 descendants.
avatar
Slammeur (qu'on voit danser, le long des golfes clairs).
Mon blog qui parle de jeux-vidéo

6

je savais pas qu'on pouvait faire des requetes récursives !?

edit ah on peut pas, faut une procédure smile

7

Je peux faire du Postgre, mais ça m'emmerde, en fait grin
Puis, c'est surtout une question d'avoir un SGBDr que je connais bien et qui allège la charge serveur un maximum.
avatar
Slammeur (qu'on voit danser, le long des golfes clairs).
Mon blog qui parle de jeux-vidéo

8

juddhum (./5) :
Je me pose la question des DELETE et de la récursivité, je crains une imbrication de 30 à 40 DELETE pour la suppression d'une branche avec 1 parent et 39 descendants.
Tu dois pouvoir, en MySQL, avec des CASCADE, non ? (hum, cela dit j'ai un doute, je ne sais pas si les systèmes gérés par MySQL permettent d'avoir des clés étrangères pointant sur la table elle-même).
avatar

9

Pas tous les moteurs en tout cas.

10

Je vais me renseigner sur "CASCADE".

Vous m'avez remis les idées au clair.

Merci à vous tous.
avatar
Slammeur (qu'on voit danser, le long des golfes clairs).
Mon blog qui parle de jeux-vidéo

11

Tiens c'est marrant, j'ai eu cette question il n'y a pas si longtemps, je pensais faire ça avec 2 tables :
1ère table :
id -- nom -- parent

2e table :
parent -- id_section

Dans la première tu fais to schéma normal, avec les parents c'est facile à faire, et la 2e table est là en cas de modification. Pour chaque entrée que tu mets dans la première table, tu la met aussi dans la seconde table, mais avec chaque parent jusqu'à la source.

Si pour la première table tu as :
7 -- Dossier Kakao -- 0
51 -- Dossier Chocho -- 7
52 -- Dossier Colas -- 7
76 -- Dossier Portos -- 52
77 -- Dossier Aramis -- 52
78 -- Dossier Turlutte -- 52
17 -- Dossier Blabla -- 0

pour la 2e table tu auras :

7 -- 51
7 -- 52
52 -- 76
7 -- 76
52 -- 77
7 -- 77
52 -- 78
7 -- 78

Comme ça si tu supprimes le premier dossier (Kakao ID 7) tu trouves facilement grâce à la 2e table (tous les ids où le parent est 7), et si tu déplaces, par exemple Colas devient un sous-dossier de Chocho, avec la 2e table tu peux avoir directement tous les IDs de tous les sous-dossiers que ça contient (tous les ids où parent est 52, + 52 lui même), tu supprimes toutes les lignes avec les ids récupérés avec tous les parents de 52 (seulement 7 ici), puis tu prend tous les parents de Chocho (7 encore, mais ça pourrait être complètement différent) + id de chocho (donc 7 + 51), et tu ajoutes dans la 2e table les ids 52, 76, 77, 78 avec pour parents 7 et 51.

Bon je n'ai pas essayé, j'avais 2 minutes pour réfléchir à ça, mais le mec avait l'air de dire que c'était pas trop mal.

12

Le problème c'est que c'est une représentation dénormalisée, donc ça risque d'être difficile de garantir la cohérence des données en base.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

13

Sinon utiliser Doctrine, avec l'extension qui va bien ^^
https://github.com/Atlantic18/DoctrineExtensions/blob/master/doc/tree.md

Comme ça pas de prise de tête, tout est déjà pris en charge, et ça fonctionne bien smile