11.10. Classes e famílias de operador #

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

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

A classe de operador 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 operador inclui funções de comparação para valores do tipo de dados int4. Na prática, a classe de operador padrão para o tipo de dados da coluna é geralmente suficiente. O principal motivo para existirem classes de operador é 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 operador para o tipo de dados e, em seguida, selecionando a classe apropriada ao construir o índice. A classe de operador 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 operador nativas, além das classes que são padrão:

A consulta a seguir mostra as 5 primeiras classes de operador 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 operador é, na verdade, apenas um subconjunto de uma estrutura maior chamada família de operador. 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 operador para cada um dos tipos de dados devem ser agrupadas na mesma família de operador. 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 operador 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 operador 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.