SQL, Postgres-OIDs, Was sind sie und warum sind sie nützlich?

161

Ich schaue mir eine PostgreSQL-Tabellenerstellung an und bin darauf gestoßen:

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

Ich habe die Dokumentation von postgres gelesen und kenne das Konzept der Objektkennung von OOP, verstehe es aber immer noch nicht.

  • Warum wäre eine solche Kennung in einer Datenbank nützlich?
  • Abfragen kürzer machen?
  • Wann sollte es verwendet werden?
fabrizioM
quelle
Ich kann derzeit keine zu zitierenden Verweise finden, aber zu Ihrer Information, ich habe gehört, dass die Verwendung von Microsoft Access als Front-End für Postgres das Vorhandensein der oldSystemspalte erfordert .
Basil Bourque

Antworten:

165

OIDs geben Ihnen im Grunde eine integrierte, global eindeutige ID für jede Zeile, die in einer Systemspalte enthalten ist (im Gegensatz zu einer User-Space-Spalte). Dies ist praktisch für Tabellen, in denen Sie keinen Primärschlüssel, doppelte Zeilen usw. haben. Wenn Sie beispielsweise eine Tabelle mit zwei identischen Zeilen haben und die älteste der beiden löschen möchten, können Sie dies mit dem tun oid Spalte.

Nach meiner Erfahrung wird die Funktion in den meisten von Postgres unterstützten Anwendungen im Allgemeinen nicht verwendet (wahrscheinlich teilweise, weil sie nicht dem Standard entsprechen), und ihre Verwendung ist im Wesentlichen veraltet :

In PostgreSQL 8.1 ist default_with_oids standardmäßig deaktiviert. In früheren Versionen von PostgreSQL war es standardmäßig aktiviert.

Die Verwendung von OIDs in Benutzertabellen wird als veraltet angesehen, daher sollten die meisten Installationen diese Variable deaktiviert lassen. Anwendungen, die OIDs für eine bestimmte Tabelle benötigen, sollten beim Erstellen der Tabelle WITH OIDS angeben. Diese Variable kann aus Gründen der Kompatibilität mit alten Anwendungen aktiviert werden, die diesem Verhalten nicht folgen.

Frank Farmer
quelle
33
Es ist nicht garantiert, dass Oids einzigartig sind. Aus den Dokumenten: "In einer großen oder langlebigen Datenbank kann der Zähler umlaufen. Daher ist es eine schlechte Praxis anzunehmen, dass OIDs eindeutig sind, es sei denn, Sie ergreifen Maßnahmen, um sicherzustellen, dass dies der Fall ist."
Radiospiel
8
Das Umschließen impliziert auch, dass Sie die ältere von zwei Zeilen nicht unbedingt nur aufgrund ihrer OID löschen konnten, da die mit der niedrigeren OID möglicherweise ein Umlaufen war.
Carl G
OIDs sind gemäß den obigen Kommentaren weder global eindeutig noch 2011, als diese Antwort geschrieben wurde. Außerdem werden OIDs für Systemobjekte benötigt, sodass die Verwendung aller OIDs auf Zeilenzählern der Datenbank nicht hilft, OIDs neuen Tabellen zuzuweisen (für die Tabelle, nicht für ihre Zeilen). Überlegen Sie auch, ob ein einzelner 4-Byte-Ganzzahlzähler wirklich für jede Tabelle in Ihrer Datenbank ausreicht.
FuzzyChef
Es ist erwähnenswert, dass in den meisten Implementierungen von phpPgAdmin beim Erstellen einer Tabelle die Option als standardmäßig deaktiviert aktiviert ist, was tatsächlich bedeutet, dass diese Option veraltet ist.
Vdegenne
3
Wenn Sie nicht wissen, wofür OIDs verwendet werden, möchten Sie sie wahrscheinlich nicht verwenden.
Vdegenne
16

OIDs werden immer noch für Postgres mit großen Objekten verwendet (obwohl einige Leute argumentieren würden, dass große Objekte im Allgemeinen sowieso nicht nützlich sind). Sie werden auch häufig von Systemtabellen verwendet . Sie werden beispielsweise von TOAST verwendet, das BYTEAs (usw.) mit mehr als 8 KB in einem separaten Speicherbereich (transparent) speichert, der standardmäßig von allen Tabellen verwendet wird . Ihre direkte Verwendung in Verbindung mit "normalen" Benutzertabellen ist grundsätzlich veraltet .

Der OID-Typ ist derzeit als vorzeichenlose 4-Byte-Ganzzahl implementiert. Daher ist es nicht groß genug, um eine datenbankweite Eindeutigkeit in großen Datenbanken oder sogar in großen Einzeltabellen bereitzustellen. Es wird daher davon abgeraten, die OID-Spalte einer vom Benutzer erstellten Tabelle als Primärschlüssel zu verwenden. OIDs werden am besten nur für Verweise auf Systemtabellen verwendet.

Anscheinend wird die OID-Sequenz "umbrochen", wenn sie 4B 6 überschreitet . Im Wesentlichen handelt es sich also um einen globalen Zähler, der umbrochen werden kann. Wenn es umbrochen wird, kann es zu einer gewissen Verlangsamung kommen, wenn es verwendet und nach eindeutigen Werten usw. "durchsucht" wird.

Siehe auch https://wiki.postgresql.org/wiki/FAQ#What_is_an_OID.3F

Rogerdpack
quelle
9

OIDs werden auslaufen

Das für Postgres zuständige Kernteam setzt OIDs schrittweise aus.

Postgres 12 entfernt das spezielle Verhalten von OID-Spalten

Die Verwendung von OID als optionale Systemspalte in Ihren Tabellen wurde jetzt aus Postgres 12 entfernt. Sie können nicht mehr Folgendes verwenden:

  • CREATE TABLE … WITH OIDS Befehl
  • default_with_oids (boolean) Kompatibilitätseinstellung

Der Datentyp OIDbleibt in Postgres 12. Sie können explizit eine Spalte des Typs erstellenOID .

Nach der Migration zu Postgres 12 ist eine optional definierte Systemspalte oid standardmäßig nicht mehr unsichtbar. Das Durchführen eines SELECT *Testaments enthält jetzt diese Spalte. Beachten Sie, dass diese zusätzliche "Überraschungs" -Spalte möglicherweise naiv geschriebenen SQL-Code beschädigt.

Basil Bourque
quelle
5

Um alle OIDs aus Ihren Datenbanktabellen zu entfernen, können Sie dieses Linux-Skript verwenden:

Melden Sie sich zunächst als PostgreSQL-Superuser an:

sudo su postgres

Führen Sie nun dieses Skript aus und ändern Sie YOUR_DATABASE_NAME mit Ihrem Datenbanknamen:

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

Ich habe dieses Skript verwendet, um alle meine OIDs zu entfernen, da Npgsql 3.0 damit nicht funktioniert und es für PostgreSQL nicht mehr wichtig ist.

Rodrigo Boratto
quelle