2011-04-11 137 views
104

我在看一些PostgreSQL表的創建和我偶然發現了這一點:SQL,Postgres OID,它們是什麼以及它們爲什麼有用?

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

我讀到的Postgres提供的文件和我知道,從OOP對象標識符的概念,但我仍然沒有把握,

  • 爲什麼這樣的標識符會在數據庫中有用?
  • 使查詢更短?
  • 什麼時候應該使用它?

回答

115

OID基本上給你一個系統列(與用戶空間列相對)中包含的每行的內置全局唯一標識符。對於那些沒有主鍵,有重複行等的表格,這很方便。例如,如果你有一個有兩個相同行的表,並且你想刪除兩個最老的表,你可以使用oid列。

以我的經驗,該功能在大多數的Postgres支持的應用程序(可能部分是因爲他們是非標準的)一般不使用,並their use is essentially deprecated

在PostgreSQL 8.1 default_with_oids是 默認關閉;在PostgreSQL的早期版本 中,它默認爲開啓。

用戶表中使用OID的是 視爲過時,因此大多數 安裝應該離開這個 變量禁用。當創建 表時, 需要特定表的OID的應用程序 應指定WITH OIDS。此變量可以是 ,以便與不遵循此 行爲的舊 應用程序兼容。

+24

oids不保證是唯一的。從文檔中可以看出:「在大型數據庫或長期數據庫中,計數器可能會環繞,因此,假設OID是唯一的,除非您採取措施確保這種情況是錯誤的做法。」 – radiospiel 2013-07-24 15:43:34

+7

的周圍包裹也意味着你可以不必刪除僅基於OID兩行的年紀大了,作爲一個具有較低OID可能是一個環繞式。 – 2014-04-18 17:30:33

+0

OIDs並非全球唯一,每個評論以上,也不是他們在2011年寫這個答案時。另外,系統對象需要OID,因此在行計數器中使用所有OID並不能幫助數據庫將OID分配給新表(對於表而不是其行)。另外,考慮單個4字節整數計數器是否真的足夠用於數據庫中的每個表。 – FuzzyChef 2015-01-30 21:12:26

9

OID的仍在使用Postgres的withobjects(雖然有些人會認爲大對象不是一般的有用反正)。它們也被system tables廣泛使用。它們被用於例如TOAST,其將大於8KB的BYTEA(等)存儲到單獨的存儲區域(透明地),其默認使用所有表。它們與「正常」用戶表關聯的直接使用基本上是deprecated

oid類型當前實現爲無符號的四字節整數。因此,它不足以在大型數據庫或甚至大型單個表中提供數據庫範圍的唯一性。因此,不鼓勵使用用戶創建的表的OID列作爲主鍵。 OID最好只用於系統表的引用。

顯然,如果OID序列超過4B,則會「包裹」。所以實質上它是一個可以換行的全局計數器。如果它包裝,一些減速可能開始發生,當它被使用和「搜索」唯一值,等等。

又見https://wiki.postgresql.org/wiki/FAQ#What_is_an_OID.3F

2

從數據庫表中刪除所有的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,因爲Npgsql 3.0不適用於這個,它對PostgreSQL不再重要。

相關問題