33.2. PostgreSQL 类型系统 #
PostgreSQL 数据类型可以分为基础类型、复合类型、域和伪类型。
33.2.1. 基础类型
基本类型是像 int4 这样在
SQL 语言层级之下实现(通常用 C 之类的低级语言)的类型。它们大体对应于通常所说的抽象数据类型。PostgreSQL 只能通过用户提供的函数操作这类类型,并且只在用户描述它们的程度上理解这类类型的行为。基本类型进一步细分为标量类型和数组类型。对每个标量类型,都会自动创建一个对应的数组类型,它可以保存该标量类型的大小可变的数组。
33.2.2. 复合类型
用户每次创建表时,都会创建复合类型(也称行类型)。还可以定义不关联任何表的“独立”复合类型。复合类型就是带有对应字段名的基类型列表。复合类型的值是由字段值组成的一行或一条记录。用户可以在 SQL 查询中访问各个组成字段。
33.2.3. 域
域基于某一种特定的基础类型,并且在很多场合下都可以与其基础类型互换。不过,域可以带有约束,把其合法值限制在底层基础类型所允许值的一个子集内。
域可以用 SQL 命令
CREATE DOMAIN 创建。它们的创建和使用不在本章讨论之列。
33.2.4. 伪类型
有少数几种“伪类型”用于特殊目的。伪类型不能作为表的列或复合类型的属性出现,但它们可以用来声明函数的参数类型和结果类型。这为在类型系统内部识别特殊类别的函数提供了一种机制。表 8.20列出了现有的伪类型。
33.2.5. 多态类型 #
两种特别值得关注的伪类型是 anyelement 和
anyarray,它们统称为多态类型。使用这些类型声明的函数称为多态函数。多态函数可以操作多种不同的数据类型,具体类型由某次调用时实际传入的数据类型决定。
多态参数和结果相互关联,在解析调用多态函数的查询时,会被解析为某种具体的数据类型。每个声明为 anyelement 的位置(参数或返回值)都可以具有任意具体的实际数据类型,但在同一次调用中,它们必须具有相同的实际类型。每个声明为 anyarray 的位置可以具有任意数组数据类型,但同样必须全部具有相同的类型。此外,如果某些位置声明为
anyarray,另一些位置声明为 anyelement,那么 anyarray 位置上的实际数组类型,其元素类型必须与 anyelement 位置上的类型相同。
因此,当多于一个参数位置声明为多态类型时,净效果是只允许实际参数类型的某些组合。例如,声明为
foo(anyelement, anyelement) 的函数接受任意两个输入值,只要它们具有相同的数据类型。
如果函数的返回值声明为多态类型,那么至少有一个参数位置也必须是多态的,并且实际传入的参数数据类型决定该次调用的实际结果类型。例如,如果尚不存在数组下标机制,可以将实现下标访问的函数定义为 subscript(anyarray, integer)
returns anyelement。这一声明将实际的第一个参数约束为数组类型,并允许解析器根据第一个参数的实际类型推导正确的结果类型。