Struktura drzewiasta w bazie danych Odc. 4 Nested set – odczytywanie gałęzi

W poprzednich artykułach tej serii pokazałam jak wygląda konstrukcja drzewa typu nested set a także jak wczytać zawartość drzewa tego typu. W tym odcinku pokażę, że wystarczą niewielkie modyfikacje omówionych wcześniej zapytań, by bez trudu odczytać dowolnie wybraną gałąź naszej struktury.

Dla przypomnienia

Na początek przypomnę tabelę zawierająca strukturę drzewa, którą wykorzystywałam w poprzednich artykułach oraz wygląd drzewa jaki można uzyskać wykonując jedno z dwóch pokazanych poniżej zapytań.

SELECT
concat( repeat('-', COUNT(parent.id) - 1),child.title)
AS title,
child.id
FROM tree AS child,
tree AS parent
WHERE child.lft BETWEEN parent.lft AND parent.rgt
GROUP BY child.id
ORDER BY child.lft
SELECT 
concat( repeat('-', 
    (SELECT count(parent.id)-1
     FROM tree AS parent
     WHERE node.lft BETWEEN parent.lft AND parent.rgt)
),node.title) AS title,
node.id
FROM tree AS node
ORDER BY node.lft

Wczytanie gałęzi

Załóżmy teraz, że chcemy wczytać tylko gałąź zaczynającą się od rekordu o id=2 (title=Windows). Nic prostszego wystarczy zapytać o rekordy, których wartości parametrów ‘lft’ i ‘rgt’ mieszczą się pomiędzy 2 a 13, takie bowiem wartości mają te parametry dla wybranego przez nas rekordu. Tak więc wykonanie jednego z poniższych zapytań da zamierzony efekt, co widać na załączonej ilustracji.

SELECT
concat( repeat('-', COUNT(parent.id) - 1),child.title)
AS title,
child.id
FROM tree AS child,
tree AS parent
WHERE child.lft BETWEEN parent.lft AND parent.rgt
AND child.lft BETWEEN 2 AND 13
GROUP BY child.id
ORDER BY child.lft
SELECT 
concat( repeat('-', 
    (SELECT count(parent.id)-1
     FROM tree AS parent
     WHERE node.lft BETWEEN parent.lft AND parent.rgt)
),node.title) AS title,
node.id
FROM tree AS node
WHERE node.lft BETWEEN 2 AND 13
ORDER BY node.lft

Wykluczenie gałęzi

W podobny sposób można wykluczyć jakąś gałąź odczytując strukturę drzewa. Zabieg ten jest przydatny podczas przenoszenia gałęzi. W strukturze drzewa zakodowana jest pewna hierarchia. Przenosząc gałąź należy uniemożliwić podanie jako miejsca docelowego, elementu, który do tej gałęzi należy. Także i w tym wypadku modyfikacja obu alternatywnych zapytań jest niewielka. Załóżmy, że chcemy wykluczyć tę samą gałąź, którą poprzednio wczytywaliśmy. Zapytania przybiorą następującą formę:

SELECT
concat( repeat('-', COUNT(parent.id) - 1),child.title)
AS title,
child.id
FROM tree AS child,
tree AS parent
WHERE child.lft BETWEEN parent.lft AND parent.rgt
AND (child.lft < 2 OR child.rgt > 13)
GROUP BY child.id
ORDER BY child.lft
SELECT 
concat( repeat('-', 
    (SELECT count(parent.id)-1
     FROM tree AS parent
     WHERE node.lft BETWEEN parent.lft AND parent.rgt)
),node.title) AS title,
node.id
FROM tree AS node
WHERE node.lft < 2 OR node.rgt > 13
ORDER BY node.lft

Podsumowanie

Warto zauważyć, że opisane powyżej operacje, w przypadku drzewa zrealizowanego tak jak to pokazałam w pierwszym artykule na temat struktur drzewiastych byłyby niemal nie do wykonania na poziomie bazy danych. Aby je przeprowadzić trzeba by wczytywać cała tabelę i dopiero za pomocą skryptu analizować. Dlatego uważam, że zaprezentowane tu zapytania, mimo iż mogą sprawiać trudności początkującym programistom, są wygodne i pozwalają operować danymi w sposób elegancki.

2 komentarze do wpisu „Struktura drzewiasta w bazie danych Odc. 4 Nested set – odczytywanie gałęzi”

  1. Zbiory zagnieżdżone są w miarę przyjazne na etapie wybierania danych. Czekam jak podejdziesz do tematu modyfikacji struktury drzewa, a zwłaszcza przenoszenia całych gałęzi.

  2. 17-tego maja ukarze się kolejny artykuł, tym razem o dodawaniu rekordów do struktury. W następnej kolejności pojawi się tekst właśnie o przenoszeniu gałęzi, tak więc trzymaj rękę na pulsie :)

    A ja właśnie dlatego zainteresowałam się taką implementacją drzewa, bo wychodzę z założenia, że tego typu struktury jednak dużo częściej się odczytuje niż modyfikuje. Warto więc podjąć wysiłek związany z implementacją mechanizmów pozwalających na modyfikację, po to, żeby mieć ułatwioną sprawę przy odczycie.

Leave a Reply to JoannaCancel reply

%d bloggers like this: