Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Le ltree (inclue par défaut) ajoute le type de données
ltree
permettant de représenter des chemins dans un arbre taxonomique.Un index GIST sur le type ltree est alors très efficace pour rechercher des taxons parents/enfants.
Vue matérialisée
taxonomie.taxref_tree
Le VM est assez légère et rapide à générer (~140Mo, et 1 minute pour la construire, index compris, sur l'ensemble du taxref).
La colonne path (ltree) contient les cd_noms de l'ensemble des parents, jusqu'à la racine de l'arbre. Elle ne concerne que les taxons de référence (cd_nom = cd_ref). Elle pourrait être générée sur l'ensemble des synonymes, mais cela ferait du stockage inutile d'information dupliquée. Le cd_nom étant unique dans la VM, on est bien sur une cardinalité "1-0..1" avec la table taxonomie.taxref.
J'avais initialement exploré la piste d'une VM type "cd_nom int | cd_nom_parent int" , avec pour chaque cd_nom l'ensemble des ancêtres. Mais cette dernière solution était plus lourde, moins performante et moins intuitive.
Utilisation et exemples
L'opérateur @> permet de comparer deux path en utilisant l'index GIST. Il renvoi TRUE si le chemin à gauche est un ancêtre du chemin à droite.
ltree intègre aussi une fonction lca() permettant de trouver les ancêtres communs à une liste de path.
Discussion
Le module ltree intègre aussi un type lquery qui permet des recherches types regex dans les path (par exemple pour recherche un cd_nom au début, dans ou à la fin d'un path :
'*.'||cd_nom||'.*'
, mais l'usage est beaucoup plus lent que les opérateurs permettant de comparer deux path.Il existe plusieurs approches possibles, plus ou moins verbeuses et/ou claires. Les différentes fonctions et opérateurs inclus avec ltree semble couvrir la plupart des usages possibles (subpath, index, nlevel, etc.).
A voir :
https://www.cybertec-postgresql.com/en/postgresql-speeding-up-recursive-queries-and-hierarchic-data/
http://patshaughnessy.net/2017/12/13/saving-a-tree-in-postgres-using-ltree
http://patshaughnessy.net/2017/12/15/looking-inside-postgres-at-a-gist-index
https://docs.postgresql.fr/12/ltree.html