前言

数据类型是编程语言中,在其数据结构上定义的相同值类型的集合以及对该相同值集合的一组操作。而数据类型的值存储离不开变量,因此变量的一个作用就是使用它来存储相同值集的数据类型。数据类型决定了如何将代表这些值的集合存储在计算机的内存中。变量一般遵循先声明后使用的原则。而在数据库中,变量就是字段,用字段来表示一组相同值类型的集合,其实也是先声明后使用的原则。

PostgreSQL支持丰富的数据类型,包括一般的数据类型和非常规的数据类型。一般数据类型包括数值型,货币类型,字符类型,日期类型,布尔类型,枚举类型等,非常规数据类型包括二进制数据类型,几何类型,网络地址类型,位串类型,文本搜索类型,UUID类型,XML类型,JSON类型,数组类型,复合类型,范围类型,Domain类型,OID类型,pg_lsn类型和pseudo-Types类型。

一、数值类型

1.1整型

PostgreSQL中的整型类型有小整型,整型,大整型,用 smallint,integer,和bigint表示,虽然三个都可以存储相同的数据类型,但是它们各自的存储大小和存储范围却不相同。见下表:

 

如下示例所示,在PostgreSQL中,smallint,integer,bigint 数据类型可以使用 int2,int4,int8的扩展写法来标识。

示例:

hrdb=# --创建整型数据类型的表
hrdb=# CREATE TABLE IF NOT EXISTS tab_num(v1 smallint,v2 smallint,v3 int,v4 int,v5 bigint,v6 bigint);
CREATE TABLE
hrdb=# --表字段注释
hrdb=# COMMENT ON COLUMN tab_num.v1 IS '小整型最小范围';
COMMENT
hrdb=# COMMENT ON COLUMN tab_num.v2 IS '小整型最大范围';
COMMENT
hrdb=# COMMENT ON COLUMN tab_num.v3 IS '整型最小范围';
COMMENT
hrdb=# COMMENT ON COLUMN tab_num.v4 IS '整型最大范围';
COMMENT
hrdb=# COMMENT ON COLUMN tab_num.v5 IS '大整型最小范围';
COMMENT
hrdb=# COMMENT ON COLUMN tab_num.v6 IS '大整型最大范围';
COMMENT
hrdb=# --描述数据类型
hrdb=# \d+ tab_num
                                    Table "public.tab_num"
 Column |   Type   | Collation | Nullable | Default | Storage | Stats target |  Description   
--------+----------+-----------+----------+---------+---------+--------------+----------------
 v1     | smallint |           |          |         | plain   |              | 小整型最小范围
 v2     | smallint |           |          |         | plain   |              | 小整型最大范围
 v3     | integer  |           |          |         | plain   |              | 整型最小范围
 v4     | integer  |           |          |         | plain   |              | 整型最大范围
 v5     | bigint   |           |          |         | plain   |              | 大整型最小范围
 v6     | bigint   |           |          |         | plain   |              | 大整型最大范围

