11.10. Classes e famílias de operadores #

Uma definição de índice pode especificar uma classe de operadores para cada coluna de um índice.

CREATE INDEX nome ON tabela ↵
            (coluna opclass ↵
            [ ( opclass_options ) ] ↵
            [opções de classificação] ↵
            [, ...]);

A classe de operadores identifica os operadores a serem usados pelo índice desta coluna. Por exemplo, um índice B-Tree no tipo de dados int4 usaria a classe int4_ops; esta classe de operadores inclui funções de comparação para valores do tipo de dados int4. Na prática, a classe de operadores padrão para o tipo de dados da coluna é geralmente suficiente. O principal motivo para existirem classes de operadores é que, para alguns tipos de dados, pode haver mais de um comportamento de índice significativo. Por exemplo, podemos querer classificar o tipo de dados número complexo pelo valor absoluto (módulo), ou pela parte real. Poderíamos fazer isto definindo duas classes de operadores para o tipo de dados e, em seguida, selecionando a classe apropriada ao construir o índice. A classe de operadores determina a ordem de classificação básica (que pode ser modificada adicionando as opções de classificação COLLATE, ASC/DESC e/ou NULLS FIRST/NULLS LAST).

Também existem algumas classes de operadores nativas, além das classes que são padrão:

A consulta a seguir mostra as 5 primeiras classes 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
    LIMIT 5;

 index_method |   opclass_name    | indexed_type | is_default
--------------+-------------------+--------------+------------
 brin         | bit_minmax_ops    | bit          | t
 brin         | box_inclusion_ops | box          | t
 brin         | bpchar_bloom_ops  | character    | f
 brin         | bpchar_minmax_ops | character    | t
 brin         | bytea_bloom_ops   | bytea        | f
(5 linhas)

Uma classe de operadores é, na verdade, apenas um subconjunto de uma estrutura maior chamada família de operadores. Nos casos em que vários tipos de dados têm comportamentos semelhantes, é frequentemente útil definir operadores de tipo de dados cruzados, e permitir que funcionem com índices. Para fazer isto, as classes de operadores para cada um dos tipos de dados devem ser agrupadas na mesma família de operadores. Os operadores de tipo de dados cruzado são membros da família, mas não estão associados a uma única classe na família.

Esta versão expandida da consulta anterior mostra a família de operadores à qual cada classe de operadores pertence:

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
    LIMIT 5;

 index_method |   opclass_name    |   opfamily_name   | indexed_type | is_default
--------------+-------------------+-------------------+--------------+------------
 brin         | bit_minmax_ops    | bit_minmax_ops    | bit          | t
 brin         | box_inclusion_ops | box_inclusion_ops | box          | t
 brin         | bpchar_bloom_ops  | bpchar_bloom_ops  | character    | f
 brin         | bpchar_minmax_ops | bpchar_minmax_ops | character    | t
 brin         | bytea_bloom_ops   | bytea_bloom_ops   | bytea        | f
(5 linhas)

Esta consulta mostra todas as famílias de operadores definidas, e todos os operadores incluídos em cada família:

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
    LIMIT 5;

 index_method | opfamily_name  | opfamily_operator
--------------+----------------+-------------------
 brin         | bit_minmax_ops | =(bit,bit)
 brin         | bit_minmax_ops | <(bit,bit)
 brin         | bit_minmax_ops | >(bit,bit)
 brin         | bit_minmax_ops | <=(bit,bit)
 brin         | bit_minmax_ops | >=(bit,bit)
(5 linhas)

Dica

O psql possui os comandos \dAc, \dAf e \dAo, que fornecem versões um pouco mais sofisticadas destas consultas.