Étant donné que vous effectuez des opérations hiérarchiques, vous devez utiliser une stratégie pour enregistrer et récupérer ces données dans votre base de données.
Une approche consiste à utiliser modèle d'ensemble imbriqué , cela peut faciliter les choses. Laravel a un excellent package qui s'en occupe, appelé etrepat/baum , qui explique aussi comment ça marche et je cite :
La théorie derrière, une version TL;DR
Un moyen simple de visualiser le fonctionnement d'un ensemble imbriqué est de penser à une entité parent entourant tous ses enfants, et son parent l'entourant, etc. Donc cet arbre :
root
|_ Child 1
|_ Child 1.1
|_ Child 1.2
|_ Child 2
|_ Child 2.1
|_ Child 2.2
Pourrait être visualisé comme ceci :
___________________________________________________________________
| Root |
| ____________________________ ____________________________ |
| | Child 1 | | Child 2 | |
| | __________ _________ | | __________ _________ | |
| | | C 1.1 | | C 1.2 | | | | C 2.1 | | C 2.2 | | |
1 2 3_________4 5________6 7 8 9_________10 11_______12 13 14
| |___________________________| |___________________________| |
|___________________________________________________________________|
Les nombres représentent les limites gauche et droite. Le tableau pourrait alors ressembler à ceci :
id | parent_id | lft | rgt | depth | data
1 | | 1 | 14 | 0 | root
2 | 1 | 2 | 7 | 1 | Child 1
3 | 2 | 3 | 4 | 2 | Child 1.1
4 | 2 | 5 | 6 | 2 | Child 1.2
5 | 1 | 8 | 13 | 1 | Child 2
6 | 5 | 9 | 10 | 2 | Child 2.1
7 | 5 | 11 | 12 | 2 | Child 2.2
Pour obtenir tous les enfants d'un parent nœud, vous
SELECT * WHERE lft IS BETWEEN parent.lft AND parent.rgt
Pour obtenir le nombre d'enfants, c'est
(right - left - 1)/2
Pour qu'un nœud et tous ses ancêtres remontent à la racine, vous
SELECT * WHERE node.lft IS BETWEEN lft AND rgt
Comme vous pouvez le voir, les requêtes qui seraient récursives et excessivement lentes sur des arbres ordinaires sont soudainement assez rapides. Sympa, n'est-ce pas ?