PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

klonowanie danych hierarchicznych

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.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jakiś powód, dla którego nie korzystasz z wbudowanego wyszukiwania pełnotekstowego PostgreSQL w Heroku?

  2. szyny dynamiczne, gdzie zapytanie sql

  3. Alternatywa w przypadku wprowadzenia klauzuli IN DUŻO wartości (postgreSQL)

  4. Dynamiczne zapytanie przestawne przy użyciu PostgreSQL 9.3

  5. Postgis / Geodjango:Nie można określić wersji PostGIS dla bazy danych