Implémentation d'une structure de données hiérarchique dans une base de données
Je sais qu'il y a deux approches: la liste d'adjacence et imbriquée de l'arbre. Il est dit que le critère de contiguïté liste peut devenir lent à utiliser sur la traversée, car de nombreuses questions. Mais je ne connais pas de chiffres réalistes pour cela. Le site que je suis en train de faire sera de l'ordre de 200 pages. Est transversal à générer (par exemple) un sitemap va prendre plus de temps que d'environ 0,3 secondes?
En cours d'exécution sur MySQL (innoDB) avec une LAMPE de pile.
Je préfère le mettre en œuvre la contiguïté si possible en raison de la conception simpliste.
Grâce.
source d'informationauteur
Vous devez vous connecter pour publier un commentaire.
Il y a plus d'options que les deux que vous citez. Il y a:
Voir ma réponse à "Quel est le plus efficace/moyen élégant pour analyser une table à plat dans un arbre?"
Ou un couple de livres:
L'article La gestion Hiérarchique des Données dans MySQL va dans les détails à ce sujet.
Je vous recommande le "sous ensemble" technique", car elle permet d'obtenir l'ensemble de l'arbre (et ses enfants) dans une requête. Fondamentalement, les lectures sont bon marché, mais les écritures sont chers parce que l'ensemble de l'arbre doit être ré-équilibré. Mais dans le cas où vous avez 99% lit ensuite son totalement justifiable.
L'approche naïve pour l'analyse d'une liste d'adjacence nécessite beaucoup de requêtes, et pour les grandes listes peuvent prendre beaucoup de temps à construire dans la mémoire. Pour référence, l'approche naïve je fais allusion pourrait être résumés comme suit: Sélectionner tous les éléments, sans parents, Puis pour chaque élément de manière récursive obtenir ses enfants. Cette approche nécessite n+1 requêtes de base de données.
J'ai utilisé la méthode suivante pour construire une liste d'adjacence avec 1 de la requête. Sélectionnez tous les éléments de formulaire de la base de données. Le transfert de tous les éléments dans un tableau indexé par leur clé. Parcourir le tableau et lui affecter une référence de l'objet parent pour chacun de ses enfants. Parcourir le tableau à une seconde de temps et de supprimer tous les objets enfants, laissant seulement le niveau de la racine des objets.
Puisque vous avez mentionné pile LAMP, PHP code pour ce faire est à peu près comme suit:
Veuillez noter que ce code est destiné à illustrer une technique pour la construction d'une liste d'adjacence à partir d'une seule requête de base de données. Il pourrait probablement être optimisé pour moins de consommation de mémoire, etc. Il n'a également pas été testé.
Jim,
Voici quelques questions qui pourraient vous aider:
SQL façon de stocker et de la navigation des hiérarchies
Quel est le meilleur schéma de base de données pour ma navigation
L'autre approche est appelée "ensemble imbriqué", je pense, pas de "nested arbre".
De toute façon, une bonne chose à propos d'un plan du site est que vous savez peut-être sa profondeur maximale. Je pense que le problème de la proximité du modèle est que les requêtes SQL correspondant fonctionne sur un seul niveau à la fois, donc si vous avez des " n " niveaux, alors vous avez besoin d'une boucle de 'n' SQL ... mais je pense (je ne suis pas sûr) que si vous connaissez le maximum de " n " à l'avance, alors vous pouvez code correspondant fixe-nombre-de-plusieurs-niveaux SQL.
0,3 secondes sonne pour moi comme un très long temps à la figure de 200 pages, donc c'est probablement OK.
Également une carte du site n'est pas mis à jour très souvent; ainsi, même si elle prend du temps à récupérer à partir de SQL, vous pouvez probablement le cache de l'extrait/calculé arbre dans la mémoire RAM.
Alternativement, au lieu de se soucier de la SQL pour créer une arborescence, vous pouvez simplement le magasin le plus simplement possible (liste d'adjacence), le récupérer à partir de la base de données comme un simple ensemble de lignes, et construire l'arbre dans la mémoire vive (en utilisant des boucles dans votre langage de programmation) au lieu d'utiliser des boucles dans le SQL pour créer l'arborescence à l'aide d'instructions SQL.
Pour completeneness: Oracle a la
START_WITH
etCONNECT_BY
opérateurs: voir ce Des Requêtes Hiérarchiques document.