PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Chemin matérialisé Postgres - Quels sont les avantages d'utiliser ltree ?

TL;DR Les étiquettes réutilisables, les modèles de recherche complexes et les recherches d'ascendance sur plusieurs nœuds descendants (ou un seul nœud dont le chemin n'a pas encore été récupéré) ne peuvent pas être accomplis à l'aide d'un index de chemin matérialisé.

Pour ceux qui s'intéressent aux détails sanglants...

Premièrement, votre question n'est pertinente que si vous ne réutilisez aucune étiquette dans la description de votre nœud. Si vous l'étiez, le l-tree est vraiment la seule option des deux. Mais les implémentations de chemins matérialisés n'en ont généralement pas besoin, alors mettons cela de côté.

Une différence évidente sera dans la flexibilité des types de recherches que l-tree vous offre. Considérez ces exemples (du ltree docs liés dans votre question):

foo         Match the exact label path foo
*.foo.*     Match any label path containing the label foo
*.foo       Match any label path whose last label is foo

La première requête est évidemment réalisable avec un chemin matérialisé. Le dernier est également réalisable, où vous ajusteriez la requête comme une recherche de frères et sœurs. Le cas intermédiaire, cependant, n'est pas directement réalisable avec une seule recherche d'index. Vous devrez soit diviser cela en deux requêtes (tous les descendants + tous les ancêtres), soit recourir à une analyse de table.

Et puis il y a des requêtes vraiment complexes comme celle-ci (également de la documentation) :

Top.*{0,2}.sport*@.!football|tennis.Russ*|Spain

Un index de chemin matérialisé serait inutile ici, et une analyse complète de la table serait nécessaire pour gérer cela. l-tree est la seule option si vous souhaitez effectuer cela en tant que requête SARGable.

Mais pour les opérations hiérarchiques standard, trouver l'un des éléments suivants :

  • parent
  • enfants
  • descendance
  • nœuds racine
  • nœuds feuilles

chemin matérialisé fonctionnera aussi bien que l-tree. Contrairement à l'article lié ci-dessus , la recherche de tous les descendants d'un ancêtre commun est très faisable en utilisant un b-tree. Le format de requête WHERE path LIKE 'A.%' est SARGable à condition que votre index soit préparé correctement (j'ai dû baliser explicitement mon index de chemin avec varchar_pattern_ops pour que cela fonctionne).

Ce qui manque à cette liste, c'est de trouver tous les ancêtres pour un descendant. Le format de requête WHERE 'A.B.C.D' LIKE path || '.%' n'utilisera malheureusement pas l'index. Une solution de contournement que certaines bibliothèques implémentent consiste à analyser les nœuds ancêtres du chemin et à les interroger directement :WHERE id IN ('A', 'B', 'C') . Cependant, cela ne fonctionnera que si vous ciblez les ancêtres d'un nœud spécifique dont vous avez déjà récupéré le chemin. l-tree va gagner sur celui-ci.