2010-04-07 12 views
10

J'ai une table MySQL qui représente des données pour un composant graphique d'arbre, voici la structure de ma table:Comment sélectionner tous les parents d'un noeud dans une table mysql hiérarchique?

treeTable ( 
    id INT NOT NULL PRIMARY KEY, 
    parentId INT, 
    name VARCHAR(255) 
); 

parentId est une auto-référencement clé étrangère.

Maintenant je veux écrire une procédure stockée qui obtient un identifiant de noeud et retourne un ensemble de résultats qui contient ce noeud et tous ses parents.

Par exemple, supposons que ma table est remplie de ces données:

1, null, 'root' 
2, 1 , 'level_1' 
3, 2 , 'level_2' 

Maintenant, je veux obtenir tous les nœuds parents du nœud 3 (nœuds 1 et 2) et retourner un jeu de résultats qui contient tous les arbres enregistrements. Est-ce que quelqu'un peut m'aider s'il vous plaît?

+0

Regardez ce sujet: [hiérarchique des données en MySQL] [1] [1]: http://stackoverflow.com/questions/1085287/hierarchical-data-in- mysql –

Répondre

2

Bonne question. Dans Oracle, vous devez utiliser quelque chose comme CONNECTER PAR. Puisque vous utilisez MySQL, je vous suggère de changer votre structure de données pour répondre efficacement à cette requête. Here sont quelques idées.

1

There was a similar discussion à ce qui pourrait être utile pour résoudre ce problème.

Je pense que je pourrais attaquer ce problème en récupérant récursivement les données jusqu'à ce que j'aie atteint le nœud racine (parent était null). Je pourrais avoir été enclin à le faire en dehors de la procédure stockée initialement (appeler plusieurs fois la chose jusqu'à ce que la ligne récupérée ait le parent nul), mais la solution "table de fermeture" sur la page que j'ai référencée ici ressemble à une excellente solution.

1

Il faut aussi penser à materialized paths. Concept assez simple qui est vraiment agnostique de base de données. Il est beaucoup plus facile de gérer les insertions etc, contrairement aux ensembles imbriqués, vous n'avez pas besoin de savoir que vous êtes des nœuds gauche/droit, etc. avant de les insérer.

1

MySQL ne prend pas en charge les fonctions de table 18.2.1. Stored Routine Syntax (qui est ce dont vous avez besoin pour retourner un jeu de résultats arbitraire).

Sans eux, vous avez trois choix:

  1. Déroulez la requête d'arbre à une profondeur maximale fixe et limite l'imbrication permise dans la hiérarchie,
  2. utilisent une boucle pour écrire les données dans une table temporaire et introduire une convention pour renvoyer les résultats à l'appelant. Vous devrez envisager une ré-entrée, ou,
  3. pré-calculer les résultats en incluant tous les ancêtres de chaque composant dans une table de support (comme indiqué) et le maintenir avec des déclencheurs sur le treeTable. De cette façon, la procédure stockée renvoie les lignes dans parentTable filtré de manière appropriée. Vous devrez créer une clé primaire composée et éventuellement des index pour un accès efficace.

La troisième option a de très petites lignes, donnera de bonnes performances et évite les limitations artificielles.

parentTable (
    id INT NOT NULL, 
    parentId INT NOT NULL 
); 

La suggestion d'utiliser une approche d'ensemble imbriqué peut être appropriée dans cette application où les données sont en grande partie statiques. Un ensemble de données en évolution rapide commencerait à avoir un impact sur les performances d'E/S car en moyenne, la moitié des lignes de la table sont mises à jour pour chaque insertion ou suppression.