PostgreSQL時間戳與Oracle的不一樣

PG有兩種時間戳:一、timestamp without time zone;二、timestamp with time zone;實際在內部存儲上它們並無什麼不一樣。內部名字分別是timestamp和timestamptz(類型名字問題之前博文講過,請自行閱讀),OID分別是1114和1184。sql

它們的類型定義:數據庫

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字節,保存的是微秒,內部定義是bash

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,它有三種時間戳 一、timestamp without time zone;二、timestamp with time zone;三、timestamp with local time zone;code

從文檔來看,最後一種是不保存輸入時區的,調整爲數據庫時區,其實這個類型更像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裏一樣的操做:input

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內嵌,仍是咱們自行定義複合類型,都是能夠的,有機會再演示。

相關文章
相關標籤/搜索