PostgreSQL提供了丰富的数据类型。用户可以使用CREATE TYPE命令在数据库中创建新的数据类型。PostgreSQL的数据类型被分为四种,分别是基本数据类型、复合数据类型、域和伪类型。
基本数据类型是数据库内置的数据类型,包括integer、char、varchar等数据类型。表6-1列出了PostgreSQL提供的所有基本数据类型。复合数据类型是用户自己定义的,使用CREATE TYPE命令就能创建一个复合数据类型。域是一种特殊的基本数据类型,它由基本数据类型加上一个约束条件构成,使用CREATE DOMAIN命令就能创建一个域,关于域的详细信息,参考《SQL命令手册》对CREATE DOMAIN命令的解释。伪类型是具有特殊作用的数据类型,这些数据类型不能作为表的列的数据类型,只能作为函数的参数或返回值的数据类型。
下面的小节将会详细介绍基本数据类型、复合数据类型和伪类型。
表6-1.基本数据类型
名字
描述
bigint
有符号8字节整数
bigserial
自增八字节整数
bit [ (n) ]
定长位串
bit varying [ (n) ]
变长位串
boolean
逻辑布尔量 (真/假)
box
平面中的长方形
bytea
二进制数据("字节数组")
character varying [ (n) ]
变长字符串
character [ (n) ]
定长字符串
cidr
IPv4或者IPv6网络地址
circle
平面中的圆
date
日历日期(年,月,日)
double precision
双精度浮点数字
inet
IPv4或者IPv6网络地址
integer
四字节长有符号整数
interval [ (p) ]
时间间隔
line
平面中的无限长直线
lseg
平面中的线段
macaddr
MAC地址
numeric [ (p, s) ]
可选精度的准确数字
path
平面中的几何路径
point
平面中的点
polygon
平面中的封闭几何路径
real
单精度浮点数
smallint
有符号两字节整数
serial
自增四字节整数
text
变长字符串
time [ (p) ] [ without time zone ]
一天里的时间
time [ (p) ] with time zone
一天里的时间,包括时区
timestamp [ (p) ] [ without time zone ]
日期和时间
timestamp [ (p) ] with time zone
日期和时间
tsquery
全文检索查询
tsvector
全文检索文档
txid_snapshot
用户级别事务ID快照
uuid
通用唯一标识符
xml
XML数据
兼容性:下列类型是在SQL标准中定义的:bit,bit varying,boolean,char,character,character varying,varchar,date,double precision,integer,interval,numeric,decimal,real,smallint,time(包括有时区和无时区的),timestamp(包括有时区和无时区的)。
PostgreSQL的词法分析器在解析用户发出的SQL命令时,首先将其中的单词分成五类:整数、非整数数字、字符串、标识符和关键字。大部分的非数值常量首先被认为是字符串。
SQL语言提供了明确地指定字符串的类型的机制。例如:
SELECT 'Origin':: text AS "label", '(0,0)':: point AS "value";
label| value
--------+-------
Origin | (0,0)
(1 row)
在上面的例子中,用户指定'Origin'的类型是text,'(0,0)'的类型是point。如果用户没有明确地指定和'Origin'和'(0,0)'的数据类型,系统先把它们的类型设为unknown,以后再确定它们的具体数据类型。
6.2数值类型
数值类型包括2、4或8字节的整数,4或8字节的浮点数和可以定义精度的十进制数。 表6-2列出了所有数值类型。
表6-2.数值类型
名字
存储空间
描述
取值区间
smallint
2字节
小整数
-32768到+32767
integer
4字节
常用的整数
-2147483648到+2147483647
bigint
8字节
大整数
-9223372036854775808到9223372036854775807
decimal
变长
用户定义精度,可以精确地表示小数
无限制
numeric
变长
用户定义精度,可以精确地表示小数
无限制
real
4字节
精度可变,不能精确地表示小数
精度是6个十进制位
double precision
8字节
精度可变,不能精确地表示小数
精度是15个十进制位
serial
4字节
小范围的自增整数
大范围的自增整数
bigserial
8字节
大范围的自增整数
1到9223372036854775807
数值类型常量的语法在第1.4.4节里描述。 数值类型有一套完整的数学运算符和函数。相关信息请参考第7章。下面将详细描述这些类型。
6.2.1整数类型
类型smallint、integer和bigint只能保存整数,也就是没有小数部分的数字。如果试图在一个整数类型中保存一个超过它能够表示的值范围的整数,数据库将会报错。
常用的类型是integer,因为它提供了在表示范围、存储空间和性能之间的最佳平衡。只有在磁盘空间紧张的情况下才使用smallint。只有在integer太小的时候才使用bigint,因为在进行数学运算时,interger类型的数据bigint类型的数据要快。
SQL标准只定义了整数类型integer(或int)、smallint和bigint。
6.2.2任意精度数值
numeric类型最多能存储有1000个数字位的数字并且能进行准确的数值计算。它主要用于需要准确地表示数字的场合,如货币金额。不过,对numeric类型进行算术运算比整数类型和浮点类型要慢很多。
numeric类型有两个术语,分别是标度和精度。numeric类型的标度(scale)是到小数点右边所有小数位的个数,numeric的精度(precision)是所有数字位的个数,因例如,23.5141的精度是6而标度为4。可以认为整数的标度是零。
numeric类型的最大精度和最大标度都是可以配置的。可以用下面的语法定义一个numeric类型:
(1)NUMERIC(precision,scale)
(2)NUMERIC(precision)
(3)NUMERIC
精度必须为正数,标度可以为零或者正数。在上面的第二种语法中没有指定标度,则系统会将标度设为0,所以NUMERIC(precision,0)和NUMERIC(precision)是等价的。第三种类型的语法没有指定精度和标度,则这种类型的列可以接受任意精度和标度的numeric数据(在系统能表示的最大精度范围内),而不会对输入的数据进行精度或标度的变换。如果一个列被定义成numeric类型而且指定了标度,那么输入的数据将被强制转换成这个标度(如果它的标度比定义列的numeric的标度大),进行标度转换时的规则是四舍五入。如果输入的数据进行标度转换后得到的数据在小数点左边的数据位的个数超过了列的类型的精度减去标度的差,系统将会报告类似下面的错误:
错误:numeric类型数据溢出。
细节:precision为3, scale为3的数必须被四舍五入成小于1的数。
下面是一个实例:
create table test ( col1 numeric(3,3));
insert into test values(0.5678);
insert into test values(0.5671);
insert into test values ( 1.4);
错误:numeric类型数据溢出。
细节:precision为3, scale为3的数必须被四舍五入成小于1的数。
=>select * from test;
col1
-------
0.568
0.567
(2 rows)
numeric类型接受一个特殊的值 “NaN”,它的意思是“不是一个数字"。任何在NaN上面的操作都生成另外一个NaN。 如果在SQL命令里把这些值当作一个常量写,必须把它用单引号引起来,比如UPDATE table SET x = 'NaN'。在输入时,”NaN”的大小写无关紧要。
注意:在其它的数据库中,NaN和任何的数值数据都不相等,两个NaN也是不相等的,在postgresSQL中,为了索引实现的方便,NaN被看成大于或等于所有非NaN的数值。
类型decimal和numeric是等价的,两种类型都是SQL标准定义的,SQL标准要求numeric的默认精度应该是0,PostgreSQL没有执行这个规则,为了增强程序的移植性,最好同时指定numeric的精度和标度。
6.2.3浮点类型
数据类型real和double precision表示不准确的变精度的数字。这些类型实现了IEEE标准754二进制浮点数算术(分别对应单精度和双精度)。
不准确的意思是一些数值不能准确地用real和double precision表示,存储在数据库里的只是它们的近似值。如果要求准确地保存某些数值(比如计算货币金额),应使用numeric类型。另外,比较两个浮点数是否相等时,可能会得到意想不到的结果。
通常,real类型的表示的数值范围是至少-1E+37到+1E+37,精度至少是6位小数。double precision类型表示的范围通常是-1E+308到+1E+308,精度是至少15位小数。太大或者太小的数值都会导致错误。如果输入数据的精度太高,会被约成可以被接受的精度。太接近零的数字,如果和0的内部表示形式一样,会产生下溢(underflow)的错误。
浮点类型还有几个特殊值:
Infinity-InfinityNaN
这些值分别表示IEEE 754标准中的特殊值"正无穷大","负无穷大", 以及"不是一个数字"。如果在SQL命令里把这些数值当作常量写,必须在它们用单引号引起来,例如UPDATE table SET x = 'Infinity'。 输入时,这些值的大小写无关紧要。
注意:IEEE 754标准要求NaN和任何的数值数据都不相等,两个NaN也是不相等的,在postgresSQL中,为了索引实现的方便,NaN被看成大于或等于所有非NaN的数值。
PostgreSQL还支持SQL标准中定义的类型float和float(p)。p定义以二进制位表示的最低可以接受的精度,p的取值在1到53之间。实际上,如果p的取值在1到24之间,float(p)被看成是real类型,如果p的取值在25到53之间,float(p)被看成是double precision类型。不带精度的float被看成是double precision类型。
6.2.4序列号类型(Serial)
serial和bigserial并不是真正的数据类型,只是为了可以给表中的数据行设置一个唯一的标识。它类似其它一些数据库中的AUTO_INCREMENT属性。使用它们的方法如下:
CREATE TABLEtablename(
colnameSERIAL
);
上面的命令实际上上等价于下面的两条命令:
CREATE SEQUENCEtablename_colname_seq;
CREATE TABLEtablename(
colnameinteger DEFAULT nextval('tablename_colname_seq') NOT NULL
);
上面的命令在表中创建了一个类型为无符号整数的列,该列与一个序列对象相关联,这个序列对象的初始值是1, 表中每插入一条新的记录,该序列的值会自动加一,在向表中插入数据时,INSERT命令不要为该列指定数据,或者指定它的值为DEFAULT。
下面是一个实例:
create table test3 ( product_id serial, name char(5));
insert into test3(name)values('pen');
insert into test3(name)values('car');
insert into test3values(DEFAULT, 'bike');
=>select * fromtest3;
product_id | name
------------+-------
1 | pen
2 | car
3 | bike
(3 rows)
注意:insert命令中一定不要为serial或bigserial类型的列指定一个不是DEFAULT的值,因为对于这样的命令系统是不会报错的,会导致serial或bigserial类型的列上的数值出现混乱。
6.3字符类型
表6-3.字符类型
名字
描述
character varying(n),varchar(n)
变长,最大长度有限制
character(n),char(n)
定长,不足补空白
text
变长,最大长度没有限制
表6-3列出了PostgresSQL中可以使用的字符类型。
SQL标准定义了两种基本的字符类型:character varying(n)和character(n),这里的n是一个正整数。两种类型最多可以存储n个字符。试图存储更长的字串到这些类型的列里,系统会报错,除非所有超出长度n的字符都是空格(这种情况下该字符串将被截断成长度为n的字符串)。如果要存储的字符串的长度比n小,类型为character的列将自动用空格填充该字符串,使它的长度达到n,而类型为character varying的列直接保存该字符串,不会对它进行任何处理。
如果明确将把一个数值转换成character(n)或者character varying(n)类型,如果转换以后的字符串的长度超过n,那么它将被自动截断成长度为n的字符串,系统不会报错(这也是SQL标准要求的)。
char(n)和varchar(n)分别是character(n)和character varying(n)的别名。没有定义长度的character等同于character(1)。没有定义长度的character varying类型接受任意长度的字符串,这是PostgreSQL的扩展特性。
另外,PostgreSQL提供了text类型,它可以存储任意长度的字符串,而且长度没有最大限制。尽管SQL标准中没有定义text类型,但许多其它SQL数据库系统中有这个类型。
character(n)类型的数据在存储时长度不足n的字符串会用空格填充,在显示数据时也会把填充的空格显示出来,但是在比较两个character类型的值的时候,字符串的所有结尾空格符号将自动被忽略,在转换成其它字符串类型的时候,character类型的值里面结尾的空格字符都会被删除。请注意,对于character varying和text类型的值,结尾的空格在处理时是不会被忽略的。
对于character(n)和character varying(n)类型,允许存储的最长字符串所占的存储空间大概1GB。如果想存储长度没有上限的长字串,那么使用text类型或者没有指定长度的character varying。
提示:这三种数据类型之间没有性能差别,不过character(n)比character varying(n)类型多使用了物理存储空间。 虽然在某些其它的数据库系统里,character(n)比character varying(n)快一些, 但在PostgreSQL里没有这种情况。在大多数情况下,应该使用text或者character varying。
请参考第1.4.1节和1.4.2节得到字符串常量的的语法信息,参考第7.4节得到处理字符串的运算符和函数的信息。数据库的字符集决定用于存储文本值的字符集,有关字符集的详细信息,请参考《数据库管理员指南》第5章。
下面是一个使用字符串的实例:
CREATE TABLE test1 (a character(4));
INSERT INTO test1 VALUES ('ok');
INSERT INTO test1 VALUES ('ok ');--ok后面跟了一个空格
SELECT a, char_length(a) FROM test1; --函数char_length在第7.4节中有详细介绍.
a| char_length
------+-------------
ok|2
ok|2
(2 rows)
CREATE TABLE test2 (b varchar(5));
INSERT INTO test2 VALUES ('ok');
INSERT INTO test2 VALUES ('good');
INSERT INTO test2 VALUES ('too long');
错误:输入的字符串对于类型character varying(5)来说过长。
INSERT INTO test2 VALUES ('too long'::varchar(5)); --截断字符串
SELECT b, char_length(b) FROM test2;
b| char_length
-------+-------------
ok|2
good|5
too l |5
在PostgreSQL还有另外两种定长字符串类型,在表6-4里显示。这两种类型是供系统内部使用的,应用程序不应该使用这两种类型。name类型长度当前定为64字节(63可用字符加上结束符)。类型"char"(注意引号)和char(1)是不一样的,它只占一个字节的存储空间,它在系统内部当枚举类型用。
表6-4。 特殊字符类型
名字
存储空间
描述
"char"
1字节
单字节内部类型
name
64字节
对象名的内部类型
6.4二进制数据类型
bytea类型可以存储二进制字符串,如表6-5所示。
表6-5.二进制数据类型
名字
存储空间
描述
bytea
1或4字节加上实际的二进制字符串
变长的二进制字符串
二进制字符串是一个字节数值的序列。SQL标准定义了一种不同的二进制字符串类型,叫做BLOB或者BINARY LARGE OBJECT,其输入格式和bytea不同,但是提供的函数和操作符大多一样。bytea类型数据的具体含义由应用程序自己决定,数据库也提供了和普通文本字符串的处理方式类似的方法来对bytea类型数据进行输入和输出。
可以使用字符串常量的语法来输入bytea类型的数据,对特殊的字符如单引号、反斜杠、不可打印的字符以及0,要使用转义表示法,具体用法如表6-6所示。
表6-6.需要进行转义处理的字符
十进制数值
描述
输入格式
例子
输出格式
0
零
'//000'
select '//000'::bytea;
/000
39
单引号
'/''或者'//047'
select '/''::bytea;
'
92
反斜杠
''或者'//134'
select ''::bytea;
//
0到31和127到255
不可打印的字符
'//xxx'(八进制值)
SELECT '//001'::bytea;
/001
bytea类型的数据在输出时也要进行转义处理,反斜杠用两个反斜杠表示,不可打印的字符用反斜杠加上表示它们的值的三个八进制位表示,可打印的字符用它们自身表示。如表6-7所示。
表6-7.bytea输出格式
十进制数值
描述
转义以后的输出个数
例子
输出结果
92
反斜杠
//
select '//134'::bytea;
//
0到31和127到255
不可打印的八进制字符
/xxx(octal value)
select '//001'::bytea;
/001
32到126
可打印的八进制字符
客户端字符集表现形式
(1)select '//175'::bytea;
(2)select '//165//166'::bytea
(1)}
(2)uv
6.5日期/时间类型
PostgreSQL支持SQL标准中所有的日期和时间类型,如表6-8所示。这些数据类型上可以进行的操作在第7.9节里描述。
表6-8.日期/时间类型
名字
存储空间大小
描述
最小值
最大值
分辨率
timestamp [ (p) ] [ without time zone ]
8 bytes
包括日期和时间
4713 BC
294276 AD
1微妙/ 14位
timestamp [ (p) ] with time zone
8 bytes
包括日期和时间,带时区
4713 BC
294276 AD
1微妙/ 14位
interval [ (p) ]
12 bytes
时间间隔
-178000000年
178000000年
1微妙/ 14位
date
4 bytes
只有日期
4713 BC
5874897 AD
1天
time [ (p) ] [ without time zone ]
8 bytes
只有时间
00:00:00
24:00:00
1微妙/ 14位
time [ (p) ] with time zone
12 bytes
只有时间,带时区
00:00:00+1459
24:00:00-1459
1微妙/ 14位
time、timestamp和interval可以定义精度值p,这个精度值定义用来表示秒的小数位的个数,默认的情况下,没有精度限制。对于timestamp和interval,p的取值范围是0到6(实际的精度可能小于6)。对于time,p的取值范围是0到10。
类型time with time zone是SQL标准定义的,这个类型有些多余。在大多数情况下,date、time、timestamp without time zone和timestamp with time zone的组合就能满足任何应用需求。
类型abstime和reltime是低分辨率时间类型,它们是数据库内部使用的类型,在应用程序里面不应该使用这两个类型。
6.5.1日期/时间输入
日期和时间可以用多种格式来表示,包括ISO 8601、SQL标准中定义的格式等。对于一些格式,日期输入里的月和天的表示可能会有歧义,如果参数DateStyle被设置为MDY,数据库将按“月-日-年”的格式来解释输入的数据,DMY表示“日-月-年”,而YMD表示“年-月-日”。
PostgreSQL在处理日期/时间输入上比SQL标准要灵活得多。像一个文本字符串一样,任何日期或时间的输入都必须用单引号括起来。SQL标准定义的语法如下:
type[ (p) ] 'value'
对于time、timestamp和interval类型的数据可以指定精度p,p的取值范围上一节已经讲过。如果没有定义p,默认是输入的时间常量的精度。 表6-9、6-10和6-11列出了日期/时间数据在输入和输出时使用的关键字。
表6-9.表示月的关键字
月
缩写
January
Jan
February
Feb
March
Mar
April
Apr
May
June
Jun
July
Jul
August
Aug
September
Sep, Sept
October
Oct
November
Nov
December
Dec
表6-10.表示天的关键字
天
缩写
Sunday
Sun
Monday
Mon
Tuesday
Tue, Tues
Wednesday
Wed, Weds
Thursday
Thu, Thur, Thurs
Friday
Fri
Saturday
Sat
表6-11.日期/时间域修饰符
标识符
描述
ABSTIME
忽略
AM
12:00以前的时间
AT
忽略
JULIAN,JD,J
下一个域用儒略日表示(Julian Day)
ON
忽略
PM
12:00以后的时间
T
下一个域是时间
6.5.1.1日期
表6-12显示了date类型可能的输入格式。
表6-12.日期格式
例子
描述
January 8, 1999
无论参数datestyle取任何值,都没有歧义
1999-01-08
ISO-8601格式,任何模式下都是1999年1月8号(推荐使用该格式)
1/8/1999
有歧义,在MDY下是1月8日;在DMY模式下是做8月1日
1/18/1999
在MDY模式下是1月18日,其它模式下被拒绝
01/02/03
MDY模式下的2003年一月2日;DMY模式下的2003 年 2月 1日;YMD模式下的2001年二月三日
1999-Jan-08
任何模式下都是1月8日
Jan-08-1999
任何模式下都是1月8日
08-Jan-1999
任何模式下都是1月8日
99-Jan-08
在YMD模式下是1月8日,其它模式报错
08-Jan-99
1月8日,YMD模式下会报错
Jan-08-99
1月8日,YMD模式下会报错
19990108
ISO-8601;任何模式下都是1999年1月8日
990108
ISO-8601;任何模式下都是1999年1月8日
1999.008
年和年里的第几天
J2451187
儒略日
January 8, 99 BC
公元前99年
6.5.1.2时间
时间类型包括time [ (p) ] without time zone和time [ (p) ] with time zone。 只写time等同于time without time zone。对于类型time [ (p) ] with time zone,需要同时指定时间和日期。如果在time without time zone类型的输入中指定了时区,时区会被忽略。
表6-13.时间输入
例子
描述
04:05:06.789
ISO 8601
04:05:06
ISO 8601
04:05
ISO 8601
040506
ISO 8601
04:05 AM
与04:05一样;AM不影响数值
04:05 PM
与16:05一样;输入小时数必须<= 12
04:05:06.789-8
ISO 8601
04:05:06-08:00
ISO 8601
04:05-08:00
ISO 8601
040506-08
ISO 8601
04:05:06 PST
带缩写的时区
2003-04-12 04:05:06 America/New_York
带全称的时区
表6-14.时区输入
例子
描述
PST
太平洋标准时间(Pacific Standard Time)
America/New_York
时区全称
PST8PDT
POSIX风格的时区名称
-8:00
ISO-8601与PST的偏移
-800
ISO-8601与PST的偏移
-8
ISO-8601与PST的偏移
Zulu
军方对UTC的缩写(译注:可能是美军)
Z
zulu的缩写
视图pg_timezone_names列出了所有可以识别的时区名。
6.5.1.3时间戳(timestamp)
时间戳类型的输入由一个日期和时间的联接组成,后面跟着一个可选的时区,一个可选的AD或者BC(AD/BC可以出现在时区前面,但最好放在时区的后面)。下面是两个实例,它们兼容ISO8601:
(1)1999-01-08 04:05:06
(2)1999-01-08 04:05:06 -8:00
还可以使用下面的格式
January 8 04:05:06 1999 PST
SQL标准通过查看符号"+"或"-"是否存在来区分常量的类型是timestamp without time zone还是timestamp with time zone。例如,TIMESTAMP '2004-10-19 10:23:54'的类型timestamp without time zone,TIMESTAMP '2004-10-19 10:23:54+02'的类型是timestamp with time zone。PostgreSQL不使用这个规则,因此前面的两个例子的例子都会被认为timestamp without time zone。在PostgreSQL中,timestamp without time zone类型的常量前面必须加上TIMESTAMP WITH TIME ZONE,例如,TIMESTAMP WITH TIME ZONE '2004-10-19 10:23:54+02'。
timestamp without time zone类型的常量中如果有时区信息,时区信息会被系统自动忽略。
timestamp with time zone类型的数据的内部存储的格式总是UTC(全球统一时间,以前也叫格林威治时间GMT)。如果一个输入值中指定了时区,系统将以该时区为依据将它转换为UTC格式,如果在输入的值中没有指定声明,系统以参数timezone的值作为指定时区为依据,将它转换为UTC格式。
如果要输出一个timestamp with time zone类型的数据,它总是从UTC被转到参数timezone指定的时区,并被显示为该时区的本地时间。要看其它时区的该时间,要么修改参数参数timezone的值,要么使用AT TIME ZONE子句(参考第7.9.3节)。
在timestamp without time zone和timestamp with time zone之间的进行转换是通常假设timestamp without time zone数值的时区是参数timezone指定的时区。可以用AT TIME ZONE指定其它的时区。
6.5.1.4时间间隔
interval类型的数值可以用下面语法来定义:
[@]quantityunit[quantityunit...] [direction]
这里quantity是一个数字(可能有符号),unit是microsecond、millisecond、second、minute,、hour、day、week、month、year、decade、century、millennium或者这些单位的缩写或复数,direction可以是ago或者为空。符号 “@”是可选的,可以不写。
天、小时、分钟以及秒的数值的后面可以不用明确地跟单位。 比如,“1 12:59:10”和“1 day 12 hours 59 min 10 sec”是等价的。
可选精度p的取值在0到6之间,默认是输入的常量的精度。
6.5.1.5特殊值
PostgreSQL为方便起见支持几个特殊输入值,所有这些值在SQL命令里作为常量使用时,要用单引号引起来。now、today、tomorrow和yesterday在被读取时会被自动转换为普通的日期或时间值。
表6-15.特殊日期/时间输入
输入的字符串
有效的数据类型
描述
Epoch
date,timestamp
1970-01-01 00:00:00+00 (Unix系统零时)
infinity
timestamp
比任何其它时间戳都晚
-infinity
timestamp
比任何其它时间戳都早
Now
date,time,timestamp
当前事务开始的时间
Today
date,timestamp
今日午夜
tomorrow
date,timestamp
明日午夜
yesterday
date,timestamp
昨日午夜
allballs
time
00:00:00.00 UTC
下列与SQL标准兼容的函数也可以用于获取对应数据类型的当前值:CURRENT_DATE,CURRENT_TIME,CURRENT_TIMESTAMP,LOCALTIME,LOCALTIMESTAMP。最后四个函数接受一个可选的秒的精度值(在第7.9.4节里对这些函数有详细描述)。
6.5.2日期/时间输出
时间/日期类型的输出格式有四种:ISO 8601、SQL(Ingres)、传统的POSTGRES和German。可以使用命令SET datestyle来设置时间/日期类型的输出格式,默认是ISO格式(SQL标准要求使用ISO 8601格式)。表6-16列出了了每种输出格式的实例。
表6-16.日期/时间输出格式
类型
描述
例子
ISO
ISO-8601/SQL标准
1997-12-17 07:37:16-08
SQL
传统风格
12/17/1997 07:37:16.00 PST
POSTGRES
原始风格
Wed Dec 17 07:37:16 1997 PST
German
地区风格
17.12.1997 07:37:16.00 PST
如果参数datestyle里有DMY信息,在SQL和POSTGRES风格里,日期在月份之前出现,否则月份出现在日期之前。表6-17是另外一些实例。
表6-17.日期顺序
类型
描述
例子
SQL, DMY
日/月/年
17/12/1997 15:37:16.00 CET
SQL, MDY
月/日/年
12/17/1997 07:37:16.00 PST
Postgres, DMY
日/月/年
Wed 17 Dec 07:37:16 1997 PST
interval的输出格式和输入格式类似,century和week被转换成年和日,而ago被转换成合适的符号。在ISO模式下输出格式如下:
[quantityunit[ ... ]] [days] [hours:minutes:secondes]
可以用命令SET datestyle来设置日期/时间的输出格式,也可以在文件postgresql.conf里修改参数DateStyle的值。也可以用函数to_char(参阅第7.8节)更灵活地控制输出格式。
6.5.3时区
PostgreSQL目前支持1902年到2038年之间的夏时制时间(对应于传统Unix系统时间的表示的范围)。如果时间超过这个范围,那么假设时间是选取的时区的"标准时间"。SQL标准在日期和时间类型和功能上有一些混乱,下面是两个常见的问题:
(1)date(日期)类型与时区没有关联,而time(时间)类型却有或可以与时区关联。然而现实世界的时区必须与与时间和日期同时关联才有意义。
(2)默认的时区用同UTC的偏移来表示。因此,当在DST的边界进行日期/时间运算时,无法将时间转换成夏时制时间。
为了解决这些问题,建议在使用时区的时候,使用那些同时包含日期和时间的日期/时间类型。建议不要使用类型time with time zone(保留此类型是为了同SQL标准兼容)。
PostgresSQL有三种方式来指定时区名