階層的な操作を行っているため、このデータをデータベースに保存して取得するための戦略を使用する必要があります。
1つのアプローチは、入れ子集合モデル を使用することです。 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
ご覧のとおり、再帰的で非常に遅い通常のツリーのクエリは、突然非常に高速になります。気の利いたね