數據庫的幾種日期時間類型,你真的會用嗎?

日期和時間是每個系統,每個數據庫設計必不可少的部分。也是容易被大家忽視的部分。很多開發者可能根本不瞭解以不同類型存儲日期和時間意味着什麼。

有朋友可能會說,數據庫定義一個datetime或timestamp類型的字段,然後在Java代碼中獲取當前時間並存入數據庫不就可以了嗎?

Date now = new Date();
// 調用insert或update方法創建或更新日期字段。

最近設計新系統的數據庫,涉及到跨時區的問題,於是專門調研了不同日期時間類型的利弊,也諮詢了不少同行使用的情況。這裏分享給大家。

常見的日期時間使用情況有如下幾種:字符串、Datetime、Timestamp、Unix timestamp。如果將日期和時間具體拆分細化又可包含DATE、TIME、YEAR,這部分我們這裏暫且不過多討論。

字符串存儲日期

把日期和時間當做一個字符串進行存儲,進而將日期和時間拆分成兩個字段,一個字段記錄日期(如yyyy-MM-dd),另外一個字段存儲時間(如:HH:mm:ss)的形式。

此種方式就不多說,除非極個別的場景,不建議使用。當使用此種方式進行處理日期,不僅性能有問題,比較、處理、取範圍等都是麻煩事。

之所以提出這種方式,也是提醒大家,如果你的數據庫日期字段還在用字符串存儲,需要慎重考慮一下了。

DateTime類型

DateTime類型存儲的值既有日期又有時間。我們直觀看到的格式爲:yyyy-MM-dd HH:mm:ss。它支持的時間範圍是“1000-00-00 00:00:00”到“9999-12-31 23:59:59”。

但DateTime中並未存儲時區信息,只存儲了本地時間。也就是說:如果你將服務器的時區進行修改,數據庫中記錄的日期和時間並不會對應的變化。

那麼,讀出的數據與新存儲的數據便是不一致的,也可以說是錯誤的。

通常,針對此種情況,如果涉及到跨時區問題,可考慮單獨用一個字段來存儲時區。

Timestamp類型

Timestamp類型:也是既有日期又有時間的數據。存儲和顯示的格式跟Datetime一樣。支持的時間範圍是“1970-01-01 00:00:01”到“2038-01-19 03:14:07”。

Timestamp類型不僅存儲了日期和時間,還存儲了時區信息。如果以Timestamp類型存儲,各數據庫的實現會有所不相同,有的進行了內部時區自動轉換。

如果應用服務器的時區和數據庫服務器的時區不一致,你無法確定數據庫驅動程序會不會自動幫你轉換。

同時,時間範圍是Timestamp硬傷。

Unix timestamp

由於時區問題,地球上不同地方的人看到太陽升起的時間是不一樣的。比如歐洲和北京時差有6-7個小時,當早上8點在北京看到太陽時,歐洲還處於凌晨1-2點。

除了上面所說的通過Timestamp類型存儲包含時區的日期和時間外,還可以通過“絕對時間”來進行計算,單位爲秒。

在計算機中,當前時間是指從一個基準時間(1970-1-1 00:00:00 +0:00)到現在的秒數,用一個整數表示。

在Java編程語言中我們可以通過如下兩種方式(這裏單位爲毫秒)獲取:

System.currentTimeMillis();

// 需要JDK8以上版本
Instant.now().toEpochMilli()

那麼,我們只需要將表示絕對時間的時間戳通過Long類型或float類型保存到數據庫中,當不同時區使用時直接格式化成對應的字符串就可以了。對應數據庫類型爲Bigint或float。

關於使用絕對時間戳的好處有以下幾項:

1、數據存儲的時區問題不存在了,只是一個絕對的數值。

2、比較時也很簡單,只用比較兩個數值的大小或範圍即可,範圍可採用between(?, ?)形式的SQL。

3、顯示問題也很容易處理,各個展示端,只需要根據所在時區對數值進行轉換即可,即便是JavaScript也能正常處理。

有朋友可能會說,數據庫的可讀性太差。在調研時我也遇到類似的疑問,後來諮詢了架構師的朋友,他說mysql提供了豐富的函數,可以進行轉換。

image

上圖中,數據庫存儲的是毫秒數,通過FROM_UNIXTIME函數,在查詢時將其轉換成指定格式即可。如果你的數據庫存儲的單位爲秒,則在SQL中無需除以1000。

關於日期時間的其他事項

爲了調研數據庫日期和時間的設置,也參考了阿里的開發手冊,令人疑惑的是阿里使用的竟然是datetime類型。

image

後來跟PayPal的朋友溝通之後,便豁然開朗了。他說:阿里的開發手冊在我們公司只做參考。

的確如此,畢竟每個公司的業務範圍不同,使用場景也不同。優秀的理念可以參考,但不能照搬。就好比本篇文章,介紹了不同類型的日期和時間存儲,而根據你的業務場景選擇最適合的那便是最好的。

我這裏最終決定用絕對時間戳來進行處理。

原文鏈接:《數據庫的幾種日期時間類型,你真的會用嗎?

精品SpringBoot 2.x視頻教程

《Spring Boot 2.x 視頻教程全家桶》,精品Spring Boot 2.x視頻教程,打造一套最全的Spring Boot 2.x視頻教程。


程序新視界

公衆號“程序新視界”,一個讓你軟實力、硬技術同步提升的平臺

微信公衆號:程序新視界

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章