PostgreSQL类型系统

PostgreSQL 9.4.4 中文手册
上一页 | 上一级 | 章 35. 扩展SQL | 下一页

# 35.2. PostgreSQL类型系统

PostgreSQL数据类型可以分为基本类型、复合类型、域、伪类型。

## 35.2.1. 基本类型

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

## 35.2.2. 复合类型

复合类型(或者说行类型)是用户创建表时创建的。 也可以用CREATE TYPE创建一个"独立的"、没有关联表的复合类型。 复合类型只是一个带着相关字段名称的基本类型的列表。 复合类型的数值是一行字段值或者一条字段值组成的记录。 用户可以从SQL查询里访问其字段。 参考第 8.16 节获取更多复合类型的相关信息。

## 35.2.3. 域

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

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

## 35.2.4. 伪-类型

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

## 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)`: 两个实际参数必须是相同的枚举类型。

一个可变参数函数（其使用一个可变数目的参数，如第 35.4.5 节中描述） 可以是多态的： 可以通过声明它的最后一个参数为`VARIADIC` `anyarray`来实现。 为了实现参数匹配并决定实际结果类型， 这样一个函数的行为等同于将`anynonarray`参数写一个合适的数目。

上一页 | 起始页 | 下一页
扩展性是如何实现的 | 上一级 | 用户定义的函数