2025年9月25日: PostgreSQL 18 釋出!
支援的版本:當前 (18) / 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 內部用作各種系統表的primary key。型別 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 識別符號。例如,一個名為 Foo(首字母 F 大寫)且接受兩個整數引數的函式的 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.76

另一個 regclass 的實際應用示例是查詢 information_schema 檢視中列出的表的 OID,這些檢視不直接提供此類 OID。例如,您可能希望呼叫 pg_relation_size() 函式,該函式需要表的 OID。考慮到上述規則,正確的做法是:

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 值嚴格單調遞增,並且在資料庫叢集的生命週期內不會被重用。有關更多詳細資訊,請參閱 第 67.1 節

系統使用的第三種識別符號型別是 cid,即命令識別符號。這是系統列 cmincmax 的資料型別。命令識別符號也是 32 位數量。

系統使用的最後一種識別符號型別是 tid,即元組識別符號(行識別符號)。這是系統列 ctid 的資料型別。元組 ID 是一個對(塊編號,塊內元組索引),它標識了行在表內的物理位置。

(系統列在 第 5.6 節 中有更詳細的解釋。)

提交更正

如果您在文件中看到任何不正確、與您在使用特定功能時的經驗不符或需要進一步澄清的內容,請使用此表單報告文件問題。