Wyciągnięcie tego wyniku w sposób rekurencyjny jest trudne (choć możliwe). Jednak zazwyczaj nie jest to zbyt wydajne i jest dużo lepszy sposób na rozwiązanie tego problemu.
Zasadniczo rozszerzasz tabelę o dodatkową kolumnę, która śledzi drzewo do góry - nazwę to „Upchain”. To tylko długi ciąg, który wygląda mniej więcej tak:
name | id | parent_id | upchain
root1 | 1 | NULL | 1:
root2 | 2 | NULL | 2:
root1sub1 | 3 | 1 | 1:3:
root1sub2 | 4 | 1 | 1:4:
root2sub1 | 5 | 2 | 2:5:
root2sub2 | 6 | 2 | 2:6:
root1sub1sub1 | 7 | 3 | 1:3:7:
Bardzo łatwo jest aktualizować to pole za pomocą wyzwalacza w tabeli. (Przepraszam za terminologię, ale zawsze robiłem to z SQL Server). Za każdym razem, gdy dodajesz lub usuwasz rekord albo aktualizujesz pole parent_id, wystarczy zaktualizować pole upchain w tej części drzewa. To trywialne zadanie, ponieważ po prostu bierzesz upchain rekordu nadrzędnego i dołączasz identyfikator bieżącego rekordu. Wszystkie rekordy podrzędne można łatwo zidentyfikować za pomocą funkcji LIKE, aby sprawdzić rekordy z początkowym ciągiem w łańcuchu upchain.
To, co robisz skutecznie, to zamienianie odrobiny dodatkowej aktywności związanej z pisaniem na duże zapisywanie, gdy przyjdziesz przeczytać dane.
Gdy chcesz wybrać całą gałąź w drzewie, jest to trywialne. Załóżmy, że chcesz mieć gałąź pod węzłem 1. Węzeł 1 ma upchain '1:', więc wiesz, że każdy węzeł w gałęzi drzewa pod tym węzłem musi mieć upchain rozpoczynający się '1:...'. Więc po prostu zrób to:
SELECT *
FROM table
WHERE upchain LIKE '1:%'
To jest bardzo szybko (oczywiście zaznacz pole upchain). Jako bonus sprawia również, że wiele czynności jest niezwykle prostych, takich jak znajdowanie częściowych drzew, poziomów w drzewie itp.
Użyłem tego w aplikacjach, które śledzą duże hierarchie raportowania pracowników, ale można go używać do prawie każdej struktury drzewa (podział części itp.)
Notatki (dla wszystkich zainteresowanych):
- Nie podałem kodu SQL krok po kroku, ale kiedy już zrozumiesz zasadę, implementacja jest dość prosta. Nie jestem świetnym programistą, więc mówię z doświadczenia.
- Jeśli masz już dane w tabeli, musisz przeprowadzić jednorazową aktualizację, aby wstępnie zsynchronizować upchains. Ponownie, nie jest to trudne, ponieważ kod jest bardzo podobny do kodu UPDATE w wyzwalaczach.
- Ta technika jest również dobrym sposobem na identyfikację odniesień cyklicznych, które w przeciwnym razie mogą być trudne do wykrycia.