SQL, Postgres OIDs, cosa sono e perché sono utili?


161

Sto osservando la creazione di una tabella PostgreSQL e mi sono imbattuto in questo:

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

Ho letto la documentazione fornita da Postgres e conosco il concetto di identificatore di oggetto da OOP, ma ancora non capisco,

  • perché tale identificatore sarebbe utile in un database?
  • abbreviare le domande?
  • quando dovrebbe essere usato?

Non riesco a trovare alcun riferimento da citare al momento, ma FYI ho sentito che l'utilizzo di Microsoft Access come front-end per Postgres richiede la presenza della oldcolonna di sistema .
Basil Bourque,

Risposte:


165

Gli OID offrono fondamentalmente un ID univoco integrato per ogni riga, contenuto in una colonna di sistema (al contrario di una colonna dello spazio utente). È utile per le tabelle in cui non si dispone di una chiave primaria, di righe duplicate, ecc. Ad esempio, se si dispone di una tabella con due righe identiche e si desidera eliminare la più vecchia delle due, è possibile farlo utilizzando il colonna oid.

Nella mia esperienza, la funzione è generalmente inutilizzata nella maggior parte delle applicazioni supportate da postgres (probabilmente in parte perché non sono standard) e il loro uso è sostanzialmente deprecato :

In PostgreSQL 8.1 default_with_oids è disattivato di default; nelle versioni precedenti di PostgreSQL, era attivo per impostazione predefinita.

L'uso di OID nelle tabelle utente è considerato obsoleto, quindi la maggior parte delle installazioni dovrebbe lasciare questa variabile disabilitata. Le applicazioni che richiedono OID per una determinata tabella devono specificare WITH OIDS durante la creazione della tabella. Questa variabile può essere abilitata per la compatibilità con le vecchie applicazioni che non seguono questo comportamento.


33
Oids non è garantito per essere unico. Dai documenti: "In un database di grandi dimensioni o di lunga durata, è possibile che il contatore si avvolga. Pertanto, è una buona pratica presumere che gli OID siano unici, a meno che non si adottino misure per garantire che ciò avvenga."
radiospiel,

8
L'avvolgimento implica anche che non è possibile eliminare necessariamente la più vecchia di due righe in base solo al loro OID, poiché quella con l'OID inferiore potrebbe essere stata un avvolgimento.
Carl G,

Gli OID non sono univoci a livello globale, per commenti sopra, né lo erano nel 2011 quando questa risposta è stata scritta. Inoltre, gli OID sono necessari per gli oggetti di sistema, quindi l'utilizzo di tutti gli OID sui contatori di righe non aiuta il database ad assegnare OID a nuove tabelle (per la tabella, non per le sue righe). Inoltre, considera se un contatore intero a 4 byte singolo sarà davvero sufficiente per ogni tabella nel tuo database.
FuzzyChef

vale la pena ricordare, nella maggior parte dell'implementazione di phpPgAdmin durante la creazione di una tabella, l'opzione è disabilitata come predefinita, il che significa che questa opzione è obsoleta.
vdegenne,

3
se non sai a cosa servono gli OID, probabilmente non li vuoi usare.
vdegenne,

16

Gli OID sono ancora in uso per Postgres con oggetti di grandi dimensioni (anche se alcune persone sostengono che gli oggetti di grandi dimensioni non sono comunque generalmente utili). Sono inoltre ampiamente utilizzati dalle tabelle di sistema . Sono utilizzati ad esempio da TOAST che memorizza BYTEA di dimensioni superiori a 8 KB (ecc.) In un'area di archiviazione separata (in modo trasparente) che viene utilizzata per impostazione predefinita da tutte le tabelle . Il loro uso diretto associato a tabelle "normali" dell'utente è sostanzialmente deprecato .

Il tipo oid è attualmente implementato come numero intero a quattro byte senza segno. Pertanto, non è abbastanza grande per fornire unicità a livello di database in database di grandi dimensioni o anche in singole tabelle di grandi dimensioni. Pertanto, l'utilizzo della colonna OID di una tabella creata dall'utente come chiave primaria è sconsigliato. Gli OID sono utilizzati al meglio solo per riferimenti a tabelle di sistema.

Apparentemente la sequenza OID "fa" si avvolge se supera 4B 6 . Quindi, in sostanza, è un contatore globale che può avvolgere. In caso contrario, potrebbe verificarsi un rallentamento quando viene utilizzato e "cercato" per valori univoci, ecc.

Vedi anche https://wiki.postgresql.org/wiki/FAQ#What_is_an_OID.3F


9

OID in fase di eliminazione

Il core team responsabile di Postgres sta gradualmente eliminando gli OID.

Postgres 12 rimuove il comportamento speciale delle colonne OID

L'uso di OID come colonna di sistema opzionale sui tuoi tavoli è ora rimosso da Postgres 12. Non puoi più usare:

  • CREATE TABLE … WITH OIDS comando
  • default_with_oids (boolean) impostazione di compatibilità

Il tipo di dati OIDrimane in Postgres 12. Puoi creare esplicitamente una colonna del tipo OID.

Dopo la migrazione a Postgres 12 , qualsiasi colonna di sistema definita facoltativamente oidnon sarà più invisibile per impostazione predefinita. L'esecuzione di un SELECT *includerà ora questa colonna. Si noti che questa colonna "sorpresa" in più potrebbe rompere il codice SQL scritto ingenuamente.


5

Per rimuovere tutti gli OID dalle tabelle del database, è possibile utilizzare questo script Linux:

Innanzitutto, accedi come superutente PostgreSQL:

sudo su postgres

Ora esegui questo script, cambiando YOUR_DATABASE_NAME con il nome del tuo database:

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

Ho usato questo script per rimuovere tutti i miei OID, poiché Npgsql 3.0 non funziona con questo e non è più importante per PostgreSQL.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.