Qual è il modo migliore per creare la tabella che rappresenterà l'albero? Voglio implementare una selezione, inserire, aggiornare ed eliminare che funzionerà bene con i big data. La selezione, ad esempio, dovrà supportare "Espandi TUTTO" - ottenendo tutti i bambini (e i figli) per un dato nodo.Come implementare la visualizzazione ad albero ad alte prestazioni in SQL Server 2005
risposta
Utilizzare CTE
.
Data l'albero-come la struttura della tabella:
id parent name
1 0 Electronics
2 1 TV
3 1 Hi-Fi
4 2 LCD
5 2 Plasma
6 3 Amplifiers
7 3 Speakers
, questa query restituirà id
, parent
e la profondità di livello, ordinato come un albero:
WITH v (id, parent, level) AS
(
SELECT id, parent, 1
FROM table
WHERE parent = 0
UNION ALL
SELECT id, parent, v.level + 1
FROM v
JOIN table t
ON t.parent = v.id
)
SELECT *
FROM v
id parent name
1 0 Electronics
2 1 TV
4 2 LCD
5 2 Plasma
3 1 Hi-Fi
6 3 Amplifiers
7 3 Speakers
Sostituire parent = 0
con parent = @parent
per ottenere solo un ramo di un albero.
Se esiste un indice su table (parent)
, questa query funzionerà in modo efficiente su una tabella molto grande, poiché utilizzerà ricorsivamente INDEX LOOKUP
per trovare tutti i chilrden per ciascun genitore.
Per aggiornare un ramo certo problema:
WITH v (id, parent, level) AS
(
SELECT id, parent, 1
FROM table
WHERE parent = 0
UNION ALL
SELECT id, parent, v.level + 1
FROM v
JOIN table t
ON t.parent = v.id
)
UPDATE table t
SET column = newvalue
WHERE t.id IN
(
SELECT id
FROM v
)
dove @parent
è la radice del ramo.
Verificare Joe Celko's book on trees and hierarchies per diversi modi per affrontare il problema della gerarchia. Il modello che scegli dipenderà da come pesi le ricerche rispetto agli aggiornamenti rispetto alla complessità. È possibile rendere le ricerche abbastanza rapide (soprattutto per ottenere tutti i bambini in un nodo) utilizzando il modello di elenco di adiacenza, ma gli aggiornamenti alla struttura sono più lenti.
Grazie, cercherò. L'unione è più efficiente del ricorsivo? Ho sentito che mssql 2005 ha un nuovo modo di gestire gli alberi, sai se funziona bene con DB di grandi dimensioni? – SirMoreno
L'UNION ALL all'interno di un CTE è ricorsivo, anche se non sono sicuro di come SQL Server lo gestisca dietro le quinte o se ci sono ritocchi delle prestazioni ad esso. Non ho fatto abbastanza test su larga scala con CTE per dire con certezza sulle prestazioni. –
È necessario porsi queste domande prima: 1) Qual è il rapporto tra le modifiche e le letture? (= albero per lo più statico o in costante cambiamento?) 2) Quanto profondo e quanto ti aspetti che l'albero cresca?
I set nidificati sono ideali per gli alberi per lo più statici in cui è necessario eseguire operazioni su interi rami. Gestisce alberi profondi senza problemi.
materializzata percorso funziona bene per dinamico (cambia) alberi vincolata profondità/prevedibile.
CTE recursive sono l'ideale per molto piccoli alberi, ma le operazioni di filiale ("ottenere tutti i bambini in questo ramo ..") ottenere molto costosi con profonda grande albero /.
My Tree è molto dinamico, molti aggiornamenti ma molti selezionano pure. E mi piacerebbe essere in grado di approfondire come 10-15 livelli. Ho trovato questo articolo sui set annidati: http://sqlblog.com/blogs/adam_machanic/archive/2006/07/12/swinging-from-tree-to-tree-using-ctes-part-1-adjacency -to-nested-sets.aspx I set nidificati come descritto in questo articolo sono la mia migliore opzione? grazie. – SirMoreno
Se si dispone di molti aggiornamenti e seleziona, l'opzione migliore sembra essere il percorso Enumeration modello, che viene brevemente descritto qui:
http://www.sqlteam.com/article/more-trees-hierarchies-in-sql
Mi sorprende che nessuno ha menzionato andando con un Closure Table . Molto efficiente per letture e molto semplice da scrivere.
Potete per favore elaborare la struttura dei tavoli? questa query funzionerà bene con un db di grandi dimensioni? – SirMoreno
grazie, Come si può fare un aggiornamento approfondito? - aggiorna tutti i nodi sotto un genitore? (Compresi i nipoti) – SirMoreno
ehi, sto cercando di farlo funzionare, e sembra che l'elemento VQ dosent lavoro, sto provando nel 2008 però.Inoltre, il livello deve essere memorizzato nel database, in quanto non è mostrato nella tabella? –