选择 打开 改范围 完整检索页
受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: 19 / devel
不受支持的版本: 13 / 12 / 11 / 10
当前 PostgreSQL 版本不在支持生命周期内。
您可以参阅当前版本的对应页面,或其他在上面列出的活跃大版本。

37.2. PostgreSQL 类型系统 #

PostgreSQL 数据类型可以分为基础类型、 容器类型、域和伪类型。

37.2.1. 基础类型

基础类型是像 integer 这样的类型,它们在 SQL 语言层之下实现(通常使用像 C 这样的底层语言)。 它们通常对应于通常所说的抽象数据类型。 PostgreSQL 只能通过用户提供的函数来操作这类 类型,并且只能在用户所描述的范围内理解这类类型的行为。 内置基础类型见 Chapter 8

枚举(enum)类型可以看作是基础类型的一个子类。其主要区别在于,它们 只需使用 SQL 命令即可创建,而不需要任何底层编程。 更多信息参见 Section 8.7

37.2.2. 容器类型

PostgreSQL 有三种容器类型, 即包含其他类型多个值的类型。它们是数组、复合类型和范围类型。

数组可以保存多个同一类型的值。每一种基础类型、复合类型、范围类型和 域类型都会自动创建一个对应的数组类型。但不存在数组的数组。就类型系 统而言,多维数组与一维数组并无区别。更多信息参见 Section 8.15

复合类型,也称行类型,会在用户创建表时自动产生。也可以使用 CREATE TYPE 定义一个没有关联表的 独立复合类型。复合类型只是带有关联字段名的一组类型。 复合类型的值是一行或一条记录,其中包含各字段的值。更多信息参见 Section 8.16

范围类型可以保存同一类型的两个值,它们分别是该范围的下界和上界。 范围类型由用户创建,不过也存在少数内置的范围类型。更多信息参见 Section 8.17

37.2.3. 域 #

域基于某一种特定的底层类型,并且在很多场合下都可以与其底层类型互换。 不过,域可以带有约束,把其合法值限制在底层类型所允许值的一个子集内。 域使用 SQL 命令 CREATE DOMAIN 创建。更多信息参见 Section 8.18

37.2.4. 伪类型

有少数几种 伪类型 用于特殊目的。伪类型不能作为表的列 或容器类型的组成部分出现,但它们可以用来声明函数的参数类型和结果类 型。这为在类型系统内部识别特殊类别的函数提供了一种机制。 Table 8.27 列出了现有的伪类型。

37.2.5. 多态类型 #

五种特别值得关注的伪类型是 anyelementanyarrayanynonarrayanyenumanyrange,它们统称为多态类型。使用这些类型声明的函数称为多态函数。多态函数可以操作多种不同的数据类型,具体类型由某次调用时实际传入的数据类型决定。

多态参数和结果相互关联,在解析调用多态函数的查询时,会被解析为某种具体的数据类型。每个声明为 anyelement 的位置(参数或返回值)都可以具有任意具体的实际数据类型,但在同一次调用中,它们必须具有相同的实际类型。每个声明为 anyarray 的位置可以具有任意数组数据类型,但同样必须全部具有相同的类型。类似地,声明为 anyrange 的位置必须全部具有相同的范围类型。此外,如果某些位置声明为 anyarray,另一些位置声明为 anyelement,那么 anyarray 位置上的实际数组类型,其元素类型必须与 anyelement 位置上的类型相同。类似地,如果某些位置声明为 anyrange,另一些位置声明为 anyelementanyarray,那么 anyrange 位置上的实际范围类型,其子类型必须与 anyelement 位置上的类型相同,并与 anyarray 位置上的元素类型相同。anynonarray 的处理与 anyelement 完全相同,但增加了实际类型不能为数组类型的约束。anyenum 的处理与 anyelement 完全相同,但增加了实际类型必须为枚举类型的约束。

因此,当多个参数位置被声明为多态类型时,其总体效果就是只允许某些实际 参数类型组合。例如,声明为 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):两个实际参数都必须是同一种枚 举类型。

可变参数函数(接受可变数量参数的函数,见 Section 37.5.5)可以是多态的:将其最后一个参数声明为 VARIADIC anyarray 即可。就参数匹配和确定实际结果类型而言,这样的函数与写出相应数量的 anynonarray 参数时行为相同。