PostgreSQL 数据类型可以分为基本类型、复合类型、域、伪类型。
基本类型是那些在 SQL 语言层次更低级别(通常是 C 语言)上实现的类型(比如 int4 类型),它们通常与抽像数据类型对应。PostgreSQL 对这些数据类型只能通过用户提供的函数来操作,并且对这些数据类型行为的理解只限于用户所描述的范围。基本类型进一步分成标量和数组类型。对于每种标量类型,系统都会自动创建一个对应的数组类型,可以保存该标量类型的变长数组。
复合类型(或者说行类型)是用户创建表时创建的。也可以用 CREATE TYPE 创建一个"独立的"、没有关联表的复合类型。复合类型只是一个带着相关字段名称的基本类型的列表。复合类型的数值是一行字段值或者一条字段值组成的记录。用户可以从 SQL 查询里访问其字段。参考节8.11获取更多复合类型的相关信息。
域基于一种特定的基本类型,从很多角度来看,它们也可以和其对应的基本类型交换。但是,域可以有约束,把它的有效值限制在其对应的基本类型的有效值范围的一个子集中。
域可以用 SQL 命令 CREATE DOMAIN 创建。它们的创建和使用不在本章讨论。
系统里有集中用于特殊目的的"伪类型"。伪类型不能作为表的字段类型,也不能作为复合类型的属性,但是它们可以用于声明函数的参数和结果类型。这样就在类型系统里提供了一个标识特殊类型函数的机制。表8-20列出了现有的伪类型。
anyelement 和 anyarray 是两种特别有趣的伪类型,它们被称作多态类型。任何用这些类型定义的函数就叫做多态函数。一种多态函数可以在许多不同的数据类型上操作,它们根据调用中实际传递进来的数据类型判断具体的类型。
多态参数和结果是相互绑定的,并且在分析查询调用的函数时解析成特定的数据类型。每个声明成 anyelement 的位置(参数或者返回类型)都允许拥有一个特定的实际数据类型,但是在任何给定的调用过程中,它们都必须是同样的类型。每个声明为 anyarray 的位置都可以是任何数组数据类型,类似的,它们也必许都是同样的类型。如果有些位置声明为 anyarray 而其它位置声明为 anyelement ,那么在 anyarray 位置上的类型必须是元素类型与那些出现在 anyelement 位置上的类型相同的数组。
因此,如果多个参数位置声明为多态类型,其实际效果是只允许某些实际参数类型的组合出现。比如,一个函数声明为 equal(anyelement, anyelement) 将接受任何两个输入值,只要它们的数据类型相同。
如果一个函数的返回值声明为多态类型,那么至少有一个参数位置也是多态的,并且提供给参数的类型决定本次调用实际返回的类型。比如,如果没有数组下标机制,那么我们可以定义一个实现下标的函数 subscript(anyarray, integer) returns anyelement 。这个声明约束第一个实际参数是一个数组类型,并且允许分析器从第一个参数的实际类型推导出正确的返回类型。