SQL, OID Postgres, que sont-ils et pourquoi sont-ils utiles?

161

Je regarde une création de table PostgreSQL et je suis tombé sur ceci:

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

J'ai lu la documentation fournie par postgres et je connais le concept d'identifiant d'objet de la POO mais je ne saisis toujours pas,

  • pourquoi un tel identifiant serait utile dans une base de données?
  • raccourcir les requêtes?
  • quand doit-il être utilisé?
fabrizioM
la source
Je ne trouve aucune référence à citer pour le moment, mais pour info, j'ai entendu dire que l'utilisation de Microsoft Access comme frontal de Postgres nécessite la présence de la oldcolonne système .
Basil Bourque

Réponses:

165

Les OID vous donnent essentiellement un identifiant intégré et globalement unique pour chaque ligne, contenu dans une colonne système (par opposition à une colonne d'espace utilisateur). C'est pratique pour les tables où vous n'avez pas de clé primaire, avez des lignes en double, etc. Par exemple, si vous avez une table avec deux lignes identiques et que vous souhaitez supprimer la plus ancienne des deux, vous pouvez le faire en utilisant le colonne oid.

D'après mon expérience, la fonctionnalité est généralement inutilisée dans la plupart des applications postgres (probablement en partie parce qu'elles ne sont pas standard), et leur utilisation est essentiellement obsolète :

Dans PostgreSQL 8.1, default_with_oids est désactivé par défaut; dans les versions précédentes de PostgreSQL, il était activé par défaut.

L'utilisation d'OID dans les tables utilisateur est considérée comme obsolète, donc la plupart des installations doivent laisser cette variable désactivée. Les applications qui nécessitent des OID pour une table particulière doivent spécifier WITH OIDS lors de la création de la table. Cette variable peut être activée pour la compatibilité avec les anciennes applications qui ne suivent pas ce comportement.

Frank Farmer
la source
33
les oids ne sont pas garantis comme étant uniques. Extrait de la documentation: "Dans une base de données volumineuse ou de longue durée, il est possible que le compteur s'enroule. Par conséquent, il est déconseillé de supposer que les OID sont uniques, sauf si vous prenez des mesures pour vous assurer que c'est le cas."
radiospiel
8
Le bouclage implique également que vous ne pouvez pas nécessairement supprimer la plus ancienne des deux lignes uniquement en fonction de leur OID, car celle avec l'OID le plus bas peut avoir été un bouclage.
Carl G
Les OID ne sont pas uniques au monde, selon les commentaires ci-dessus, ni ne l'étaient en 2011 lorsque cette réponse a été rédigée. De plus, les OID sont nécessaires pour les objets système, donc l'utilisation de tous les OID sur les compteurs de lignes n'aide pas la base de données à attribuer des OID aux nouvelles tables (pour la table, pas ses lignes). Vérifiez également si un seul compteur entier de 4 octets sera vraiment suffisant pour chaque table de votre base de données.
FuzzyChef
il convient de mentionner que dans la plupart des implémentations de phpPgAdmin lors de la création d'une table, l'option est désactivée par défaut, ce qui signifie en fait que cette option est obsolète.
vdegenne
3
si vous ne savez pas à quoi servent les OID, vous ne voudrez probablement pas les utiliser.
vdegenne le
16

Les OID sont toujours utilisés pour Postgres avec des objets volumineux (bien que certaines personnes soutiennent que les objets volumineux ne sont généralement pas utiles de toute façon). Ils sont également largement utilisés par les tables système . Ils sont utilisés par exemple par TOAST qui stocke plus de 8 Ko de BYTEA (etc.) dans une zone de stockage séparée (de manière transparente) qui est utilisée par défaut par toutes les tables . Leur utilisation directe associée aux tables utilisateur "normales" est fondamentalement obsolète .

Le type oid est actuellement implémenté sous la forme d'un entier non signé de quatre octets. Par conséquent, il n'est pas assez grand pour fournir une unicité à l'échelle de la base de données dans les grandes bases de données, ou même dans les grandes tables individuelles. Par conséquent, l'utilisation de la colonne OID d'une table créée par l'utilisateur comme clé primaire est déconseillée. Les OID sont mieux utilisés uniquement pour les références aux tables système.

Apparemment, la séquence OID «fait» un bouclage si elle dépasse 4B 6 . Donc, en substance, c'est un compteur mondial qui peut envelopper. S'il s'enroule, un ralentissement peut commencer à se produire lorsqu'il est utilisé et "recherché" des valeurs uniques, etc.

Voir aussi https://wiki.postgresql.org/wiki/FAQ#What_is_an_OID.3F

rogerdpack
la source
9

OID en cours d'élimination

L'équipe principale responsable de Postgres supprime progressivement les OID.

Postgres 12 supprime le comportement spécial des colonnes OID

L'utilisation d'OID comme colonne système facultative sur vos tables est désormais supprimée de Postgres 12. Vous ne pouvez plus utiliser:

  • CREATE TABLE … WITH OIDS commander
  • default_with_oids (boolean) paramètre de compatibilité

Le type de données OIDreste dans Postgres 12. Vous pouvez créer explicitement une colonne du type OID.

Après la migration vers Postgres 12 , toute colonne système éventuellement définie neoid sera plus invisible par défaut. L'exécution d'un SELECT *inclut désormais cette colonne. Notez que cette colonne «surprise» supplémentaire peut casser du code SQL écrit naïvement.

Basil Bourque
la source
5

Pour supprimer tous les OID de vos tables de base de données, vous pouvez utiliser ce script Linux:

Tout d'abord, connectez-vous en tant que superutilisateur PostgreSQL:

sudo su postgres

Maintenant, exécutez ce script, en changeant YOUR_DATABASE_NAME avec votre nom de base de données:

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

J'ai utilisé ce script pour supprimer tous mes OID, car Npgsql 3.0 ne fonctionne pas avec cela, et ce n'est plus important pour PostgreSQL.

Rodrigo Boratto
la source