sql >> Database teknologi >  >> RDS >> PostgreSQL

kloning af hierarkiske data

Det er vanskeligt at trække dette resultat ind rekursivt (selv om det er muligt). Det er dog typisk ikke særlig effektivt, og der er meget bedre måde at løse dette problem på.

Grundlæggende udvider du tabellen med en ekstra kolonne, som sporer træet til toppen - jeg vil kalde det "Upchain". Det er bare en lang streng, der ser sådan ud:

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:

Det er meget nemt at holde dette felt opdateret ved at bruge en trigger på bordet. (Undskyld terminologien, men jeg har altid gjort dette med SQL Server). Hver gang du tilføjer eller sletter en post eller opdaterer parent_id-feltet, skal du blot opdatere upchain-feltet på den del af træet. Det er et trivielt job, fordi du bare tager opkæden af ​​den overordnede post og tilføjer id'et for den aktuelle post. Alle underordnede poster identificeres nemt ved at bruge LIKE til at tjekke for poster med startstrengen i deres upchain.

Det, du effektivt gør, er at bytte lidt ekstra skriveaktivitet for en stor sparer, når du kommer for at læse dataene.

Når du vil vælge en hel gren i træet, er det trivielt. Antag, at du vil have grenen under node 1. Node 1 har en upchain '1:', så du ved, at enhver node i grenen af ​​træet under den node skal have en upchain, der starter '1:...'. Så gør du bare dette:

SELECT *
FROM table
WHERE upchain LIKE '1:%'
 

Dette er ekstremt hurtigt (indekser upchain-feltet selvfølgelig). Som en bonus gør det også en masse aktiviteter ekstremt enkle, såsom at finde deltræer, niveau i træet osv.

Jeg har brugt dette i applikationer, der sporer store medarbejderrapporteringshierarkier, men du kan bruge det til stort set enhver træstruktur (opdeling af dele osv.)

Bemærkninger (til alle, der er interesserede):

  • Jeg har ikke givet et trin-for-trin af SQL-koden, men når først du har forstået princippet, er det ret nemt at implementere. Jeg er ikke en god programmør, så jeg taler af erfaring.
  • Hvis du allerede har data i tabellen, skal du lave en engangsopdatering for at få upchains synkroniseret indledningsvis. Igen, dette er ikke svært, da koden minder meget om UPDATE-koden i triggerne.
  • Denne teknik er også en god måde at identificere cirkulære referencer på, som ellers kan være vanskelige at få øje på.


  1. MySQL kombinerer vælg med sum fra anden tabel

  2. importere csv-filer på postgres numeriske typer

  3. Oracle hvordan man importerer manglende java-klasser, når man kalder java fra plsql

  4. Start MySQL Server som en tjeneste (Win 8)