PostgreSQLLa base de données la plus sophistiquée au monde.
Documentation PostgreSQL 15.10 » Internes » Index B-Tree » Comportement des classes d'opérateur B-Tree

67.2. Comportement des classes d'opérateur B-Tree

Comme montré dans Tableau 38.3, une classe d'opérateur btree doit fournir cinq opérateurs de comparaison, <, <=, =, >= et >. On pourrait supposer que <> devraient également faire partie de la classe d'opérateur, mais ce n'est pas le cas car cela ne serait presque jamais utile d'utiliser une clause WHERE <> dans une recherche d'index. (Dans certains cas, le planificateur traite <> comme s'il était associé avec une classe d'opérateur btree ; mais il trouve cet opérateur via le lien du négateur de l'opérateur =, plutôt que depuis pg_amop.)

Quand plusieurs types de données partagent des sémantiques de tri presque identiques, leurs classes d'opérateurs peuvent être regroupées dans une famille d'opérateur. Il est avantageux de procéder ainsi car cela permet au planificateur de faire des déductions quant aux comparaisons entre plusieurs types. Chaque classe d'opérateur au sein d'une famille devrait contenir les opérateurs concernant un seul type (et les fonctions de support associées), tandis que les opérateurs de comparaison inter-types et les fonctions de support sont « libres » dans la famille. Il est recommandé qu'un ensemble complet d'opérateurs inter-types soit inclus dans la famille, afin d'assurer que le planificateur puisse représenter n'importe quelle condition de comparaison qu'il pourrait déduire depuis la transitivité.

Il y a des supposition basiques qu'une famille d'opérateur btree doit satisfaire :

  • Un opérateur = doit être une relation d'équivalence ; c'est-à-dire que pour toutes les valeurs non nulles A, B, C du type de données :

    • A = A est vrai (loi de réflexivité)

    • si A = B, alors B = A (loi de symétrie)

    • si A = B et B = C, alors A = C (loi de transitivité)

  • Un opérateur < doit être une relation de tri forte ; c'est-à-dire, pour toutes les valeurs non nulles A, B, C :

    • A < A est faux (loi d'antiréflexivité)

    • si A < B et B < C, alors A < C (loi de transitivité)

  • De plus, le tri est total ; c'est-à-dire, pour toutes les valeurs non nulles A, B :

    • exactement une seule des expressions A < B, A = B, et B < A est vraie (loi de trichotomie)

    (Bien entendu, la loi de trichotomie justifie la définition de la fonction de support de comparaison).

Les trois autres opérateurs sont définis avec = et < de manière évidente, et doivent se comporter de manière cohérentes avec ceux-ci.

Pour une famille d'opérateur supportant plusieurs types de données, les lois définies auparavant doivent continuer à s'appliquer quand A, B, C sont pris de n'importe quel type de données de la famille. Les lois de transitivité sont les plus délicates à garantir, car, dans des situations inter-types, elles représentent des déclarations comme quoi les comportements de deux ou trois différents opérateurs sont cohérents. Comme exemple, mettre float8 et numeric dans la même famille d'opérateur ne fonctionnerait pas, du moins pas avec les sémantiques actuelles qui définissent que les valeurs de type numeric sont converties en float8 pour la comparaison vers un float8. Du fait de la précision limitée du type float8, cela veut dire que des valeurs numeric distinctes seraient considérées par la comparaison comme égales à la même valeur float8, et par conséquent la loi de transitivé échouerait.

Une autre exigence pour les familles contenant plusieurs types est que les transtypages implicites ou de coercition binaire qui sont définis entre les types de données inclus dans la famille d'opérateur ne doivent pas changer l'ordre de tri associé.

La raison pour laquelle les index btree nécessitent que ces lois soient vérifiées pour un même type de données devraient être tout à fait claires : sans celles-ci, il n'y a pas d'ordre avec lequel organiser les clés. En outre, les recherches d'index utilisant une clé de comparaison d'un type de données différent nécessitent que la comparaison se comporte sainement à travers deux types de données. Les extensions à trois types de données ou plus au sein d'une famille ne sont pas strictement requis par le mécanisme d'index btree lui-même, mais le planificateur se repose sur eux pour des besoins d'optimisation.