SQL, OIDs do Postgres, o que são e por que são úteis?

161

Eu estou olhando para alguma criação de tabela do PostgreSQL e me deparei com isso:

CREATE TABLE (
...
) WITH ( OIDS = FALSE );

Eu li a documentação fornecida pelo postgres e conheço o conceito de identificador de objeto do OOP, mas ainda não entendo,

  • por que esse identificador seria útil em um banco de dados?
  • tornar as consultas mais curtas?
  • quando deve ser usado?
fabrizioM
fonte
Não consigo encontrar nenhuma referência a ser citada no momento, mas, para sua informação, ouvi dizer que usar o Microsoft Access como front-end do Postgres requer a presença da oldcoluna do sistema .
Basil Bourque

Respostas:

165

Os OIDs basicamente fornecem um ID interno globalmente exclusivo para cada linha, contida em uma coluna do sistema (em oposição a uma coluna de espaço do usuário). Isso é útil para tabelas nas quais você não possui uma chave primária, possui linhas duplicadas etc. Por exemplo, se você possui uma tabela com duas linhas idênticas e deseja excluir a mais antiga das duas, pode fazer isso usando o comando coluna oid.

Na minha experiência, o recurso geralmente não é usado na maioria dos aplicativos suportados pelo postgres (provavelmente em parte porque eles não são padrão) e seu uso é essencialmente descontinuado :

No PostgreSQL 8.1, default_with_oids está desativado por padrão; nas versões anteriores do PostgreSQL, estava ativado por padrão.

O uso de OIDs em tabelas de usuários é considerado reprovado, portanto, a maioria das instalações deve deixar essa variável desativada. Os aplicativos que requerem OIDs para uma tabela específica devem especificar WITH OIDS ao criar a tabela. Essa variável pode ser ativada para compatibilidade com aplicativos antigos que não seguem esse comportamento.

Frank Farmer
fonte
33
não é garantido que os oids sejam únicos. Dos documentos: "Em um banco de dados grande ou de longa duração, é possível que o contador seja contornado. Portanto, é uma prática recomendada supor que os OIDs sejam únicos, a menos que você tome medidas para garantir que esse seja o caso".
Radiospiel
8
A quebra de linha também implica que você não pode necessariamente excluir a mais antiga das duas linhas com base apenas no seu OID, pois a que possui o OID mais baixo pode ter sido uma quebra de linha.
Carl G
Os OIDs não são globalmente exclusivos, de acordo com os comentários acima, nem em 2011 quando esta resposta foi escrita. Além disso, os OIDs são necessários para objetos do sistema, portanto, o uso de todos os OIDs nos contadores de linhas não ajuda o banco de dados a atribuir OIDs a novas tabelas (para a tabela, não para suas linhas). Além disso, considere se um contador inteiro de 4 bytes simples será realmente suficiente para todas as tabelas do banco de dados.
FuzzyChef
vale ressaltar, na maioria das implementações do phpPgAdmin ao criar uma tabela, a opção é desabilitada como padrão, o que significa que essa opção está obsoleta.
precisa saber é o seguinte
3
se você não sabe para que servem os OIDs, provavelmente não deseja usá-los.
Vdegenne
16

OIDs ainda estão em uso no Postgres com grandes objetos (embora algumas pessoas argumentem que objetos grandes geralmente não são úteis). Eles também são usados ​​extensivamente pelas tabelas do sistema . Eles são usados, por exemplo, pelo TOAST, que armazena mais de 8 KB de BYTEA (etc.) em uma área de armazenamento separada (transparente), que é usada por padrão em todas as tabelas . Seu uso direto associado a tabelas de usuários "normais" é basicamente preterido .

O tipo oid é atualmente implementado como um número inteiro de quatro bytes não assinado. Portanto, não é grande o suficiente para fornecer exclusividade em todo o banco de dados em bancos de dados grandes ou mesmo em tabelas individuais grandes. Portanto, não é recomendável usar a coluna OID de uma tabela criada pelo usuário como chave primária. Os OIDs são melhor utilizados apenas para referências a tabelas do sistema.

Aparentemente, a sequência OID "quebra" se exceder 4B 6 . Então, em essência, é um contador global que pode quebrar. Se isso acontecer, pode ocorrer um abrandamento quando for usado e "pesquisado" por valores exclusivos, etc.

Veja também https://wiki.postgresql.org/wiki/FAQ#What_is_an_OID.3F

rogerdpack
fonte
9

OIDs sendo descontinuados

A equipe principal responsável pelo Postgres está gradualmente eliminando os OIDs.

O Postgres 12 remove o comportamento especial das colunas OID

O uso do OID como uma coluna opcional do sistema em suas tabelas agora foi removido do Postgres 12. Você não pode mais usar:

  • CREATE TABLE … WITH OIDS comando
  • default_with_oids (boolean) configuração de compatibilidade

O tipo de dados OIDpermanece no Postgres 12. Você pode criar explicitamente uma coluna do tipo OID.

Após a migração para o Postgres 12 , qualquer coluna do sistema definida opcionalmente oidnão será mais invisível por padrão. Executar um SELECT *agora incluirá esta coluna. Observe que essa coluna extra de "surpresa" pode quebrar o código SQL gravado de maneira ingenuamente.

Basil Bourque
fonte
5

Para remover todos os OIDs de suas tabelas de banco de dados, você pode usar este script Linux:

Primeiro, faça o login como superusuário do PostgreSQL:

sudo su postgres

Agora execute esse script, alterando YOUR_DATABASE_NAME com o nome do seu banco de dados:

for tbl in `psql -qAt -c "select schemaname || '.' || tablename from pg_tables WHERE schemaname <> 'pg_catalog' AND schemaname <> 'information_schema';" YOUR_DATABASE_NAME` ; do  psql -c "alter table $tbl SET WITHOUT OIDS" YOUR_DATABASE_NAME ; done

Eu usei esse script para remover todos os meus OIDs, pois o Npgsql 3.0 não funciona com isso e não é mais importante para o PostgreSQL.

Rodrigo Boratto
fonte