这篇文章给大家介绍PostgreSQL时间戳与Oracle的不同的是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
PG有两种时间戳:1、timestamp without time zone;2、timestamp with time zone;实际在内部存储上它们并没有什么不同。内部名字分别是timestamp和timestamptz(类型名字问题以前博文讲过,请自行阅读),OID分别是1114和1184。
它们的类型定义:
flying=# select typname,typlen,typstorage,typinput from pg_type where oid in (1114,1184); typname | typlen | typstorage | typinput -------------+--------+------------+---------------- timestamp | 8 | p | timestamp_in timestamptz | 8 | p | timestamptz_in (2 rows) flying=#
都是8字节,保存的是微秒,内部定义是
typedef int64 Timestamp; typedef int64 TimestampTz; typedef int64 TimeOffset; typedef int32 fsec_t; /* fractional seconds (in microseconds) */ typedef struct { TimeOffset time; /* all time units other than days, months and * years */ int32 day; /* days, after time for alignment */ int32 month; /* months and years, after time for alignment */ } Interval;
前两个类型分别对应timestamp和timestamptz,最后一个Interval对应的是类型interval(其他文章提到interval类型的datum是指向数据的指针,就是它了)。
再来看输入函数 timestamptz_in(src/backend/utils/adt/timestamp.c),前边是语法分析(没错,这里嵌了个小语法分析器)解析字符串,如果输入格式是我们常见的诸如:2019-07-09 14:19:34.255 CST 指定时区,它会调用tm2timestamp,在这个函数里有一个根据时区做的调整 dt2local,也就是说最后存储的时间并没有记录输入的时区。
再来看Oracle,它有三种时间戳 1、timestamp without time zone;2、timestamp with time zone;3、timestamp with local time zone;
从文档来看,最后一种是不保存输入时区的,调整为数据库时区,其实这个类型更像PG的timestamp with time zone,而PG并没有类型能够对应Oralce的timestamp with time zone。
先体验一下Oracle下的操作
SQL> CREATE TABLE t(col1 TIMESTAMP WITH TIME ZONE); 表已创建。 SQL> desc t 名称 是否为空? 类型 ----------------------------------------- -------- ---------------------------- COL1 TIMESTAMP(6) WITH TIME ZONE SQL>
默认精度为6
SQL> INSERT INTO t VALUES('15-7月 -19 11.15.46.369000 上午 +08:00'); 已创建 1 行。 SQL> INSERT INTO t VALUES('15-7月 -19 11.15.46.369000 上午 +09:00'); 已创建 1 行。 SQL> SELECT * FROM t; COL1 --------------------------------------------------------------------------- 15-7月 -19 11.15.46.369000 上午 +08:00 15-7月 -19 11.15.46.369000 上午 +09:00 SQL>
PG里同样的操作:
flying=# CREATE TABLE t(col1 TIMESTAMP WITH TIME ZONE); CREATE TABLE flying=# show timezone; TimeZone ---------- UTC (1 row) flying=# INSERT INTO t VALUES('2019-7-15 11:15:46.369000 +8'); INSERT 0 1 flying=# INSERT INTO t VALUES('2019-7-15 11:15:46.369000 +9'); INSERT 0 1 flying=# SELECT * FROM t; col1 ---------------------------- 2019-07-15 03:15:46.369+00 2019-07-15 02:15:46.369+00 (2 rows) flying=# show timezone; TimeZone ---------- UTC (1 row)
插入数据本身的时区属性其实已经消失。
可以设想,如果有一个场景客户对每个输入时间的本地时间更感兴趣,希望查询时原样查出,PG一样可以应对,但明显要给应用开发端找些麻烦了。
自定义类型可以很好满足这个需求,不管是让PG内嵌,还是我们自行定义复合类型,都是可以的,有机会再演示。
关于PostgreSQL时间戳与Oracle的不同的是什么就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。