Une définition d'index peut indiquer une classe d'opérateurs pour chaque colonne de l'index.
CREATE INDEXnom
ONtable
(colonne
classe_operateur
[options de tri
][, ...]);
La classe d'opérateurs identifie les opérateurs que l'index doit utiliser
sur cette colonne. Par exemple, un index B-tree sur une colonne de type
int4
utilise la classe int4_ops
.
Cette classe d'opérateurs comprend des fonctions de comparaison pour les
valeurs de type int4
.
En pratique, la classe d'opérateurs par défaut pour le type de données de la
colonne est généralement suffisante. Les classes d'opérateurs sont utiles pour
certains types de données, pour lesquels il peut y avoir plus d'un
comportement utile de l'index.
Par exemple, une donnée de type nombre complexe peut être classée
par sa valeur absolue, ou par sa partie entière.
Cela peut s'obtenir en définissant deux classes d'opérateurs pour ce
type de données et en sélectionnant la bonne classe à la création de l'index.
La classe d'opérateur détermine l'ordre de tri basique (qui peut ensuite
être modifié en ajoutant des options de tri comme
COLLATE
, ASC
/DESC
et/ou
NULLS FIRST
/NULLS LAST
).
Il y a quelques classes d'opérateurs en plus des classes par défaut :
Les classes d'opérateurs text_pattern_ops
,
varchar_pattern_ops
et
bpchar_pattern_ops
supportent les index B-tree sur
les types text
, varchar
et char
,
respectivement. À la différence des classes d'opérateurs par défaut,
les valeurs sont comparées strictement caractère par caractère plutôt
que suivant les règles de tri spécifiques à la localisation.
Cela rend ces index utilisables pour des requêtes qui utilisent des
recherches sur des motifs (LIKE
ou des expressions
régulières POSIX) quand la base de données n'utilise pas la locale standard
« C ».
Par exemple, on peut indexer une colonne varchar
comme ceci :
CREATE INDEX test_index ON test_table (col varchar_pattern_ops);
Il faut créer un index avec la classe d'opérateurs par
défaut pour que les requêtes qui utilisent une comparaison <
,
<=
, >
ou >=
ordinaire utilisent un index. De telles requêtes ne peuvent pas utiliser
les classes d'opérateurs
.
Néanmoins, des comparaisons d'égalité ordinaires peuvent utiliser ces
classes d'opérateur. Il est possible de créer plusieurs index sur la
même colonne avec différentes classes d'opérateurs.
Si la locale C est utilisée, les classes
d'opérateur xxx
_pattern_ops
ne sont pas nécessaires, car un index avec une classe d'opérateurs
par défaut est utilisable pour
les requêtes de correspondance de modèles dans la locale C.
xxx
_pattern_ops
Les requêtes suivantes montrent les classes d'opérateurs prédéfinies :
SELECT am.amname AS index_method, opc.opcname AS opclass_name, opc.opcintype::regtype AS indexed_type, opc.opcdefault AS is_default FROM pg_am am, pg_opclass opc WHERE opc.opcmethod = am.oid ORDER BY index_method, opclass_name;
Une classe d'opérateurs n'est qu'un sous-ensemble d'une structure plus large appelée famille d'opérateurs. Dans les cas où plusieurs types de données ont des comportements similaires, il est fréquemment utile de définir des opérateurs identiques pour plusieurs types de données et d'autoriser leur utilisation avec des index. Pour cela, les classes d'opérateur de chacun de ces types doivent être groupés dans la même famille d'opérateurs. Les opérateurs inter-types sont membres de la famille, mais ne sont pas associés avec une seule classe de la famille.
Cette version étendue de la requête précédente montre la famille d'opérateur à laquelle appartient chaque classe d'opérateur :
SELECT am.amname AS index_method, opc.opcname AS opclass_name, opf.opfname AS opfamily_name, opc.opcintype::regtype AS indexed_type, opc.opcdefault AS is_default FROM pg_am am, pg_opclass opc, pg_opfamily opf WHERE opc.opcmethod = am.oid AND opc.opcfamily = opf.oid ORDER BY index_method, opclass_name;
Cette requête affiche toutes les familles d'opérateurs définies et tous les opérateurs inclus dans chaque famille :
SELECT am.amname AS index_method, opf.opfname AS opfamily_name, amop.amopopr::regoperator AS opfamily_operator FROM pg_am am, pg_opfamily opf, pg_amop amop WHERE opf.opfmethod = am.oid AND amop.amopfamily = opf.oid ORDER BY index_method, opfamily_name, opfamily_operator;