実体化されたパスをデータベースに保存する方法。

この方法の主な利点は、1つのデータベースクエリ内の任意のレベルの子ノードへのアクセスです(ただし、INNER JOINを使用)。

例:
/ company /セクションのニュースリストにアクセスする必要があります(item1、item2)

データは、次の構造を持つテーブルに保存されます。
パス - パスを持つツリー
id
parent_id # id (paths.id)
name # ,
path # (/company/, /company/news/item1/)
title #


path_have_childs-リンクテーブル。親ノードに相対的なレベルの子ノードのリストを格納します

parent_id # id (paths.id)
child_id # id (paths.id)
level #


データ-パスを持つテーブル:
idparent_idお名前タイトル
10/ホーム
21会社/会社/会社について
42ニュース/会社/ニュース/ニュース
54item1/会社/ニュース/ item1 /ニュース1
64item2/会社/ニュース/ item2 /ニュース2
31カタログ/カタログ/カタログ
73category1/カタログ/ category1 /カテゴリー1
87category2/カタログ/ category1 / category2 /カテゴリー2


追加テーブル-親に対する子ノードのレベルのストレージ:
parent_idchild_idレベル
121
183
172
163
153
142
131
252
262
241
371
382
461
451
781

レベルの追加テーブルを生成するクエリ-各ノードについて、直接の子ノード以外のすべての子ノードが検出され、現在のノードに相対的なネストレベルが計算されます。
INSERT INTO path_have_childs
SELECT
P.id AS parent_id,
C.id AS child_id,
(LENGTH(C. path ) - LENGTH(REPLACE(C. path , '/' , '' )))
- (LENGTH(P. path ) - LENGTH(REPLACE(P. path , '/' , '' )))
FROM paths AS P
INNER JOIN paths AS C ON (C. path LIKE CONCAT(P. path , '_%' ))


レベルY(parent_have_childs.level)のノードX(parent_have_childs.parent_id)のすべての子ノードを選択します。
SELECT C. path
FROM path_have_childs AS PHC
INNER JOIN paths AS C ON (PHC.child_id = C.id)
WHERE
PHC. level = Y
AND PHC.parent_id = X


建設的なコメントと批判を歓迎します...

Source: https://habr.com/ru/post/J52298/


All Articles