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

36.2. PostgreSQL 型別系統 #

PostgreSQL 資料型別可分為基本型別、容器型別、域和偽型別。

36.2.1. 基本型別 #

基本型別是指那些在語言(通常是像 C 這樣的底層語言)的底層實現的型別,例如 integerSQL它們通常對應於常被稱為抽象資料型別的型別。PostgreSQL 只能透過使用者提供的函式來操作這些型別,並且只理解使用者描述的這些型別的行為。內建的基本型別在 第 8 章 中進行了描述。

列舉(enum)型別可以被視為基本型別的一個子類。主要區別在於它們可以使用簡單的SQL命令建立,而無需任何底層程式設計。有關更多資訊,請參閱 8.7 節

36.2.2. 容器型別 #

PostgreSQL 有三種“容器”型別,它們是包含多個其他型別值的型別。這些是陣列、複合型別和範圍型別。

陣列可以包含所有相同型別的多個值。對於每種基本型別、複合型別、範圍型別和域型別,都會自動建立一個數組型別。但是沒有陣列的陣列。就型別系統而言,多維陣列與一維陣列相同。有關更多資訊,請參閱 8.15 節

複合型別,或行型別,是在使用者建立表時建立的。也可以使用 CREATE TYPE 來定義一個沒有關聯表的“獨立”複合型別。複合型別只是一個包含關聯欄位名的型別列表。複合型別的值是欄位值的行或記錄。有關更多資訊,請參閱 8.16 節

範圍型別可以包含同一型別的兩個值,它們是範圍的下限和上限。範圍型別是使用者建立的,儘管存在一些內建的範圍型別。有關更多資訊,請參閱 8.17 節

36.2.3. 域 #

域基於特定的底層型別,並且在許多用途上與其底層型別可互換。但是,域可以具有限制其有效值範圍的約束,使其成為底層型別允許範圍的子集。域使用SQL命令 CREATE DOMAIN 建立。有關更多資訊,請參閱 8.18 節

36.2.4. 偽型別 #

有一些用於特殊目的的“偽型別”。偽型別不能作為表列或容器型別的元件出現,但它們可以用於宣告函式的引數和返回型別。這在型別系統中提供了一種機制來標識函式的特殊類別。表 8.27 列出了現有的偽型別。

36.2.5. 多型型別 #

一些特別有趣的偽型別是多型型別,它們用於宣告多型函式。這一強大功能允許單個函式定義操作多種不同的資料型別,其中具體資料型別在特定呼叫中透過傳遞給它的實際資料型別來確定。多型型別顯示在 表 36.1 中。一些使用示例出現在 36.5.11 節

表 36.1. 多型型別

