2009-05-12 8 views

Répondre

8

Utilisez CTE 's.

Compte tenu de la structure de la table arborescente:

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 

, cette requête retourne id, parent et le niveau de profondeur, ordonné comme un arbre:

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 

Remplacer parent = 0 avec parent = @parent pour obtenir seulement une branche d'un arbre.

Pourvu qu'il existe un index sur table (parent), cette requête fonctionnera efficacement sur une très grande table, car elle utilisera récursivement INDEX LOOKUP pour trouver tous les chilrden pour chaque parent.

Pour mettre à jour une branche, numéro:

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 
     ) 

@parent est la racine de la branche.

+0

Pouvez-vous élaborer sur la structure des tables? cette requête fonctionnera-t-elle bien avec une grande base de données? – SirMoreno

+0

merci, Comment peut faire une mise à jour en profondeur? - mettre à jour tous les nœuds sous un parent? (y compris les petits-enfants) – SirMoreno

+0

hé, j'essaie de faire fonctionner ça, et ça ressemble à l'article de vq travail dosent, j'essaye en 2008 cependant.Le niveau doit-il également être stocké dans la base de données, car il n'apparaît pas dans le tableau? –

2

Consultez la section Joe Celko's book on trees and hierarchies pour connaître les différentes manières de résoudre le problème de hiérarchie. Le modèle que vous choisissez dépendra de la façon dont vous pondérez les recherches par rapport aux mises à jour par rapport à la complexité. Vous pouvez effectuer les recherches assez rapidement (en particulier pour obtenir tous les enfants dans un nœud) en utilisant le modèle de liste d'adjacence, mais les mises à jour de l'arborescence sont plus lentes.

+0

Merci, je vais chercher. L'union est-elle plus efficace que la récursive? J'ai entendu dire que mssql 2005 a une nouvelle façon de traiter les arbres, savez-vous si cela fonctionne bien avec les grandes bases de données? – SirMoreno

+0

L'ALL UNION d'un CTE est récursif, bien que je ne sois pas sûr de la manière dont SQL Server le gère en coulisse ou s'il y a des ajustements de performances. Je n'ai pas fait assez de tests à grande échelle avec des CTE pour dire avec certitude sur la performance. –

3

Vous devez d'abord vous poser ces questions: 1) Quel est le rapport entre les modifications et les lectures? (= arbre essentiellement statique ou en constante évolution?) 2) Quelle est la profondeur et la grosseur de l'arbre?

Les ensembles imbriqués sont parfaits pour les arbres essentiellement statiques où vous avez besoin d'opérations sur des branches entières. Il gère les arbres profonds sans problèmes.

Le chemin matérialisé fonctionne bien pour les arbres dynamiques (changeants) avec une profondeur contrainte/prévisible.

Les CTE récursifs sont idéaux pour les très petits arbres, mais les opérations de branchement ("avoir tous les enfants dans cette branche ..") deviennent très coûteuses avec un arbre profond/grand.

+1

Mon arbre est très dynamique, beaucoup de mises à jour mais beaucoup de sélections également. Et j'aimerais être en mesure d'atteindre 10-15 niveaux. J'ai trouvé cet article sur Ensembles imbriqués: http://sqlblog.com/blogs/adam_machanic/archive/2006/07/12/swinging-from-tree-to-tree-using-ctes-part-1-adjacency -to-nested-sets.aspx Est-ce que les ensembles imbriqués décrits dans cet article seront ma meilleure option? merci. – SirMoreno

0

Je suis surpris que personne n'a mentionné d'aller avec un Closure Table . Très efficace pour les lectures et assez simple à écrire.

Questions connexes