支援的版本:目前 (17) / 16 / 15 / 14 / 13
開發版本:devel
不支援的版本:12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1 / 8.0 / 7.4 / 7.3

8.19. 物件識別碼類型 #

物件識別碼 (OID) 在 PostgreSQL 內部被用作各種系統資料表的主鍵。類型 oid 代表物件識別碼。還有幾種類型是 oid 的別名,每種類型都命名為 regsomething表 8.26 顯示了概述。

oid 類型目前實作為一個無符號四位元組整數。因此,它不夠大,無法在大型資料庫中,甚至在大型的個別資料表中提供資料庫範圍內的唯一性。

oid 類型本身除了比較之外,幾乎沒有任何操作。但是,它可以轉換為整數,然後使用標準的整數運算符進行操作。(如果這樣做,請注意可能的符號與無符號混淆。)

OID 別名類型除了特殊的輸入和輸出例程之外,沒有自己的操作。這些例程能夠接受和顯示系統物件的符號名稱,而不是 oid 類型會使用的原始數值。別名類型允許簡化物件的 OID 值查詢。例如,要檢查與表 mytable 相關的 pg_attribute 列,可以寫入

SELECT * FROM pg_attribute WHERE attrelid = 'mytable'::regclass;

而不是

SELECT * FROM pg_attribute
  WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'mytable');

雖然這本身看起來還不錯,但它仍然過於簡化。如果不同的結構描述中有多個名為 mytable 的資料表,則需要一個更複雜的子查詢來選擇正確的 OID。regclass 輸入轉換器根據結構描述路徑設定處理資料表查找,因此它會自動執行正確的事情。同樣,將資料表的 OID 轉換為 regclass 對於符號顯示數值 OID 來說非常方便。

表 8.26. 物件識別碼類型

名稱 參考 描述 數值範例
oid 任何 數值物件識別碼 564182
regclass pg_class 關聯名稱 pg_type
regcollation pg_collation 定序名稱 "POSIX"
regconfig pg_ts_config 文字搜尋配置 english
regdictionary pg_ts_dict 文字搜尋字典 simple
regnamespace pg_namespace 命名空間名稱 pg_catalog
regoper pg_operator 運算子名稱 +
regoperator pg_operator 具有引數類型的運算子 *(integer,​integer)-(NONE,​integer)
regproc pg_proc 函數名稱 sum
regprocedure pg_proc 具有引數類型的函數 sum(int4)
regrole pg_authid 角色名稱 smithee
regtype pg_type 資料類型名稱 integer

所有按命名空間分組的物件的 OID 別名類型都接受以結構描述限定的名稱,如果未經限定,則在目前的搜尋路徑中找不到物件,則會在輸出時顯示以結構描述限定的名稱。例如,myschema.mytableregclass 可接受的輸入(如果存在這樣的資料表)。該值可能會輸出為 myschema.mytable,或僅輸出為 mytable,具體取決於目前的搜尋路徑。regprocregoper 別名類型只會接受唯一的輸入名稱(未超載),因此它們的用途有限;對於大多數用途,regprocedureregoperator 更合適。對於 regoperator,一元運算子通過為未使用的運算元寫入 NONE 來識別。

這些類型的輸入函數允許在語法單元之間使用空白字元,並且會將大寫字母轉換為小寫字母,但雙引號內除外;這樣做的目的是使語法規則與 SQL 中物件名稱的書寫方式相似。 相反地,輸出函數在需要時會使用雙引號,以使輸出成為有效的 SQL 識別符號。 例如,帶有大寫 F 的名為 Foo 的函數的 OID,該函數帶有兩個整數引數,可以輸入為 ' "Foo" ( int, integer ) '::regprocedure。 輸出將顯示為 "Foo"(integer,integer)。 函數名稱和引數類型名稱也可以使用模式限定。

許多內建的 PostgreSQL 函數接受表格的 OID,或其他種類的資料庫物件,為了方便起見,宣告為接受 regclass(或適當的 OID 別名類型)。 這表示您不必手動查詢物件的 OID,而只需將其名稱輸入為字串文字。 例如,nextval(regclass) 函數接受序列關係的 OID,因此您可以這樣呼叫它

nextval('foo')              operates on sequence foo
nextval('FOO')              same as above
nextval('"Foo"')            operates on sequence Foo
nextval('myschema.foo')     operates on myschema.foo
nextval('"myschema".foo')   same as above
nextval('foo')              searches search path for foo

注意

當您將此類函數的引數寫為未修飾的文字字串時,它將變成 regclass(或適當類型)的常數。 由於這實際上只是一個 OID,因此即使後來重新命名、重新分配模式等,它也會追蹤最初識別的物件。 對於欄位預設值和視窗中的物件參考,這種早期繫結行為通常是理想的。 但有時您可能想要延遲繫結,即在執行時期解析物件參考。 若要獲得延遲繫結行為,請強制將常數儲存為 text 常數,而不是 regclass

nextval('foo'::text)      foo is looked up at runtime

to_regclass() 函數及其同系列函數也可以用於執行時期查詢。 請參閱表 9.74

regclass 的另一個實際使用範例是查詢列在 information_schema 視窗中的表格的 OID,這些視窗不直接提供此類 OID。 例如,人們可能希望呼叫需要表格 OID 的 pg_relation_size() 函數。 考慮到上述規則,正確的方法是

SELECT table_schema, table_name,
       pg_relation_size((quote_ident(table_schema) || '.' ||
                         quote_ident(table_name))::regclass)
FROM information_schema.tables
WHERE ...

quote_ident() 函數將在需要時處理識別符號的雙引號問題。 看起來更容易的

SELECT pg_relation_size(table_name)
FROM information_schema.tables
WHERE ...

不建議使用,因為對於您搜尋路徑之外的表格或需要引號的名稱,它將會失敗。

大多數 OID 別名類型的另一個屬性是建立依賴關係。 如果這些類型之一的常數出現在儲存的表示式中(例如欄位預設表示式或視窗),它會建立對參考物件的依賴關係。 例如,如果欄位具有預設表示式 nextval('my_seq'::regclass),則 PostgreSQL 瞭解預設表示式取決於序列 my_seq,因此系統不會允許在未先移除預設表示式的情況下捨棄序列。nextval('my_seq'::text) 的替代方案不會建立依賴關係。(regrole 是此屬性的例外。 不允許在儲存的表示式中使用此類型的常數。)

系統使用的另一個識別符號類型是 xid,或交易(縮寫為 xact)識別符號。 這是系統欄位 xminxmax 的資料類型。 交易識別符號是 32 位元的量。 在某些情況下,會使用 64 位元的變體 xid8。 與 xid 值不同,xid8 值會嚴格單調遞增,並且無法在資料庫叢集的生命週期內重複使用。 有關更多詳細資訊,請參閱第 66.1 節

系統使用的第三個識別符號類型是 cid,或命令識別符號。 這是系統欄位 cmincmax 的資料類型。 命令識別符號也是 32 位元的量。

系統使用的最後一個識別符號類型是 tid,或元組識別符號(列識別符號)。 這是系統欄位 ctid 的資料類型。 元組 ID 是一對(區塊號碼,區塊內的元組索引),用於識別列在其表格內的實際位置。

(系統欄位在第 5.6 節中進一步說明。)

提交更正

如果您在文件中發現任何不正確、與您使用特定功能的經驗不符或需要進一步澄清的地方,請使用此表格回報文件問題。