La definición de un índice puede especificar una clase de operadores para cada columna de un índice.
CREATE INDEXnombreONtabla(columnaclase_de_operadores[ (opciones_de_clase_de_operadores) ] [opciones de ordenación] [, ...]);
La clase de operadores identifica los operadores que utilizará el índice
para esa columna. Por ejemplo, un índice B-tree en el tipo int4
utilizaría la clase int4_ops; esta clase de
operadores incluye funciones de comparación para valores de tipo int4.
En la práctica, la clase de operadores por defecto para el tipo de datos de la columna suele
ser suficiente. La razón principal para tener clases de operadores es
que para algunos tipos de datos, podría haber más de un comportamiento de índice
significativo. Por ejemplo, podríamos querer ordenar un tipo de datos de números complejos
bien por valor absoluto o bien por parte real. Podríamos hacerlo
definiendo dos clases de operadores para el tipo de datos y seleccionando después
la clase adecuada al crear un índice. La clase de operadores determina
el orden de clasificación básico (que luego se puede modificar añadiendo opciones de ordenación
COLLATE,
ASC/DESC y/o
NULLS FIRST/NULLS LAST).
También hay algunas clases de operadores integradas además de las predeterminadas:
Las clases de operadores text_pattern_ops,
varchar_pattern_ops y
bpchar_pattern_ops admiten índices B-tree en
los tipos text, varchar y
char respectivamente. La
diferencia con las clases de operadores predeterminadas es que los valores
se comparan estrictamente carácter por carácter en lugar de
hacerlo según las reglas de ordenación específicas de la localización. Esto hace que
estas clases de operadores sean adecuadas para su uso en consultas que involucren
expresiones de coincidencia de patrones (LIKE o expresiones
regulares POSIX) cuando la base de datos no utiliza la localización estándar
“C”. Como ejemplo, podrías indexar una
columna varchar de esta forma:
CREATE INDEX test_index ON test_table (col varchar_pattern_ops);
Ten en cuenta que también deberías crear un índice con la clase de operadores
predeterminada si quieres que las consultas que involucren comparaciones ordinarias <,
<=, > o >=
utilicen un índice. Dichas consultas no pueden usar las
clases de operadores .
(Sin embargo, las comparaciones de igualdad ordinarias sí pueden usar estas
clases de operadores). Es posible crear múltiples
índices en la misma columna con diferentes clases de operadores.
Si utilizas la localización C, no necesitas las clases de operadores
xxx_pattern_ops,
porque un índice con la clase de operadores predeterminada es utilizable
para consultas de coincidencia de patrones en la localización C.
xxx_pattern_ops
La siguiente consulta muestra todas las clases de operadores definidas:
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;
Una clase de operadores es en realidad solo un subconjunto de una estructura mayor llamada familia de operadores. En los casos en que varios tipos de datos tienen comportamientos similares, con frecuencia es útil definir operadores cruzados entre tipos de datos y permitir que estos funcionen con índices. Para ello, las clases de operadores para cada uno de los tipos deben agruparse en la misma familia de operadores. Los operadores cruzados son miembros de la familia, pero no están asociados a ninguna clase individual dentro de la familia.
Esta versión ampliada de la consulta anterior muestra la familia de operadores a la que pertenece cada clase de operadores:
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;
Esta consulta muestra todas las familias de operadores definidas y todos los operadores incluidos en cada familia:
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;
El componente psql tiene los
comandos \dAc, \dAf
y \dAo, que proporcionan versiones ligeramente más sofisticadas
de estas consultas.