Тъй като извършвате йерархични операции, трябва да използвате стратегия за запазване и извличане на тези данни от вашата база данни.
Един подход е да използвате вложен модел на набор , това може да го улесни. Laravel има страхотен пакет, който се справя с него, наречен etrepat/baum , това също обяснява как работи и цитирам:
Теорията зад, TL;DR версия
Лесен начин да визуализирате как работи вложен набор е да мислите за родителски обект, заобикалящ всички негови деца, и неговия родител, който го заобикаля и т.н. Така че това дърво:
root
|_ Child 1
|_ Child 1.1
|_ Child 1.2
|_ Child 2
|_ Child 2.1
|_ Child 2.2
Може да се визуализира така:
___________________________________________________________________
| 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
| |___________________________| |___________________________| |
|___________________________________________________________________|
Числата представляват лявата и дясната граница. Тогава таблицата може да изглежда така:
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
За да получите всички деца на родител възел, вие
SELECT * WHERE lft IS BETWEEN parent.lft AND parent.rgt
За да получите броя на децата, това е
(right - left - 1)/2
За да получите възел и всички негови предшественици да се връщат обратно към корена, вие
SELECT * WHERE node.lft IS BETWEEN lft AND rgt
Както можете да видите, заявките, които биха били рекурсивни и непосилно бавни обикновени дървета, изведнъж са доста бързи. Чудесно, нали?