Nie ma pojedynczego zapytania SQL które mogą przynieść Ci wyniki uporządkowane tak, jak oczekujesz, w oparciu o tę strukturę tabeli.
Istnieją dwa sposoby rozwiązania tego problemu:
-
Użyj zewnętrznej logiki aplikacji (poza DB), aby wykonać rekurencyjne wywołania, które wykryją dzieci z każdej kategorii i zbudują drzewo w aplikacji.
-
Użyj jednego z algorytmów do przechowywania danych drzewa w relacyjnej bazie danych. Jeden z takich algorytmów nazywa się
Modified Preorder Tree Traversal
lub po prostu MPTT.
Zakładając, że używamy kolumn lft
i rgt
aby zachować indeksy lewy / prawy podczas przechodzenia, po wstawieniu nowej kategorii należy:
-
Uzyskaj informacje o kategorii nadrzędnej według identyfikatora:
SELECT lft,rgt FROM tbl_categories WHERE categoryId=5
Załóżmy dla przykładu, że kategoria nadrzędna miałalft=7
irgt=10
(w tym przypadku ma już jedno dziecko) -
Zrób miejsce na nowy wpis – przesuń wszystkie rekordy o 2 (1 dla lewej strony i 1 dla prawej):
UPDATE tbl_categories SET rgt=rgt+2 WHERE rgt>=10 ORDER BY rgt DESC
UPDATE tbl_categories SET lft=lft+2 WHERE lft>=10 ORDER BY lft DESC
Zanotuj tutaj ORDER
malejąco. Jako lft
i rgt
mają być unikatowe, zaleca się wykonanie UNIQUE
ograniczenie ich, a następnie wymagana jest kolejność malejąca w aktualizacji, aby zapobiec błędom zduplikowanych kluczy.
-
Ustaw
lft=<former parent rgt>
orazrgt=<former parent rgt +1>
i wstaw nowy rekord...INSERT INTO tbl_categories SET categoryName="New Child",parentCategoryId=5,lft=11,rgt=12,...
Możesz znaleźć bardziej szczegółowe przykłady z kodem, jeśli wyszukasz MPTT PHP MySQL
. Istnieje wiele samouczków na ten temat.