SQL、Postgres OID、それらは何で、なぜ便利なのですか?


161

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

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

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

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

現時点で引用する参考文献は見つかりませんが、Microsoft AccessをPostgresのフロントエンドとして使用するには、oldシステムカラムが必要であると聞きました。
バジルブルク

回答:


165

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

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

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

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


33
OIDが一意であるとは限りません。ドキュメントから:「大規模または長期のデータベースでは、カウンターが循環する可能性があります。そのため、これが当てはまることを確認する手順を実行しない限り、OIDが一意であると想定することはお勧めできません。」
radiospiel 2013

8
ラップアラウンドはまた、OIDのみに基づいて古い2つの行を削除できるとは限らないことを意味します。これは、低いOIDを持つ行がラップアラウンドであった可能性があるためです。
カールG 14

上記のコメントによると、OIDはグローバルに一意ではありません。また、この回答が書かれた2011年にはありませんでした。また、システムオブジェクトにはOIDが必要であるため、行カウンターですべてのOIDを使い果たしても、データベースが新しいテーブル(行ではなくテーブル)にOIDを割り当てるのに役立ちません。また、データベース内のすべてのテーブルに対して、単一の4バイト整数カウンターで十分かどうかも検討してください。
FuzzyChef 2015年

言及する価値があります。テーブルを作成するときのphpPgAdminのほとんどの実装では、このオプションはデフォルトで無効になっています。つまり、このオプションは廃止されています。
vdegenne 2015

3
使用するOIDがわからない場合は、おそらくそれらを使用したくないでしょう。
vdegenne

16

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

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

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

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


9

段階的に廃止される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コードを壊す可能性があることに注意してください。


5

データベーステーブルからすべての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

私はこのスクリプトを使用してすべてのOIDを削除しました。Npgsql3.0はこれで動作せず、PostgreSQLにとってもはや重要ではないためです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.