hrdb=# --插入不同整型的范围数值
hrdb=# INSERT INTO tab_num
hrdb-# VALUES (-32768,
hrdb(#         32767,
hrdb(#         -2147483648,
hrdb(#         2147483647,
hrdb(#         -9223372036854775808,
hrdb(#         9223372036854775807);
INSERT 0 1
hrdb=# --查询结果
hrdb=# SELECT * FROM  tab_num;
   v1   |  v2   |     v3      |     v4     |          v5          |         v6          
--------+-------+-------------+------------+----------------------+---------------------
 -32768 | 32767 | -2147483648 | 2147483647 | -9223372036854775808 | 9223372036854775807
(1 row)

如上所示,查询的结果为插入不同整型范围的最值,也说明不同整型范围的边界都是被包括的。在实际生产场景中,SMALLINT、INTEGER和BIGINT类型存储各种范围的数字,也就是整数。当试图存储超出范围以外的数值将会导致错误。

常用的类型是INTEGER,因为它提供了在范围、存储空间、性能之间的最佳平衡。一般只有取值范围确定不超过SMALLINT的情况下,才会使用SMALLINT类型。而只有在INTEGER的范围不够的时候才使用BIGINT,因为前者相对要快。

除此之外,创建表也可以使用 int2,int4,int8来代表 smallint,integer,bigint。如下示例所示:

hrdb=# /*
hrdb*# smallint,integer,bigint
hrdb*# 数据类型分别使用
hrdb*# int2,int4,int8代替
hrdb*# */
hrdb-# CREATE TABLE IF NOT EXISTS tab_numint(v1 int2,v2 int2,v3 int4,v4 int4,v5 int8,v6 int8);
CREATE TABLE
hrdb=# --描述表定义及数据类型
hrdb=# \d+ tab_numint
                                 Table "public.tab_numint"
 Column |   Type   | Collation | Nullable | Default | Storage | Stats target | Description 
--------+----------+-----------+----------+---------+---------+--------------+-------------
 v1     | smallint |           |          |         | plain   |              | 
 v2     | smallint |           |          |         | plain   |              | 
 v3     | integer  |           |          |         | plain   |              | 
 v4     | integer  |           |          |         | plain   |              | 
 v5     | bigint   |           |          |         | plain   |              | 
 v6     | bigint   |           |          |         | plain   |  

1.2任意精度类型和浮点类型

任意精度类型 numeric、decimal可以存储范围大的数字,存储大小为可变大小,小数点前最多131072位数字,小数点后最多16383位。它可以使用类似浮点类型,将小数精确到保留几位,也可以参与计算可以得到准确的值,但是相比于浮点类型,它的计算比较慢。通常 numeric被推荐使用于存储货币金额或其它要求计算准确的值。详细见下表:

示例:任意精度类型

hrdb=# --任意精度类型示例
hrdb=# CREATE TABLE IF NOT EXISTS tab_any_precision(col1 numeric(10,4),col2 decimal(6,4),col3 real,col4 double precision,col5 float4,col6 float8);
CREATE TABLE
hrdb=# --字段注释
hrdb=# COMMENT ON COLUMN tab_any_precision.col1 IS '表示整数最大位数为6,小数仅保留4位';
COMMENT
hrdb=# COMMENT ON COLUMN tab_any_precision.col2 IS '表示整数最大位数为2,小数保留4位';
COMMENT
hrdb=# COMMENT ON COLUMN tab_any_precision.col3 IS '表示可变的6位精度的数值类型';
COMMENT
hrdb=# COMMENT ON COLUMN tab_any_precision.col4 IS '表示可变的15位精度的数值类型';
COMMENT
hrdb=# COMMENT ON COLUMN tab_any_precision.col5 IS '同real';
COMMENT
hrdb=# COMMENT ON COLUMN tab_any_precision.col6 IS '同double precision';
COMMENT
hrdb=# --查看表定义
hrdb=# \d+ tab_any_precision
                                            Table "public.tab_any_precision"
 Column |       Type       | Collation | Nullable | Default | Storage | Stats target |            Description            
--------+------------------+-----------+----------+---------+---------+--------------+-----------------------------------
 col1   | numeric(10,4)    |           |          |         | main    |              | 表示整数最大位数为6,小数仅保留4位
 col2   | numeric(6,4)     |           |          |         | main    |              | 表示整数最大位数为2,小数保留4位
 col3   | real             |           |          |         | plain   |              | 表示可变的6位精度的数值类型
 col4   | double precision |           |          |         | plain   |              | 表示可变的15位精度的数值类型
 col5   | real             |           |          |         | plain   |              | 同real
 col6   | double precision |           |          |         | plain   |              | 同double precision

hrdb=# --插入任意精度测试
hrdb=# INSERT INTO tab_any_precision
hrdb-# VALUES(202004.26,20.2004,20.200426,20.203415341535157,20.200426,20.203415341535157);
INSERT 0 1
hrdb=# INSERT INTO tab_any_precision
hrdb-# VALUES(202004.26105,20.20045,20.2004267,20.2034153415351573,20.2004264,20.2034153415351575);
INSERT 0 1
hrdb=# --可以发现col1和col2小数部分可以超过4位,但是读取仅仅保留4位,并遵循四舍五入的原则,如下结果
hrdb=# SELECT * FROM tab_any_precision;
    col1     |  col2   |  col3   |       col4       |  col5   |       col6       
-------------+---------+---------+------------------+---------+------------------
 202004.2600 | 20.2004 | 20.2004 | 20.2034153415352 | 20.2004 | 20.2034153415352
 202004.2611 | 20.2005 | 20.2004 | 20.2034153415352 | 20.2004 | 20.2034153415352
(2 rows)

hrdb=# /*
hrdb*# 如果 col1 插入的整数最大位数超过6,将会报错。
hrdb*# 如果 col2 插入的整数最大位数超过2,将会报错。
hrdb*# real 和 double precision 没有限制。
hrdb*# */
hrdb-# INSERT INTO tab_any_precision
hrdb-# VALUES(2020042.610,20.2004,20.2004267,20.2034153415351573,20.2004264,20.2034153415351575);
ERROR:  numeric field overflow
DETAIL:  A field with precision 10, scale 4 must round to an absolute value less than 10^6.
hrdb=# INSERT INTO tab_any_precision
hrdb-# VALUES(202004.26105,202.200,20.2004267,20.2034153415351573,20.2004264,20.2034153415351575);
ERROR:  numeric field overflow
DETAIL:  A field with precision 6, scale 4 must round to an absolute value less than 10^2.
hrdb=#

1.3序列类型

SMALLSERIAL,SERIAL和BIGSERIAL类型不是真正的数据类型,只是为在表中设置唯一标识做的概念上的便利。因此,创建一个整数字段,并且把它的缺省数值安排为从一个序列发生器读取。应用了一个NOT NULL约束以确保NULL不会被插入。在大多数情况下用户可能还希望附加一个UNIQUE或PRIMARY KEY约束避免意外地插入重复的数值,但这个不是自动的。最后,将序列发生器从属于那个字段,这样当该字段或表被删除的时候也一并删除它。

示例:

hrdb=# --创建序列类型表
hrdb=# CREATE TABLE tab_serial(col1 smallserial,col2 serial,col3 bigserial);
CREATE TABLE
hrdb=# --字段注释
hrdb=# COMMENT ON  COLUMN tab_serial.col1 IS '小整型序列,从1开始,最大值为32767';
COMMENT
hrdb=# COMMENT ON  COLUMN tab_serial.col2 IS '小整型序列,从1开始,最大值为2147483647';
COMMENT
hrdb=# COMMENT ON  COLUMN tab_serial.col3 IS '小整型序列,从1开始,最大值为9223372036854775807';
COMMENT
hrdb=# --查看表定义
hrdb=# \d+ tab_serial
                                                                    Table "public.tab_serial"
 Column |   Type   | Collation | Nullable |                 Default                  | Storage | Stats target |                   Description                    
--------+----------+-----------+----------+------------------------------------------+---------+--------------+--------------------------------------------------
 col1   | smallint |           | not null | nextval('tab_serial_col1_seq'::regclass) | plain   |              | 小整型序列,从1开始,最大值为32767
 col2   | integer  |           | not null | nextval('tab_serial_col2_seq'::regclass) | plain   |              | 小整型序列,从1开始,最大值为2147483647
 col3   | bigint   |           | not null | nextval('tab_serial_col3_seq'::regclass) | plain   |              | 小整型序列,从1开始,最大值为9223372036854775807

hrdb=# --插入数据
hrdb=# INSERT INTO tab_serial VALUES(1,1,1);
INSERT 0 1
hrdb=# INSERT INTO tab_serial VALUES(32767,2147483647,9223372036854775807);
INSERT 0 1
hrdb=# --如果插入的值大于序列整型值的范围,将会整型类型越界的ERROR
hrdb=# INSERT INTO tab_serial VALUES(32767,2147483647,9223372036854775808);
ERROR:  bigint out of range
hrdb=# INSERT INTO tab_serial VALUES(32767,2147483648,9223372036854775807);
ERROR:  integer out of range
hrdb=# INSERT INTO tab_serial VALUES(32768,2147483647,9223372036854775807);
ERROR:  smallint out of range

hrdb=# --当然,既然是序列类型,那可以插入默认值
hrdb=# INSERT INTO tab_serial
hrdb-# VALUES(default,default,default);
INSERT 0 1

通过上述示例,可以知道 smallserial,serial,bigserial相当于先创建一个序列,然后在创建表分别指定不同的整型数据类型smallint,integer,bigint。如下示例:

hrdb=# --先创建序列
hrdb=# CREATE SEQUENCE IF NOT EXISTS serial_small
hrdb-# INCREMENT BY 1
hrdb-# START WITH 1 
hrdb-# NO CYCLE;
CREATE SEQUENCE
hrdb=# --再创建表
hrdb=# CREATE TABLE IF NOT EXISTS tab_test_serial(
hrdb(# col1 smallint default nextval('serial_small'),
hrdb(# col2 integer default nextval('serial_small'),
hrdb(# col3 bigint default nextval('serial_small')
hrdb(# );
CREATE TABLE
hrdb=# --插入数据
hrdb=# INSERT INTO tab_test_serial VALUES(default);
INSERT 0 1
hrdb=# --查询数据
hrdb=# SELECT * FROM tab_test_serial ;
 col1 | col2 | col3 
------+------+------
    1 |    2 |    3
(1 row)

二、货币数据类型

货币类型存储带有固定小数精度的货币金额。

关于货币数据类型的详细信息如下表:


示例:

hrdb=# --创建货币数据类型表
hrdb=# CREATE TABLE IF NOT EXISTS tab_money(amounts money);
CREATE TABLE
hrdb=# --字段注释
hrdb=# COMMENT ON COLUMN tab_money.amounts IS '金额';
COMMENT
hrdb=# --插入数值
hrdb=# INSERT INTO tab_money VALUES('20.00');
INSERT 0 1
hrdb=# --查询数据
hrdb=# SELECT * FROM tab_money;
 amounts 
---------
  $20.00
(1 row)

这里需要注意的是,如果插入的货币数据类型的金额没有明确指定货币表示符号,那么默认输出本区域货币符号,如上示例所示的20.00输出为$20.00。

如果是人民币,那么如何处理呢?

解决方法有两种,第一种,使用translate函数;第二种,修改本地区域货币符号显示参数。

hrdb=# --方法一:直接使用translate函数将 $ 符号转换为 ¥ 符号
hrdb=# SELECT translate(amounts::varchar,'$','¥') FROM tab_money;
 translate 
-----------
 ¥20.00
(1 row)

hrdb=# --方法二:修改区域货币符号显示参数
hrdb=# --查看本地区域货币符号显示参数
hrdb=# show lc_monetary ;
 lc_monetary 
-------------
 en_US.UTF-8
(1 row)

hrdb=# --修改区域货币符号显示参数
hrdb=# ALTER SYSTEM SET lc_monetary = 'zh_CN.UTF-8';
ALTER SYSTEM
hrdb=# --重新加载动态参数
hrdb=# SELECT pg_reload_conf();
 pg_reload_conf 
----------------
 t
(1 row)

hrdb=# --重新查看本地区域货币符号显示参数
hrdb=# show lc_monetary;
 lc_monetary 
-------------
 zh_CN.UTF-8
(1 row)

hrdb=# --重新查询数据
hrdb=# SELECT * FROM tab_money;
 amounts 
---------
 ¥20.00
(1 row)

货币符号作为特殊的数据类型,需要注意计算方式,以防止发生精度丢失的问题。

这种问题解决方式需要将货币类型转换为 numeric 类型以避免精度丢失。

hrdb=# INSERT INTO tab_money VALUES('20.22');
INSERT 0 1
hrdb=# SELECT * FROM tab_money ;
 amounts 
---------
 ¥20.00
 ¥20.22
(2 rows)

hrdb=# --货币数据类型避免精度丢失的解决方法
SELECT amounts::numeric::float8 FROM tab_money;
 amounts 
---------
      20
   20.22

温馨提示:

当一个money类型的值除以另一个money类型的值时,结果是double precision(也就是,一个纯数字,而不是money类型);在运算过程中货币单位相互抵消。

三、布尔类型

PostgreSQL提供标准的boolean值,boolean的状态为 true或者false和unknown,如果是unknown状态表示boolean值为null。


示例:

hrdb=# --创建boolean类型表
hrdb=# CREATE TABLE IF NOT EXISTS tab_boolean(col1 boolean,col2 boolean);
CREATE TABLE
hrdb=# --插入布尔类型的状态值,状态值可以是以下任意一种
hrdb=# INSERT INTO tab_boolean VALUES(TRUE,FALSE);--规范用法
INSERT 0 1
hrdb=# INSERT INTO tab_boolean VALUES('true','false');
INSERT 0 1
hrdb=# INSERT INTO tab_boolean VALUES('True','False');
INSERT 0 1
hrdb=# INSERT INTO tab_boolean VALUES('TRUE','FALSE');
INSERT 0 1
hrdb=# INSERT INTO tab_boolean VALUES('1','0');
INSERT 0 1
hrdb=# INSERT INTO tab_boolean VALUES('on','off');
INSERT 0 1
hrdb=# INSERT INTO tab_boolean VALUES('ON','OFF');
INSERT 0 1
hrdb=# INSERT INTO tab_boolean VALUES('y','n');
INSERT 0 1
hrdb=# INSERT INTO tab_boolean VALUES('Y','N');
INSERT 0 1
hrdb=# INSERT INTO tab_boolean VALUES('yes','no');
INSERT 0 1
hrdb=# INSERT INTO tab_boolean VALUES('Yes','No');
INSERT 0 1
hrdb=# INSERT INTO tab_boolean VALUES('YES','NO');
INSERT 0 1
hrdb=# SELECT * FROM tab_boolean ;
 col1 | col2 
------+------
 t    | f
 t    | f
 t    | f
 t    | f
 t    | f
 t    | f
 t    | f
 t    | f
 t    | f
 t    | f
 t    | f
 t    | f
(12 rows)

boolean类型被广泛地使用在业务环境中,例如手机开关机,1表示开机,0表示关机或不在服务区。手机APP登录登出,1表示登录,0表示登出,微信登陆状态,1表示登录成功,0表示登录失败(可能由于网络或者密码错误导致)等等,此处不再一一举例。

四、字符类型

SQL定义了两种主要的字符类型:character varying(n) 和 character(n)。该处的n是一个正数。这两种字符类型都可以存储n(非字节)个长度的字符串。如果存储的字符长度超过了字符类型约束的长度会引起错误,除非多出的字符是空格。


注意,除了每列的大小限制以外,每个元组的总大小也不可超过1G-8023B(即1073733621B)。

在PostgreSQL中,除了以上的字符数据类型外,还有两种特殊的字符类型如下:


示例:

hrdb=# --创建字符类型表
hrdb=# CREATE TABLE IF NOT EXISTS tab_chartype(
hrdb(# col1 char(15),
hrdb(# col2 varchar(15),
hrdb(# col3 text,
hrdb(# col4 name,
hrdb(# col5 "char" );
CREATE TABLE
hrdb=# --字段注释
hrdb=# COMMENT ON COLUMN tab_chartype.col1 IS '表示定长为15的字符串';
COMMENT
hrdb=# COMMENT ON COLUMN tab_chartype.col2 IS '表示变长为15的字符串';
COMMENT
hrdb=# COMMENT ON COLUMN tab_chartype.col3 IS '表示变长字符串,为varchar的扩展字符串';
COMMENT
hrdb=# COMMENT ON COLUMN tab_chartype.col4 IS '用于对象名的内部类型';
COMMENT
hrdb=# COMMENT ON COLUMN tab_chartype.col5 IS '表示单字节类型';
COMMENT
hrdb=# --插入数据
hrdb=# INSERT INTO tab_chartype
hrdb-# VALUES('sungsasong','sungsasong','sungsasong','tab_chartype','s');
INSERT 0 1
hrdb=# --插入包含空格的数据
hrdb=# INSERT INTO tab_chartype
hrdb-# VALUES('sungsa song','sung sas ong','sung sa song ','tab_chartype','s');
INSERT 0 1
hrdb=# --计算不同数据类型存储的字符串的长度
hrdb=# SELECT char_length(col1),char_length(col2),char_length(col3),char_length(col4),char_length(col5)
hrdb-# FROM tab_chartype ;
 char_length | char_length | char_length | char_length | char_length 
-------------+-------------+-------------+-------------+-------------
          10 |          10 |          10 |          12 |           1
          11 |          12 |          13 |          12 |           1

温馨提示:
在上面示例中,虽然统计的col1的定长为15的字符存储的字符长度为10个和11个,但是实际上,在存储中col1列占用的长度为15个。并且,在计算长度的时候,空格也被当作一个字符来对待。

五、二进制数据类型

在PostgreSQL中,二进制数据类型有两种,一种为 bytea hex格式,一种为 bytea escape格式。


注意:除了每列的大小限制以外,每个元组的总大小也不可超过1G-8203字节。

示例:

hrdb=# --创建两种bytea格式的表
hrdb=# CREATE TABLE IF NOT EXISTS tab_bytea(col1 bytea,col2 bytea);
CREATE TABLE
hrdb=# --字段注释
hrdb=# COMMENT ON COLUMN tab_bytea.col1 IS 'bytea hex 格式的二进制串';
COMMENT
hrdb=# COMMENT ON COLUMN tab_bytea.col2 IS 'bytea escape 格式的二进制串';
COMMENT
hrdb=# --插入数据,第一个值代表单引号,输出16进制的值为\x27,第二个为转义16进制的值f
hrdb=# INSERT INTO tab_bytea
hrdb-# VALUES('\047',E'\xF');
INSERT 0 1
hrdb=# --插入数据,第一个值代表反斜杠,输出16禁止的值为\x5c,第二个值为转义16进制的值fc
hrdb=# INSERT INTO tab_bytea
hrdb-# VALUES('\134',E'\\xFC');
INSERT 0 1
hrdb=# --查看结果
hrdb=# SELECT * FROM tab_bytea;
 col1 | col2 
------+------
 \x27 | \x0f
 \x5c | \xfc

注意:

实际上bytea多个十六进制值使用E’\xFC’ 类似于Oracle中的rawtohex函数。只不过Oracle中的rawtohex函数转换后的值为大写十六进制字符串。实际上如果要在上表中的col2中插入E’\xFG’时,会提示G不是一个有效的十六进制字符。

同时需要注意的是,如果使用E’\xF’只包含单个十六进制字符时,使用一个反斜杠,如果有多个十六进制字符,需要两个反斜杠,如E’\xFE’。

如下:此处的hextoraw函数为我自定义实现的一个UDF函数。

hrdb=# SELECT hextoraw('FCd');
 hextoraw 
----------
 FCD
INSERT INTO tab_bytea
VALUES('\134',E'\\xFG');
ERROR:  invalid hexadecimal digit: "G"
LINE 2: VALUES('\134',E'\\xFG');

六、日期时间数据类型

PostgreSQL支持丰富的日期时间数据类型如下表:

6.1日期输入

日期和时间的输入可以是任何合理的格式,包括ISO-8601格式、SQL-兼容格式、传统POSTGRES格式或者其它的形式。系统支持按照日、月、年的顺序自定义日期输入。如果把DateStyle参数设置为MDY就按照“月-日-年”解析,设置为DMY就按照“日-月-年”解析,设置为YMD就按照“年-月-日”解析。

日期的文本输入需要加单引号包围,语法如下:
type [ ( p ) ] ‘value’

可选的精度声明中的p是一个整数,表示在秒域中小数部分的位数。

示例:

hrdb=> --创建日期输入表
hrdb=> CREATE TABLE tab_datetype(col1 date);
CREATE TABLE
hrdb=> --字段注释
hrdb=> COMMENT ON COLUMN tab_datetype.col1 IS '日期类型,默认遵循datestyle风格(MDY)';
COMMENT
hrdb=> --插入数据
hrdb=> INSERT INTO tab_datetype VALUES(date '04-26-2020');
INSERT 0 1
hrdb=> --在MDY风格下,也支持YMD的输入方式,但是不支持DMY或者其它格式的输入,如下会报错
hrdb=> INSERT INTO tab_datetype VALUES(date '22-04-2020');
ERROR:  date/time field value out of range: "22-04-2020"
LINE 1: INSERT INTO tab_datetype VALUES(date '22-04-2020');
                                             ^
HINT:  Perhaps you need a different "datestyle" setting.
hrdb=> --解决办法,修改datestyle的格式
hrdb=> --查看当前数据库的datestyle的格式
hrdb=> show datestyle;
 DateStyle 
-----------
 ISO, MDY
(1 row)

hrdb=> --会话级别修改datestyle格式
hrdb=> SET datestyle = 'DMY';
SET
hrdb=> --再次插入 22-04-2020
hrdb=> INSERT INTO tab_datetype VALUES(date '22-04-2020');
INSERT 0 1
hrdb=> --查询数据
hrdb=> SELECT * FROM tab_datetype ;
    col1    
------------
 2020-04-26
 2020-04-22

6.2时间输入

时间类型包括

time [ § ] without time zone 和time [ § ] with time zone。

如果只写time等效于time without time zone。即不带时区的时间格式

如果在time without time zone类型的输入中声明了时区,则会忽略这个时区。

示例:

hrdb=> --不带时区的时间
hrdb=> SELECT time '13:22:25';
   time   
----------
 13:22:25
(1 row)

hrdb=> SELECT time without time zone '20:20:18';
   time   
----------
 20:20:18
(1 row)

hrdb=> SELECT time with time zone '18:20:20';
   timetz    
-------------
 18:20:20+08
(1 row)

6.3特殊时间类型

特殊时间类型以reltime表示,表示真实的时间计算值,如100将会使用00:01:40来表示。

示例:

hrdb=> --创建reltime时间数据类型表
hrdb=> CREATE TABLE tab_reltime(col1 varchar,col2 reltime);
CREATE TABLE
hrdb=> --字段注释
hrdb=> COMMENT ON COLUMN tab_reltime.col1 IS '原始时间文本时间';
COMMENT
hrdb=> COMMENT ON COLUMN tab_reltime.col2 IS 'reltime表示的时间以实际时间计算得到显示结果';
COMMENT
hrdb=> --插入数据
hrdb=> INSERT INTO tab_reltime VALUES('125','125');
INSERT 0 1
hrdb=> INSERT INTO tab_reltime VALUES('10 DAYS','10 DAYS');
INSERT 0 1
hrdb=> INSERT INTO tab_reltime VALUES('420 DAYS 12:00:23','420 DAYS 12:00:23');
INSERT 0 1
hrdb=> --查询数据
hrdb=> SELECT * FROM tab_reltime;
       col1        |             col2              
-------------------+-------------------------------
 125               | 00:02:05
 10 DAYS           | 10 days
 420 DAYS 12:00:23 | 1 year 1 mon 25 days 06:00:23

温馨提示:

对于 reltime 时间的输入,需要使用文本类型的输入,也就是说使用单引号引起来。

6.4其它时间类型

其它时间类型包含时间戳及间隔时间数据类型,示例如下:

示例:

hrdb=> --创建时间戳和间隔时间表
hrdb=> CREATE TABLE tab_timestamp_interval(col1 timestamp with time zone,col2 timestamp without time zone,col3 interval day to second);
CREATE TABLE
hrdb=> --字段注释
hrdb=> COMMENT ON COLUMN tab_timestamp_interval.col1 IS '带时区的时间戳';
COMMENT
hrdb=> COMMENT ON COLUMN tab_timestamp_interval.col2 IS '不带时区的时间戳';
COMMENT
hrdb=> COMMENT ON COLUMN tab_timestamp_interval.col1 IS '间隔时间类型';
COMMENT
hrdb=> --插入数据
hrdb=> INSERT INTO tab_timestamp_interval
hrdb-> VALUES('2020-04-26 13:20:34.234322 CST',
hrdb(>        '2020-04-08 14:40:12.234231+08',
hrdb(>        '165');
INSERT 0 1
hrdb=> INSERT INTO tab_timestamp_interval
hrdb-> VALUES('2020-04-25 14:56:34.223421',
hrdb(>        '2020-04-09 18:54:12.645643 CST',
hrdb(>        '10 YEAR 3 MONTH 25 DAYS 14 HOUR 32 MINUTE 19 SECOND');
INSERT 0 1
hrdb=> --查询数据
hrdb=> SELECT * FROM  tab_timestamp_interval;
             col1              |            col2            |               col3               
-------------------------------+----------------------------+----------------------------------
 2020-04-27 03:20:34.234322+08 | 2020-04-08 14:40:12.234231 | 00:02:45
 2020-04-25 14:56:34.223421+08 | 2020-04-09 18:54:12.645643 | 10 years 3 mons 25 days 14:32:19