日期居然用字串儲存?我笑了

2021-09-24 15:58:29 字數 2296 閱讀 6358

我發現資料庫有些日期居然用字串儲存?於是跟幾個小夥伴討論了關於資料庫的日期應該要怎麼儲存的問題,其實我一直都建議直接用數值儲存時間戳,為什麼我要這麼建議呢?

以下,我會從時區的概念來跟你們解釋一下,為什麼用數值儲存時間戳是最好的方案,同時也為了分享出來,讓更多開發小夥伴留意這些細節性的東西。

相信時區對於很多人來說的很熟悉,因為地球是圓的,在地球上不同角落看到的太陽上公升的角度都是不同的,即每個人對於時間的顯示都是不一樣的,

舉個例子:

此時處於東 8 區的我們北京時間是 10 點,那麼處於東 1 區的時間就是 3 點,但是他們的時間是等價的:

"2019-06-20 10:00 +8:00" = "2019-06-20 3:00 +1:00"
所以說,對於不同時區的人來說,顯示的時間是不一樣的,那麼此時你是如何將將時間儲存到資料中的呢?

我姑且假設你用的是 new date() 方法來儲存當時日期,但據我所知道的,資料庫的 datetime 型別是沒有時區資訊的,如果你此時用 datetime 格式儲存日期,就會丟失時區資訊,如果你的伺服器更該位址,從資料庫讀出來的日期資料就是錯誤的!

可能你會說,那我用 timestamp 型別儲存總不會丟失時區資訊了吧?確實沒丟失,沒毛病。但是據我所知道的,timestamp 儲存的時間最長不能超過 2037 年,而且你要考慮每個資料的 timestamp 型別都有可能不一樣。

to_char(sysdate, '2019-06-01 00:00:00') > start_time
要比較乙個時間大小,我需要這麼做,還需要將系統時間轉成字串來給你對比,而且在轉換成字串比較時,資料庫內部也會將其轉換成時間來比較,你覺得這種查詢條件會好到**去?

我們也知道在 jdk8 中新的時間 api localdatetime 中,有著豐富的時區轉換的方法可用,但即便你說你精通 localdatetime 的各種花式用法,你也不得不面對繁雜的轉換。

所以,我們需要乙個擁有「絕對是時間」,來幫助我們記錄日期,幫我們節省下轉換的時間,這個「絕對時間」就是時間戳,時間戳的定義是從乙個基準時間開始算起,這個基準時間是「1970-1-1 00:00:00 +0:00」,從這個時間開始,用整數表示,以秒計時,隨著時間的流逝這個時間整數不斷增加。這樣一來,我只需要乙個數值,就可以完美地表示時間了,而且這個數值是乙個絕對數值,即無論的身處地球的任何角落,這個表示時間的時間戳,都是一樣的,生成的數值都是一樣的,並且沒有時區的概念,所以在系統的中時間的傳輸中,都不需要進行額外的轉換了,只有在顯示給使用者的時候,才轉換為字串格式的本地時間。

而且很重要的一點就是,在現有的程式語言中,都提供了方法來獲取時間戳,這對於我們不同語言的專案互動來說,不要太方便!所以在這裡我強烈建議前後端關於時間的互動,都用時間戳來互動。

這時,可能有同學又來槓一波,你用乙個出數值來表示時間,我查資料庫時,以我的眼力和口算,根本不知道時間是多少,我覺得這個根本不需要擔心啊,你查資料庫無非是檢視需要的資料而已,你在 sql 裡面對時間戳字段加個轉換函式就好了,比如:

from_unixtime(1561053690000)
以上時間戳是我寫這篇文章的時間。

如果你還要繼續槓,說我就是要在資料庫表中看到時間,我覺得如果你要這樣,為什麼還需要前端,直接拿資料庫當前端展示就好了。

我總結一下資料庫用數值儲存時間戳的諸多好處:

1.在資料庫中日期比較不要太方便,小學一年級就會的數學題,而且效能好;2.數值對於任何系統互動來說都不存在障礙;3.基於絕對時間的數值儲存,不存在時區問題;4.在互動過程中,摒棄沒必要的重重轉換,乙個數字走天下,使用者需要顯示,前端只需要拿到時間戳顯示正確的本地時間;5.解決了由於各個資料庫對於時間實現的不一樣導致的問題,比如說 mysql 的時間函式跟 oracle 會有一些差別,假如你現在的 sql 有某些時間函式,換了資料庫很可能就會出錯。

近期熱文

我對支付平台架構設計的一些思考

聊聊tomcat的架構設計

從原始碼的角度解析執行緒池執行原理

rocketmq訊息傳送的高可用設計

深度解析rocketmq topic的建立機制

rocketmq原始碼分析之路由中心

mybatis-plus原始碼分析之sql注入器

鐘同學,this is for you!

基於jenkins pipeline自動化部署

dubbo服務暴露之註冊位址和埠

dubbo全鏈路追蹤日誌的實現

長按可以訂閱

mysql常用字串 MYSQL常用字串函式寶典

mysql常用字串函式 想更進一步加強自己在查詢語句方面的能力,需要掌握常用函式。字串函式 1 concat s1,s2,sn 將s1,s2,sn串聯成乙個字串。exp root test 14 43 desc t1 field type null key default extra id int ...

C split 用字串分割

string aa 1234124 234234 knfdlgndfl lfgkd nkdfln,xcmv,xzcm mxcnvmxcvnsdklfd string arrresult aa.split new string,stringsplitoptions.none 這裡不能用 string ...

用字串替換空格

用字串 20替換空格 void instead char string,int length i size int newlength size count 2 if length newlength 從後向前依次替換 while newlength 0 size 0 else size 相關題 從...