名稱 描述
anyelement 簡單 表示函式接受任何資料型別
anyarray 簡單 表示函式接受任何陣列資料型別
anynonarray 簡單 表示函式接受任何非陣列資料型別
anyenum 簡單 表示函式接受任何列舉資料型別(參見 8.7 節
anyrange 簡單 表示函式接受任何範圍資料型別(參見 8.17 節
anymultirange 簡單 表示函式接受任何多範圍資料型別(參見 8.17 節
anycompatible 通用 表示函式接受任何資料型別,並自動將多個引數提升到通用資料型別
anycompatiblearray 通用 表示函式接受任何陣列資料型別,並自動將多個引數提升到通用資料型別
anycompatiblenonarray 通用 表示函式接受任何非陣列資料型別,並自動將多個引數提升到通用資料型別
anycompatiblerange 通用 表示函式接受任何範圍資料型別,並自動將多個引數提升到通用資料型別
anycompatiblemultirange 通用 表示函式接受任何多範圍資料型別,並自動將多個引數提升到通用資料型別

多型引數和結果相互關聯,並在解析呼叫多型函式的查詢時解析為特定資料型別。當存在多個多型引數時,輸入值的實際資料型別必須匹配,如下所述。如果函式的返回型別是多型的,或者它具有多型型別的輸出引數,則這些結果的型別將根據下面描述的多型輸入值型別進行推斷。

對於“簡單”多型型別族,匹配和推斷規則如下:

宣告為 anyelement 的每個位置(引數或返回值)都可以具有任何特定的實際資料型別,但在任何給定的呼叫中,它們都必須是相同的實際型別。宣告為 anyarray 的每個位置都可以是任何陣列資料型別,但同樣它們必須是相同的型別。同樣,宣告為 anyrange 的位置必須是相同的範圍型別。 anymultirange 也是如此。

此外,如果存在宣告為 anyarray 的位置而其他位置宣告為 anyelement,則 anyarray 位置中的實際陣列型別必須是其元素型別與 anyelement 位置中出現的型別相同的陣列。anynonarray 的處理方式與 anyelement 完全相同,但增加了額外的約束,即實際型別不能是陣列型別。anyenum 的處理方式與 anyelement 完全相同,但增加了額外的約束,即實際型別必須是列舉型別。

同樣,如果存在宣告為 anyrange 的位置而其他位置宣告為 anyelementanyarray,則 anyrange 位置中的實際範圍型別必須是其子型別與 anyelement 位置中出現的型別相同,並且與 anyarray 位置中的元素型別相同的範圍。anymultirange 的宣告如果存在,其實際多範圍型別必須包含與宣告為 anyrange 的引數匹配的範圍,以及與宣告為 anyelementanyarray 的引數匹配的基本元素。

因此,當一個函式聲明瞭多個多型型別引數時,其淨效應是隻允許某些實際引數型別的組合。例如,宣告為 equal(anyelement, anyelement) 的函式將接受任意兩個輸入值,只要它們是相同資料型別即可。

當函式的返回型別宣告為多型型別時,必須至少有一個引數位置也是多型的,並且為多型引數提供的實際資料型別決定了該呼叫的實際結果型別。例如,如果還沒有陣列下標機制,可以定義一個實現下標的函式,如 subscript(anyarray, integer) returns anyelement。此宣告將第一個實際引數約束為陣列型別,並允許解析器從第一個實際引數的型別推斷出正確的結果型別。另一個例子是,宣告為 f(anyarray) returns anyenum 的函式只能接受列舉型別的陣列。

在大多數情況下,解析器可以根據同一族中不同多型型別的引數推斷出多型結果型別的實際資料型別;例如,可以從 anyelement 推斷出 anyarray,反之亦然。一個例外是, anyrange 的多型結果需要一個 anyrange 型別的引數;它無法從 anyarrayanyelement 引數推斷出來。這是因為可能存在具有相同子型別的多個範圍型別。

請注意, anynonarrayanyenum 不代表單獨的型別變數;它們與 anyelement 是相同的型別,只是增加了額外的約束。例如,將函式宣告為 f(anyelement, anyenum) 等同於將其宣告為 f(anyenum, anyenum):兩個實際引數都必須是相同的列舉型別。

對於“通用”多型型別族,匹配和推斷規則與“簡單”族大致相同,但有一個主要區別:引數的實際型別不必完全相同,只要它們可以隱式轉換為一個通用的單一型別即可。通用型別的選擇遵循與 UNION 和相關構造相同的規則(參見 10.5 節)。通用型別的選擇考慮了 anycompatibleanycompatiblenonarray 輸入的實際型別, anycompatiblearray 輸入的陣列元素型別, anycompatiblerange 輸入的範圍子型別,以及 anycompatiblemultirange 輸入的多範圍子型別。如果存在 anycompatiblenonarray,則通用型別必須是非陣列型別。一旦確定了通用型別, anycompatibleanycompatiblenonarray 位置的引數將自動轉換為該型別,而 anycompatiblearray 位置的引數將自動轉換為該型別的陣列型別。

由於無法僅透過子型別選擇範圍型別,因此使用 anycompatiblerange 和/或 anycompatiblemultirange 要求宣告具有該型別的引數必須具有相同的實際範圍和/或多範圍型別,並且該型別的子型別與選定的通用型別一致,從而不需要轉換範圍值。與 anyrangeanymultirange 一樣,將 anycompatiblerangeanycompatiblemultirange 用作函式結果型別要求存在 anycompatiblerangeanycompatiblemultirange 引數。

請注意,沒有 anycompatibleenum 型別。這種型別用處不大,因為通常沒有到列舉型別的隱式轉換,這意味著無法為不相似的列舉輸入解析通用型別。

簡單”和“通用”多型族代表兩個獨立型別的變數集。例如,考慮

CREATE FUNCTION myfunc(a anyelement, b anyelement,
                       c anycompatible, d anycompatible)
RETURNS anycompatible AS ...

在此函式的一個實際呼叫中,前兩個輸入必須具有完全相同的型別。最後兩個輸入必須可提升到一個通用型別,但該型別可能與前兩個輸入的型別無關。結果將具有後兩個輸入的通用型別。

可變引數函式(接受可變數量引數的函式,如 36.5.6 節)可以是多型的:這是透過將其最後一個引數宣告為 VARIADIC anyarrayVARIADIC anycompatiblearray 來實現的。為了進行引數匹配和確定實際結果型別,此類函式與宣告適當數量的 anynonarrayanycompatiblenonarray 引數的行為相同。

提交更正

如果您在文件中發現任何不正確、與您對特定功能的體驗不符或需要進一步說明的內容,請使用 此表單 報告文件問題。