2009-05-06 14 views
2

Je pense que c'est probablement un problème commun, mais à partir de ma recherche google je ne peux pas trouver une solution tout à fait spécifique à mon problème.Requête SQL pour un organigramme?

J'ai une liste d'organisations (tableau) dans ma base de données et je dois être capable d'exécuter des requêtes en fonction de leur hiérarchie. Par exemple, si vous interrogez l'organisation la plus élevée, je souhaite renvoyer les ID de toutes les organisations répertoriées sous cette organisation. En outre, si j'interroge une organisation de milieu de gamme, je souhaite que seuls les ID d'organisation soient répertoriés sous cette organisation.

Quelle est la meilleure façon de: a) configurer le schéma de base de données et b) interroger? Je veux seulement envoyer l'ID d'organisation le plus haut et obtenir les ID sous cette organisation.

Je pense que cela a du sens, mais je peux clarifier si nécessaire.

+0

réponses similaires à votre problème: http://stackoverflow.com/questions/38801/sql-how-to-store-and-navigate-hierarchies http://stackoverflow.com/questions/378608/how- can-i-select-all-leaf-noeuds-in-a-sql-hierarchie-under-a-given-node – Nick

+0

quelle version/type de si mssql? 2005/2008 vous pouvez utiliser CTE pour régresser les données assez facilement – u07ch

+0

Je suis curieux de savoir comment vous allez afficher cela. Je sais que vous avez dit tableau, mais comment, quelle bibliothèque? – johnny

Répondre

2

Une façon simple est de stocker la filiation de l'organisation dans un champ de texte, comme:

VENTE-EUROPE-NORD

Pour rechercher toutes les organisations de vente, vous pouvez interroger sur SALES-%. Pour chaque organisation commerciale européenne, interrogez sur SALES-EUROPE-%.

Si vous renommez une organisation, veillez également à mettre à jour ses organisations enfants.

Cela reste simple, sans récursion, au prix d'une certaine flexibilité.

+0

Autant que je sache, c'est la seule solution où vous pouvez obtenir des résultats dans un nombre fixe de requêtes (j'espère - 1). Toutes les autres méthodes de stockage d'un champ parent_id entraîneront de nombreuses requêtes et un problème de performances potentiel. Notez qu'en utilisant cet identificateur unique, vous obtenez des identifiants de journaux qui ne sont pas optimaux pour les bases de données. Vous pouvez donc avoir ces clés en tant que clé secondaire. –

+0

Parfait! Merci! –

+0

c'est une solution TERRIBLE et ça va revenir vous mordre vraiment mal quand la hiérarchie change. C'est quelque chose que ma société a lentement refactoring hors de notre système pendant des années ... si douloureux. Je vais essayer de trouver une meilleure approche que j'ai vue une fois. – rmeador

0

Vous pourriez avoir une organisation avec un identifiant PK et une référence FK parent à l'identifiant. Ensuite, pour la requête, utilisez (si votre backend de base de données les prend en charge) des requêtes récursives, alias Common Table Expressions.

1

La méthode la plus simple consiste à avoir une colonne ParentID, qui est une clé étrangère de la colonne ID dans la même table, NULL pour les nœuds racine. Mais cette méthode a quelques inconvénients.

Nested sets sont un moyen efficace de stocker des arbres dans une base de données relationnelle.

+0

Je viens de remarquer quand j'ai lu votre commentaire sur ma réponse que vous aviez déjà un lien dans votre réponse à quelque chose de presque identique à ma réponse ... si j'avais réalisé qu'avant de poster, j'aurais poussé votre réponse en tant que corriger un. – rmeador

3

Comme promis dans mon commentaire, j'ai creusé un article sur la façon de stocker des hiérarchies dans une base de données qui permet la récupération en temps constant de sous-arbres arbitraires. Je pense qu'il répondra à vos besoins beaucoup mieux que la réponse actuellement marquée comme acceptée, à la fois dans la facilité d'utilisation et la rapidité d'accès. Je pourrais jurer que j'ai vu ce même concept sur Wikipédia à l'origine, mais je ne peux pas le trouver maintenant. Il est apparemment appelé "traversée d'arbre de pré-modification modifiée". L'essentiel est de numéroter deux fois chaque nœud de l'arbre, en effectuant une traversée en profondeur, une fois en descente, et une fois en remontant (c'est-à-dire lorsque vous déroulerez la pile, dans une implémentation récursive) . Cela signifie que les enfants d'un nœud donné ont tous leurs nombres entre les deux nombres de ce nœud. Jetez un index sur ces colonnes et vous avez des recherches très rapides. Je suis sûr que c'est une explication terrible, alors lisez l'article, qui approfondit et inclut des images.

+0

solution très cool. – yetanotherdave

+0

L'article décrit un arbre équilibré personnalisé. C'est une solution TERRIBLE et elle reviendra vous mordre lorsque la hiérarchie changera. ;-) – Andomar

+0

@Andromar: d'accord, je méritais que pour la légère hyperbole dans mon commentaire sur votre réponse ... :) la principale différence ici est que l'actualisation de la hiérarchie est une opération très rapide et directe quand elle change. – rmeador