31.2. PostgreSQL 类型系统

数据类型可以分为基本类型,复合类型,域和伪类型。

31.2.1. 基本类型

基本类型是那些在 SQL 语言层次更低的级别上 实现的类型,比如 int4(通常是一种低级的语言, 比如 C):它们通常与那些常被认为是抽象数据类型的类型对应; PostgreSQL 对这些数据类型只能通过用户提供的方法来操作, 并且对这些数据类型的特性的理解只限于用户所描述的范围. 基本类型进一步分成标量和数组类型。对于每种标量类型, 系统都会自动创建一个对应的数组类型,可以保存该标量类型 变长的数组。

31.2.2. 复合类型

复合类型,或者说行类型,是当用户创建表时创建的. 我们也可以创建一个"独立的",没有关联表的 复合类型。一种复合类型只是一个带着相关字段名称的基本类型的列表。 一个复合类型的数值是一行字段值或者一条字段值组成的记录。 用户可以从 SQL 查询里访问组成字段。

31.2.3. 域

域是基于一种特定的基本类型的,从很多角度来看,它们也可以和对应 的基本类型交换。但是,一个域可以有约束,把它的有效值限制在它 的下层基本类型允许的有效值范围的一个子集。

域可以用 SQL 命令 CREATE DOMAIN 创建。 它们的创建和使用不在本章讨论。

31.2.4. 伪类型

系统里有集中用于特殊目的的"伪类型"。伪类型不能出现在表 的字段类型中,也不能用做复合类型的属性,但是它们可以用于声明函数的参数和 结果类型。这样就在类型系统里提供了一个机制用于标识特殊类型的函数。 Table 8-20 列出了现有的伪类型。

31.2.5. 多态类型

两种特别有趣的伪类型是 anyelementanyarray, 它们在一起称作多态类型。任何用这些类型定义 的函数就叫做多态函数。一种多态函数可以在许多不同 的数据类型上操作,它们判断具体类型的方法是在一次调用中,使用实际传递进来的数据类型 来判断。

多态参数和结果是相互绑定,并且在分析查询调用的函数时解析成特定的数据类型。 每个声明成 anyelement 的位置(参数或者返回类型)都允许拥有 一个特定的实际数据类型,但是在任何给定的调用过程中,它们都必须同样的类型。每个声明为 anyarray 的位置 都可以是任何数组数据类型,但是,类似的,它们也不许都是同样的类型。如果有些 位置声明为 anyarray 而其它的为自豪声明为 anyelement, 那么在 anyarray 位置上的类型必须是元素类型与那些出现在 anyelement 位置上的同类型的数组。

因此,如果多于一个参数位置声明为一个多态类型,其实际效果是只允许某些实际 参数类型的组合出现。比如,一个函数声明为 equal(anyelement, anyelement) 将接受任何两个输入值,只要它们的数据类型相同。

如果一个函数的的返回值声明为多态类型,那么至少有一个参数位置也是多态的, 并且提供给参数的类型决定该词调用实际返回的类型。比如,如果没有数组下标 机制,那么我们可以定义一个函数实现下标的函数,像 subscript(anyarray, integer) returns anyelement。 这个声明约束实际上的第一个参数是一个数组类型,并且允许分析器从第一个参数的 实际类型里推导出正确的返回类型。