Struttura del database per struttura dati ad albero


151

Quale sarebbe il modo migliore per implementare una struttura di dati ad albero personalizzabile (significato, una struttura ad albero con un numero sconosciuto di livello) in un database?

L'ho già fatto una volta prima di usare una tabella con una chiave esterna su se stessa.

Quali altre implementazioni potresti vedere e ha senso questa implementazione?



SQL Server (dal 2008) offre il tipo di dati hierarchyid
BornToCode

Risposte:


80

Lei cita il più comunemente implementato, che è l'elenco di adiacenza: https://blogs.msdn.microsoft.com/mvpawardprogram/2012/06/25/hierarchies-convert-adjacency-list-to-nested-sets

Esistono anche altri modelli, tra cui percorso materializzato e set nidificati: http://communities.bmc.com/communities/docs/DOC-9902

Joe Celko ha scritto un libro su questo argomento, che è un buon riferimento da una prospettiva SQL generale (è menzionato nel link dell'articolo set nidificato sopra).

Inoltre, Itzik Ben-Gann ha una buona panoramica delle opzioni più comuni nel suo libro "Inside Microsoft SQL Server 2005: T-SQL Querying".

Le cose principali da considerare quando si sceglie un modello sono:

1) Frequenza del cambio di struttura - con quale frequenza cambia la struttura reale dell'albero. Alcuni modelli offrono migliori caratteristiche di aggiornamento della struttura. Tuttavia, è importante separare le modifiche alla struttura dalle altre modifiche ai dati. Ad esempio, potresti voler modellare l'organigramma di un'azienda. Alcune persone modelleranno questo come un elenco di adiacenza, usando l'ID dipendente per collegare un dipendente al proprio supervisore. Questo è di solito un approccio non ottimale. Un approccio che spesso funziona meglio è modellare la struttura organizzativa separatamente dagli impiegati stessi e mantenere l'impiegato come un attributo della struttura. In questo modo, quando un dipendente lascia l'azienda, la struttura organizzativa stessa non deve essere modificata, ma solo l'associazione con il dipendente che ha lasciato.

2) L'albero è pesante per la scrittura o pesante per la lettura - alcune strutture funzionano molto bene durante la lettura della struttura, ma comportano un sovraccarico aggiuntivo quando si scrive sulla struttura.

3) Quali tipi di informazioni sono necessari per ottenere dalla struttura - alcune strutture eccellono nel fornire determinati tipi di informazioni sulla struttura. Gli esempi includono trovare un nodo e tutti i suoi figli, trovare un nodo e tutti i suoi genitori, trovare il conteggio dei nodi figlio che soddisfano determinate condizioni, ecc. È necessario sapere quali informazioni saranno necessarie dalla struttura per determinare la struttura che si adatterà meglio I tuoi bisogni.


Ciao, sto affrontando esattamente lo stesso problema indicato nella domanda e vorrei farti una domanda sugli argomenti sopra. Considerando una struttura come nell'argomento numero uno (tabella strutturata dell'organizzazione (non strutturata dai dipendenti) con ParentId a cui fa riferimento la stessa tabella), devo impostare chi è il capo di una determinata area. Assegnerò direttamente tutti i dipendenti di quell'area specifica. Dove metteresti il ​​capo di quella specifica area? Nella stessa area o sopra un gorup? Il mio approccio è di rimandarlo al gruppo sopra, che mi dà una struttura migliore penso. Grazie.
Marcos Buarque,

1
Il primo collegamento sembra essere rotto.
Jorge Leitao,

Risposta eccellente. Grazie @JeremyDWill!
bobocopy,

56

Dai un'occhiata alla gestione dei dati gerarchici in MySQL . Discute due approcci per l'archiviazione e la gestione di dati gerarchici (ad albero) in un database relazionale.

Il primo approccio è il modello di elenco di adiacenza, che è quello che sostanzialmente descrivi: avere una chiave esterna che si riferisce alla tabella stessa. Sebbene questo approccio sia semplice, può essere molto inefficiente per alcune query, come la costruzione dell'intero albero.

Il secondo approccio discusso nell'articolo è il modello di set nidificato. Questo approccio è molto più efficiente e flessibile. Fare riferimento all'articolo per spiegazioni dettagliate e domande di esempio.


il tuo link ha un argomento molto interessante in discussione. Grazie!
Fritz,

9

Se devi usare Relational DataBase per organizzare la struttura dei dati ad albero, Postgresql ha un fantastico modulo ltree che fornisce un tipo di dati per rappresentare le etichette dei dati memorizzati in una struttura gerarchica ad albero. È possibile ottenere l'idea da lì. (Per ulteriori informazioni, consultare: http://www.postgresql.org/docs/9.0/static/ltree.html )

In comune LDAP viene utilizzato per organizzare i record in struttura gerarchica.


2

Avere un tavolo con una chiave esterna per sé ha senso per me.

È quindi possibile utilizzare un'espressione di tabella comune in SQL o la precedente istruzione connect in Oracle per creare l'albero.


Ho una tabella di registro, con una colonna di identità LogID e una colonna ParentLogID con un FK che punta alla colonna LogID. Quando viene scritta la prima riga del log in una transazione, prendo SCOPE_IDENTITY (). Tutti gli altri record di registro vengono scritti con questo valore nella colonna ParentLogID. Questo è davvero utile per raggruppare le righe che appartengono insieme. È l'unico vero modo per vedere cosa è successo, senza questo, sarebbe un enorme casino di righe di log da più transazioni tutte mescolate insieme.
KM.

@KM - Ha detto "non ha senso" non "non ha senso"
John Rasch,


1

Ho usato la seguente implementazione su SQL SERVER 2005. Controlla qui


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.