Os identificadores de objeto (OIDs) são utilizados internamente pelo PostgreSQL como chaves primárias em várias tabelas do sistema. Além disso, uma coluna do sistema OID é adicionada às tabelas criadas pelo usuário, a menos que seja especificado WITHOUT OIDS na criação da tabela, ou que a variável de configuração default_with_oids esteja definida como falso. O tipo oid representa um identificador de objeto. Também existem diversos tipos aliases para oid: regproc, regprocedure, regoper, regoperator, regclass, e regtype. A Tabela 8-19 mostra uma visão geral.
O tipo oid é implementado atualmente como inteiro de quatro bytes sem sinal. Portanto, não é grande o suficiente para proporcionar unicidade para todo o banco de dados em bancos de dados grandes, ou mesmo em tabelas individuais grandes. Por isso, é desencorajada a utilização da coluna OID de uma tabela criada pelo usuário como chave primária. É melhor usar os OIDs somente para referências às tabelas do sistema.
Nota: Os OIDs são incluídos por padrão nas tabelas criadas pelo usuário no PostgreSQL 8.0.0. Entretanto, este comportamento provavelmente mudará em uma versão futura do PostgreSQL. Eventualmente, as tabelas criadas pelo usuário não incluirão a coluna do sistema OID, a menos que seja especificado WITH OIDS quando a tabela for criada, ou a variável de configuração default_with_oids esteja definida como verdade. Se o aplicativo requer a presença da coluna do sistema OID na tabela, deve ser especificado WITH OIDS na criação da tabela para garantir a compatibilidade com as versões futuras do PostgreSQL.
O tipo oid possui poucas operações próprias além da comparação. Pode, entretanto, ser convertido em inteiro e, então, manipulado utilizando os operadores padrão para inteiros (Tome cuidado com as possíveis confusões entre inteiros com sinal e sem sinal se isto for feito).
Os tipos aliases de oid não possuem operações próprias com exceção de rotinas de entrada e saída especializadas. Estas rotinas são capazes de aceitar e mostrar nomes simbólicos para objetos do sistema, em vez do valor numérico puro e simples que o tipo oid usaria. Os tipos aliases permitem uma procura simplificada dos valores de OID para os objetos: por exemplo, para examinar as linhas de pg_attribute relacionadas com a tabela minha_tabela pode ser escrito
SELECT * FROM pg_attribute WHERE attrelid = 'minha_tabela'::regclass;
em vez de
SELECT * FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'minha_tabela');
Apesar de não parecer tão ruim assim, ainda está muito simplificado. Seria necessária uma sub-seleção bem mais complicada para obter o OID correto caso existissem várias tabelas chamadas minha_tabela em esquemas diferentes. O conversor de entrada regclass trata a procura de tabela de acordo com a configuração de procura de esquema e, portanto, faz a "coisa certa" automaticamente. De forma semelhante, converter o OID da tabela para regclass é útil para mostrar simbolicamente o OID numérico.
Tabela 8-19. Tipos identificadores de objetos
Nome | Referencia | Descrição | Exemplo de valor |
---|---|---|---|
oid | qualquer um | identificador numérico de objeto | 564182 |
regproc | pg_proc | nome de função | sum |
regprocedure | pg_proc | função com tipos dos argumentos | sum(int4) |
regoper | pg_operator | nome de operador | + |
regoperator | pg_operator | operador com tipos dos argumentos | *(integer,integer) ou -(NONE,integer) |
regclass | pg_class | nome da relação | pg_type |
regtype | pg_type | nome do tipo de dado | integer |
Todos os tipos aliases de OID aceitam nomes qualificados pelo esquema, e mostram nomes qualificados pelo esquema na saída se o objeto não puder ser encontrado no caminho de procura corrente sem que esteja qualificado. Os tipos aliases regproc e regoper somente aceitam a entrada de nomes únicos (não sobrecarregados) sendo, portanto, de uso limitado; para a maioria dos casos regprocedure e regoperator são mais apropriados. Em regoperator, os operadores unários são identificados escrevendo NONE no lugar do operando não utilizado.
Outro tipo identificador utilizado pelo sistema é o xid, ou identificador de transação (abreviado como xact). Este é o tipo de dado das colunas do sistema xmin e xmax. Os identificadores de transação são quantidades de 32 bits.
O terceiro tipo identificador é o cid, ou identificador de comando. Este é o tipo de dado das colunas do sistema cmin e cmax. Os identificadores de comando também são quantidades de 32 bits.
O último tipo de identificador utilizado pelo sistema é tid, ou identificador de tupla (identificador de linha). Este é o tipo de dado da coluna do sistema ctid. O identificador de tupla é um par (número do bloco, índice da tupla dentro do bloco) que identifica a posição física da linha dentro de sua tabela.
(As colunas do sistema são explicadas mais detalhadamente na Seção 5.4.)
Exemplo 8-10. Remover as linhas duplicadas da tabela
Este exemplo utiliza os OIDs para remover as linhas duplicadas da tabela. As linhas são agrupadas por todas as colunas, exceto OID, permanecendo em cada grupo apenas a linha que possui o menor OID, que supostamente é a primeira linha do grupo que foi inserida. [1]
BEGIN; CREATE TEMPORARY TABLE t (c1 text, c2 text, c3 text) ON COMMIT DROP; INSERT INTO t VALUES ('x', 'x', 'x'); INSERT INTO t VALUES ('x', 'x', 'y'); -- 1ª duplicada (fica) INSERT INTO t VALUES ('x', 'y', 'x'); INSERT INTO t VALUES ('x', 'x', 'y'); -- 2ª duplicada (sai) INSERT INTO t VALUES ('x', 'x', 'y'); -- 3ª duplicada (sai) INSERT INTO t VALUES ('x', 'y', 'y'); INSERT INTO t VALUES ('y', 'y', 'y'); -- 1ª duplicada (fica) INSERT INTO t VALUES ('y', 'y', 'y'); -- 2ª duplicada (sai) SELECT oid, t.* FROM t; oid | c1 | c2 | c3 -------+----+----+---- 17839 | x | x | x 17840 | x | x | y 17841 | x | y | x 17842 | x | x | y 17843 | x | x | y 17844 | x | y | y 17845 | y | y | y 17846 | y | y | y (8 linhas) DELETE FROM t WHERE oid NOT IN (SELECT min(oid) FROM t GROUP BY c1, c2, c3); DELETE 3 SELECT oid, t.* FROM t; oid | c1 | c2 | c3 -------+----+----+---- 17839 | x | x | x 17840 | x | x | y 17841 | x | y | x 17844 | x | y | y 17845 | y | y | y (5 linhas) COMMIT;
[1] |
Exemplo escrito pelo tradutor, não fazendo parte do manual original. |