
PostgreSQL提供了丰富的数据类型,数据类型是我们在创建表的时候为每个字段设置的。这样做的好处是用户可以使用 CREATE TYPE 命令在数据库中创建新的数据类型。PostgreSQL 的数据类型有很多种,下面我们具体来讲解。
复合类型
复合类型表示一行或者一条记录的结构; 它实际上只是一个字段名和它们的数据类型的列表。PostgreSQL 允许像简单数据类型那样使用复合类型。比如,一个表的某个字段可以声明为一个复合类型。
声明复合类型
下面是两个定义复合类型的简单例子:CREATE TYPE complex AS (
r double precision,
i double precision);CREATE TYPE inventory_item AS (
name text,
supplier_id integer,
price numeric);
语法类似于 CREATE TABLE,只是这里只可以声明字段名字和类型。
定义了类型,我们就可以用它创建表:CREATE TABLE on_hand (
item inventory_item,
count integer);INSERT INTO on_hand VALUES (ROW('fuzzy dice', 42, 1.99), 1000);
复合类型值输入
要以文本常量书写复合类型值,在圆括弧里包围字段值并且用逗号分隔他们。 你可以在任何字段值周围放上双引号,如果值本身包含逗号或者圆括弧, 你必须用双引号括起。
复合类型常量的一般格式如下:'( val1 , val2 , ... )'
一个例子是:'("fuzzy dice",42,1.99)'
访问复合类型
要访问复合类型字段的一个域,我们写出一个点以及域的名字, 非常类似从一个表名字里选出一个字段。实际上,因为实在太像从表名字中选取字段, 所以我们经常需要用圆括弧来避免分析器混淆。比如,你可能需要从on_hand 例子表中选取一些子域,像下面这样:SELECT item.name FROM on_hand WHERE item.price > 9.99;
这样将不能工作,因为根据 SQL 语法,item是从一个表名字选取的, 而不是一个字段名字。你必须像下面这样写:SELECT (item).name FROM on_hand WHERE (item).price > 9.99;
或者如果你也需要使用表名字(比如,在一个多表查询里),那么这么写:SELECT (on_hand.item).name FROM on_hand WHERE (on_hand.item).price > 9.99;
现在圆括弧对象正确地解析为一个指向item字段的引用,然后就可以从中选取子域。
范围类型
范围数据类型代表着某一元素类型在一定范围内的值。
例如,timestamp 范围可能被用于代表一间会议室被预定的时间范围。
PostgreSQL 内置的范围类型有:int4range — integer的范围
int8range —bigint的范围
numrange —numeric的范围
tsrange —timestamp without time zone的范围
tstzrange —timestamp with time zone的范围
daterange —date的范围
此外,你可以定义你自己的范围类型。CREATE TABLE reservation (room int, during tsrange);INSERT INTO reservation VALUES (1108, '[2010-01-01 14:30, 2010-01-01 15:30)');-- 包含SELECT int4range(10, 20) @> 3;-- 重叠SELECT numrange(11.1, 22.2) && numrange(20.0, 30.0);-- 提取上边界SELECT upper(int8range(15, 25));-- 计算交叉SELECT int4range(10, 20) * int4range(15, 25);-- 范围是否为空SELECT isempty(numrange(1, 5));
范围值的输入必须遵循下面的格式:(下边界,上边界)(下边界,上边界][下边界,上边界)[下边界,上边界]空
圆括号或者方括号显示下边界和上边界是不包含的还是包含的。注意最后的格式是 空,代表着一个空的范围(一个不含有值的范围)。-- 包括3,不包括7,并且包括二者之间的所有点SELECT '[3,7)'::int4range;-- 不包括3和7,但是包括二者之间所有点SELECT '(3,7)'::int4range;-- 只包括单一值4SELECT '[4,4]'::int4range;-- 不包括点(被标准化为‘空’)SELECT '[4,4)'::int4range;
对象标识符类型
PostgreSQL 在内部使用对象标识符(OID)作为各种系统表的主键。
同时,系统不会给用户创建的表增加一个 OID 系统字段(除非在建表时声明了WITH OIDS 或者配置参数default_with_oids设置为开启)。oid 类型代表一个对象标识符。除此以外 oid 还有几个别名:regproc, regprocedure, regoper, regoperator, regclass, regtype, regconfig, 和regdictionary。名字引用描述数值例子oid任意数字化的对象标识符564182
regprocpg_proc函数名字sum
regprocedurepg_proc带参数类型的函数sum(int4)
regoperpg_operator操作符名+
regoperatorpg_operator带参数类型的操作符*(integer,integer) 或 -(NONE,integer)
regclasspg_class关系名pg_type
regtypepg_type数据类型名integer
regconfigpg_ts_config文本搜索配置english
regdictionarypg_ts_dict文本搜索字典simple
伪类型
PostgreSQL类型系统包含一系列特殊用途的条目, 它们按照类别来说叫做伪类型。伪类型不能作为字段的数据类型, 但是它可以用于声明一个函数的参数或者结果类型。 伪类型在一个函数不只是简单地接受并返回某种SQL 数据类型的情况下很有用。
下表列出了所有的伪类型:名字描述any表示一个函数接受任何输入数据类型。
anyelement表示一个函数接受任何数据类型。
anyarray表示一个函数接受任意数组数据类型。
anynonarray表示一个函数接受任意非数组数据类型。
anyenum表示一个函数接受任意枚举数据类型。
anyrange表示一个函数接受任意范围数据类型。
cstring表示一个函数接受或者返回一个空结尾的 C 字符串。
internal表示一个函数接受或者返回一种服务器内部的数据类型。
language_handler一个过程语言调用处理器声明为返回language_handler。
fdw_handler一个外部数据封装器声明为返回fdw_handler。
record标识一个函数返回一个未声明的行类型。
trigger一个触发器函数声明为返回trigger。
void表示一个函数不返回数值。
opaque一个已经过时的类型,以前用于所有上面这些用途。