Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Recupere todos os registros pai/filho do banco de dados no Laravel (dados hierárquicos)


Como você está fazendo operações hierárquicas, você deve usar uma estratégia para salvar e recuperar esses dados do seu banco de dados.

Uma abordagem é usar o Modelo de conjunto aninhado , isso pode facilitar. O Laravel tem um ótimo pacote que lida com isso, chamado etrepat/baum , isso também explica como funciona e cito:

A teoria por trás, uma versão TL;DR


Uma maneira fácil de visualizar como um conjunto aninhado funciona é pensar em uma entidade pai ao redor de todos os seus filhos, e seu pai ao seu redor, etc. Portanto, esta árvore:
root
  |_ Child 1
    |_ Child 1.1
    |_ Child 1.2
  |_ Child 2
    |_ Child 2.1
    |_ Child 2.2

Poderia ser visualizado assim:
 ___________________________________________________________________
|  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
|   |___________________________|   |___________________________|   |
|___________________________________________________________________|

Os números representam os limites esquerdo e direito. A tabela então pode ficar assim:
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

Para obter todos os filhos de um pai nó, você
SELECT * WHERE lft IS BETWEEN parent.lft AND parent.rgt

Para obter o número de filhos, é
(right - left - 1)/2

Para obter um nó e todos os seus ancestrais voltando para a raiz, você
SELECT * WHERE node.lft IS BETWEEN lft AND rgt

Como você pode ver, consultas que seriam recursivas e proibitivamente lentas em árvores comuns são repentinamente muito rápidas. Bonito, não é?