💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# 35.2\. PostgreSQL类型系统 PostgreSQL数据类型可以分为基本类型、复合类型、域、伪类型。 ## 35.2.1\. 基本类型 基本类型是那些在SQL语言层次更低级别(通常是C语言)上实现的类型(比如`int4`类型), 它们通常与抽像数据类型对应。PostgreSQL对这些数据类型只能通过用户提供的函数来操作, 并且对这些数据类型行为的理解只限于用户所描述的范围。基本类型进一步分成标量和数组类型。 对于每种标量类型,系统都会自动创建一个对应的数组类型,可以保存该标量类型的变长数组。 ## 35.2.2\. 复合类型 复合类型(或者说行类型)是用户创建表时创建的。 也可以用[CREATE TYPE](#calibre_link-100)创建一个"独立的"、没有关联表的复合类型。 复合类型只是一个带着相关字段名称的基本类型的列表。 复合类型的数值是一行字段值或者一条字段值组成的记录。 用户可以从SQL查询里访问其字段。 参考[Section 8.16](#calibre_link-956)获取更多复合类型的相关信息。 ## 35.2.3\. 域 域基于一种特定的基本类型,从很多角度来看,它们也可以和其对应的基本类型交换。 但是,域可以有约束,把它的有效值限制在其对应的基本类型的有效值范围的一个子集中。 域可以使用SQL命令[CREATE DOMAIN](#calibre_link-567)创建。 它们的创建和使用不在本章讨论。 ## 35.2.4\. 伪-类型 有一些用于特殊目的"伪类型"。伪类型不能作为表的字段类型, 也不能作为复合类型的属性,但是它们可以用于声明函数的参数和结果类型。 这样就在类型系统里提供了一个标识特殊类型函数的机制。 [Table 8-24](#calibre_link-957)列出了现有的伪类型。 ## 35.2.5\. 多态类型 `anyelement`,`anyarray`, `anynonarray`, `anyenum`, 和`anyrange`是五种特别有趣的伪类型,它们被称作_多态类型_。 任何用这些类型定义的函数就叫做_多态函数_。 一种多态函数可以在许多不同的数据类型上操作, 它们根据调用中实际传递进来的数据类型判断具体的类型。 多态参数和结果是相互绑定的,并且在分析查询调用的函数时解析成特定的数据类型。 每个声明成`anyelement`的位置(参数或者返回类型)都允许拥有一个特定的实际数据类型, 但是在任何给定的调用过程中,它们都必须是_同样的_类型。 每个声明为`anyarray`的位置都可以是任何数组数据类型,类似的,声明为`anyrange`的位置 也必许都是同样的类型。而且,如果有些位置声明为`anyarray`而其它位置声明为`anyelement`, 那么在`anyarray`位置上的类型必须是元素类型与那些出现在`anyelement`位置上的类型相同的数组。 类似的,如果有声明为`anyrange`的位置而且其他的声明为`anyelement`,那么 在`anyrange`位置上的类型必须是子类型与那些出现在`anyelement`位置上类型相同 的范围。`anynonarray`实际上被看做`anyelement`, 但却多一个约束:实际类型必须不能是一个数组类型。 `anyenum`实际上被看做`anyelement`,但却多一个约束: 实际类型必须是一个枚举类型。 因此,如果多个参数位置声明为多态类型,其实际效果是只允许某些实际参数类型的组合出现。 比如,一个函数声明为`equal(anyelement, anyelement)`将接受任何两个输入值,只要它们的数据类型相同。 如果一个函数的返回值声明为多态类型,那么至少有一个参数位置也是多态的, 并且提供给参数的类型决定本次调用实际返回的类型。比如,如果没有数组下标机制, 那么我们可以定义一个实现下标的函数`subscript(anyarray, integer) returns anyelement`。 这个声明约束第一个实际参数是一个数组类型,并且允许分析器从第一个参数的实际类型推导出正确的返回类型。 声明为一个`f(anyarray) returns anyenum`的函数的另一个例子只接受枚举类型的数组。 需要注意的是,`anynonarray`和`anyenum`不代表不同的类型变量; 它们是与`anyelement`相同的类型,只有一个额外的约束。 例如,声明一个函数为`f(anyelement, anyenum)` 等同于声明它为`f(anyenum, anyenum)`: 两个实际参数必须是相同的枚举类型。 一个可变参数函数(其使用一个可变数目的参数,如[Section 35.4.5](#calibre_link-914)中描述) 可以是多态的: 可以通过声明它的最后一个参数为`VARIADIC` `anyarray`来实现。 为了实现参数匹配并决定实际结果类型, 这样一个函数的行为等同于将`anynonarray`参数写一个合适的数目。