web-dev-qa-db-ja.com

SQL、Postgres OID、それらは何であり、なぜ有用なのですか?

私はいくつかのPostgreSQLテーブルの作成を見ていますが、これにつまずいたのです。

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

Postgresが提供するドキュメントを読み、OOPからオブジェクト識別子の概念を知っていますが、それでも理解できません。

  • なぜそのような識別子がデータベースで役立つのでしょうか?
  • クエリを短くするには?
  • いつ使用する必要がありますか?
144
fabrizioM

OIDは基本的に、システム列(ユーザー空間列ではなく)に含まれる、すべての行に対して組み込みのグローバルに一意なIDを提供します。これは、主キーを持たないテーブル、重複行があるテーブルなどに便利です。たとえば、2つの同一の行を持つテーブルがあり、2つのうち最も古いものを削除する場合は、 oid列。

私の経験では、この機能はほとんどのpostgres-backedアプリケーションでは使用されておらず(おそらく一部が非標準であるため)、そして それらの使用は本質的に非推奨です

PostgreSQL 8.1では、default_with_oidsはデフォルトでオフになっています。 PostgreSQLの以前のバージョンでは、デフォルトでオンでした。

ユーザーテーブルでのOIDの使用は非推奨と見なされるため、ほとんどのインストールではこの変数を無効のままにしておく必要があります。特定のテーブルにOIDを必要とするアプリケーションは、テーブルの作成時にWITH OIDSを指定する必要があります。この変数は、この動作に従わない古いアプリケーションとの互換性のために有効にできます。

149
Frank Farmer

OIDはまだPostgresで使用されています with large objects (とにかく大規模なオブジェクトは一般的には役に立たないと主張する人もいます)。また、 システムテーブル で広く使用されています。これらは、たとえば TOAST によって使用され、8KBを超えるBYTEA(など)をによってデフォルトで使用される別個のストレージ領域(透過的に)に保存します。すべてのテーブル。 「通常の」ユーザーテーブルに関連付けられた直接使用は、基本的に 非推奨 です。

Oid型は現在、符号なし4バイト整数として実装されています。したがって、大規模なデータベース、または大規模な個々のテーブルでデータベース全体の一意性を提供するのに十分な大きさではありません。そのため、ユーザーが作成したテーブルのOID列を主キーとして使用することはお勧めしません。 OIDは、システムテーブルへの参照にのみ最適に使用されます。

OIDシーケンスは、4Bを超えるとラップします 6 。したがって、本質的には、ラップできるグローバルカウンターです。ラップすると、一意の値などを使用して「検索」したときにスローダウンが発生する可能性があります。

https://wiki.postgresql.org/wiki/FAQ#What_is_an_OID.3F も参照してください

13
rogerdpack

廃止されているOID

Postgresを担当するコアチームは、OIDを段階的に廃止しています。

Postgres 12はOID列の特別な動作を削除します

テーブルのオプションのシステム列としてのOIDの使用は、Postgres 12から削除されました。使用できなくなりました。

  • CREATE TABLE … WITH OIDSコマンド
  • default_with_oids (boolean)互換性設定

データ型OIDはPostgres 12に残ります。タイプOIDの列を明示的に作成できます。

Postgres 12への移行 の後、オプションで定義された システム列oidはデフォルトでは非表示になりません。 SELECT *を実行すると、この列が含まれるようになります。この余分な「サプライズ」列は、単純に記述されたSQLコードを破壊する可能性があることに注意してください。

3
Basil Bourque

データベーステーブルからすべてのOIDを削除するには、次のLinuxスクリプトを使用できます。

最初に、PostgreSQLスーパーユーザーとしてログインします。

Sudo su postgres

YOUR_DATABASE_NAMEをデータベース名に変更して、このスクリプトを実行します。

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

Npgsql 3.0はこれで動作しないため、このスクリプトを使用してすべてのOIDを削除しました。これはPostgreSQLにとって重要ではなくなりました。

2
Rodrigo Boratto