久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

mysql的timestamp存在的時區(qū)問題怎么解決

142次閱讀
沒有評論

共計 8997 個字符,預(yù)計需要花費 23 分鐘才能閱讀完成。

這篇文章主要講解了“mysql 的 timestamp 存在的時區(qū)問題怎么解決”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著丸趣 TV 小編的思路慢慢深入,一起來研究和學(xué)習(xí)“mysql 的 timestamp 存在的時區(qū)問題怎么解決”吧!

簡介

眾所周知,mysql 中有兩個時間類型,timestamp 與 datetime,但當(dāng)在網(wǎng)上搜索 timestamp 與 datetime 區(qū)別時,會發(fā)現(xiàn)網(wǎng)上有不少與時區(qū)有關(guān)的完全相反的結(jié)論,主要兩種:

timestamp 沒有時區(qū)問題,而 datetime 有時區(qū)問題,原因是 timestamp 是以 UTC 格式存儲的,而 datetime 存儲類似于時間字符串的形式

兩種觀點讓人迷惑,那 timestamp 到底會不會有時區(qū)問題呢?

答:因為 mysql 數(shù)據(jù)庫未指定所在時區(qū)默認(rèn)為美國中部時間
(UTC-06:00),美國從“3 月 11 日”至“11 月 7 日”實行夏令時,美國中部時間改為 UTC-05:00,與 UTC+08:00 相差 13 小時, 冬令時則相差 14 個小時。所以存儲的時候時間就已經(jīng)有“誤差了”。
各位小伙伴使用 timestamp 類型的時候一定要注意指定時區(qū),不管是在數(shù)據(jù)庫配置指定還是數(shù)據(jù)庫連接的參數(shù)設(shè)置,一定要指定時區(qū)。

serverTimezone=Asia/Shanghai
show variables like ‘%time_zone% 
set time_zone= +08:00 
select now();

基本概念

時區(qū):
由于地域的限制,人們發(fā)明了時區(qū)的概念,用來適應(yīng)人們在時間感受上的差異,比如中國的時區(qū)是東 8 區(qū),表示為 +8:00,或 GMT+8,而日本的時區(qū)是東 9 區(qū),表示為 +9:00,或 GMT+9,當(dāng)中國是早上 8 點時,日本是早上 9 點,即東 8 區(qū)的 8 點與東 9 區(qū)的 9 點,這兩個時間是相等的。
另外時間還有如下兩個概念:

絕對時間:

如 unix 時間綴,是 1970-01-01 00:00:00 開始到現(xiàn)在的秒數(shù),如:1582416000,這種表示是絕對時間,不受時區(qū)影響,也叫紀(jì)元時 epoch。

本地時間:

相對于某一時區(qū)的時間,是本地時間,比如東 8 區(qū)的 2020-02-23 08:00:00,是中國人的本地時間,而在此時,日本人的本地時間是 2020-02-23 09:00:00,所以本地時間都是與某一時區(qū)相關(guān)的,脫離時區(qū)看本地時間,是沒有意義的,因為你并不知道這具體是指的什么時間點。

比如在 Java 中,Date 對象是絕對時間,通過 SimpleDateFormat 格式化出來的 yyyy-MM-dd HH:mm:ss 形式的時間字符串,是本地時間,如果 SimpleDateFormat 沒有調(diào)用 setTimeZone()顯示指定時區(qū),那么默認(rèn)用的是 jvm 運行在的操作系統(tǒng)上的時區(qū),我們開發(fā)機(jī)上的時區(qū)基本都是 GMT+8。

timestamp 與 datetime 區(qū)別

如下,我創(chuàng)建了一張表,里面 time_stamp 是 timestamp 類型,date_time 是 datetime 類型,create_timestamp、create_datetime 是 timestamp 與 datetime 類型,但是它們可以由數(shù)據(jù)庫自動生成。

CREATE TABLE `time_test` (
 `id` bigint unsigned,
 `time_stamp` timestamp,
 `date_time` datetime,
 `create_timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT  創(chuàng)建時間 ,
 `create_datetime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT  創(chuàng)建時間 ,
 PRIMARY KEY (`id`)
)

1、首先將數(shù)據(jù)庫時區(qū)設(shè)置為 +8:00,即中國的東 8 區(qū)

2、然后如下手動插入一個固定時間的數(shù)據(jù),以及用 now()函數(shù)插入當(dāng)前時間

3、當(dāng)插入完數(shù)據(jù)后,然后我們修改當(dāng)前會話的時區(qū)為 +9:00,即日本的東 9 區(qū),然后再次查看數(shù)據(jù)

4、如上,定義為 timestamp 類型的列 time_stamp、create_timestamp 不管是手動插入的,還是 now()函數(shù)插入的,東 9 區(qū)都比東 8 區(qū)的時間大 1 個小時,這是正確的,說明 timestamp 類型是時區(qū)相關(guān)的,然而定義為 datetime 類型的 date_time、create_datetime 字段,時間都沒有變化,這說明 datetime 類型是時區(qū)無關(guān)的。

結(jié)論:
timestamp 在存儲上是包含時區(qū)的,而 datetime 是不包含時區(qū),說明網(wǎng)上的第一種說法是對的。

再看個例子
我們將東 8 區(qū)的的 2020-02-23 08:00:00 轉(zhuǎn)換為 unix 時間綴(絕對時間),再插入數(shù)據(jù)庫試試?
如下,使用 linux 的 date 命令轉(zhuǎn)換時間串為 unix 時間綴:

$  date  --date= 2020-02-23 08:00:00 +08:00  +%s
1582416000

然后用 mysql 的 () 函數(shù),將 unix 時間綴轉(zhuǎn)換為 mysql 時間類型來插入數(shù)據(jù)。

如上,查詢出來的時間,也是東 9 區(qū)的 9 點,時間也是正確的。

為什么網(wǎng)上又說 timestamp 類型存在時區(qū)問題?

我發(fā)現(xiàn)網(wǎng)上說 timestamp 有時區(qū)問題,都是應(yīng)用端插入數(shù)據(jù),然后到數(shù)據(jù)庫中去看,結(jié)果發(fā)現(xiàn)時間不一樣,因此我打算在 Java 中寫個 Demo 試一下,看能不能重現(xiàn)這個問題。

1、首先,下面是 Java 中 Entity 的定義,與上面的 time_test 表對應(yīng),注意,這里面時間屬性都是用 Date 類型定義的,如下:

2、然后,我寫了兩個接口 /insert 與 /queryAll 來插入與查詢數(shù)據(jù),如下:

3、然后我把數(shù)據(jù)庫的時區(qū)設(shè)置為 +09:00 時區(qū),即日本的東 9 區(qū),如下:

4、然后調(diào)用 /insert 接口插入數(shù)據(jù),注意我接口傳入的時間是東 8 區(qū)的 8 點,如下:

5、插入完后,去數(shù)據(jù)庫中查詢一把,如下:

可以看到,time_stamp 字段時間是 9 點,且我已將數(shù)據(jù)庫時區(qū)設(shè)置為東 9 區(qū),東 9 區(qū)的 9 點與東 8 區(qū)的 8 點,這兩個時間實際是相等的,因此時間數(shù)據(jù)沒錯。

6、然后我使用 /queryAll 接口將數(shù)據(jù)查詢出來,如下:

mysql 的 timestamp 存在的時區(qū)問題怎么解決

timeStamp 屬性是 1582416000000,這是毫秒級的時間綴,秒級則是 1582416000,對應(yīng)是東 8 區(qū)的 2020-02-23 08:00:00,時間數(shù)據(jù)也沒錯!

7、然后我又將 mysql 時區(qū)修改回 +8:00,并重啟我們的 java 應(yīng)用,如下:

mysql 的 timestamp 存在的時區(qū)問題怎么解決

8、再查詢一下數(shù)據(jù),如下:

mysql 的 timestamp 存在的時區(qū)問題怎么解決

timeStamp 屬性還是 1582416000000,時間沒有變化,這也是正確的。

那為什么網(wǎng)上會說 timestamp 存在時區(qū)問題?

經(jīng)過一翻查看,我發(fā)現(xiàn)他們都提到了 jdbc 的 serverTimezone,會不會是這個配置錯誤導(dǎo)致的呢?就先試試吧!
1、如圖,我把數(shù)據(jù)庫時區(qū)修改回 +9:00 時區(qū),然后故意把 jdbc 的 url 上的 serverTimezone 配置為與數(shù)據(jù)庫不一致的 GMT+ 8 時區(qū),然后重啟 java 應(yīng)用,如下:

mysql 的 timestamp 存在的時區(qū)問題怎么解決

url: jdbc:mysql://localhost:3306/testdb?serverTimezone=GMT%2B8 useUnicode=true characterEncoding=utf8

其中 GMT%2B8 就是 GMT+8,因為在 url 上需要 urlencode,所以就變成了 GMT%2B8。

2、重新插入數(shù)據(jù),注意插入的時間還是東 8 區(qū)的 8 點,如下:

mysql 的 timestamp 存在的時區(qū)問題怎么解決

3、然后,我再到數(shù)據(jù)庫中查詢一把,如下:

mysql 的 timestamp 存在的時區(qū)問題怎么解決

time_stamp 中時間竟然是 8 點!要知道我們雖然插入的是東 8 區(qū)的 8 點,但當(dāng)前會話可是東 9 區(qū)的,東 8 區(qū)的 8 點等于東 9 區(qū)的 9 點,所以正確顯示應(yīng)該為 9 點才對,時間差了 1 小時!

4、然后,我又調(diào)用 /queryAll 接口查詢了一把,想看看 mybatis 查詢出來的時間數(shù)據(jù)對不對,如下:

mysql 的 timestamp 存在的時區(qū)問題怎么解決

可以看到 timeStamp 是 1582416000000,秒級是 1582416000,這個時間就是東 8 區(qū)的 8 點,東 9 區(qū)的 9 點啊!查詢出來的時間竟然是正確的,為什么???

serverTimezone 的本質(zhì)

為了找出問題所在,我調(diào)試了一下 mysql 的 jdbc 驅(qū)動代碼,終于弄明白了原因,主要可以看看如下這幾點:

1.mysql 驅(qū)動創(chuàng)建連接后,會調(diào)用 com.mysql.jdbc.ConnectionImpl#configureTimezone()來配置此連接的時區(qū),如果配置了 serverTimezone,則會使用 serverTimezone 配置的時區(qū),沒配置時會去取數(shù)據(jù)庫中的 time_zone 變量,這就是為什么我們沒有配置 serverTimezone 變量時,結(jié)果也是正確的。

// 若使用普通驅(qū)動,使用此方法配置 mysql 連接的時區(qū)
com.mysql.jdbc.ConnectionImpl#configureTimezone()
// 若使用 cj 驅(qū)動,使用此方法配置 mysql 連接的時區(qū)
com.mysql.cj.protocol.a.NativeProtocol#configureTimezone()

2. 調(diào)用 jdbc 的 setTimestamp()方法時,實際調(diào)用的是 com.mysql.cj.jdbc.ClientPreparedStatement#setTimestamp(),這里面會根據(jù) serverTimezone 指定的時區(qū),將對應(yīng)的 Timestamp 對象轉(zhuǎn)換為 serverTimezone 指定時區(qū)的本地時間字符串。

3. 執(zhí)行 sql 語句時,會執(zhí)行 com.mysql.cj.jdbc.ClientPreparedStatement#execute(),這里面 sendPacket 變量保存著真實會發(fā)送到 mysql 的 sql 語句。

注:看的是 8.0.11 版本 mysql-connector-java 驅(qū)動源碼,不同版本代碼會稍有差異,比如 5.2.16 版本驅(qū)動,jdbc url 上需要同時配置這兩個配置:useTimezone=true serverTimezone=GMT%2B8,且 setTimestamp()對應(yīng)的是 com.mysql.jdbc.PreparedStatement#setTimestampInternal 方法。

原理總結(jié)如下:
mysql 驅(qū)動在發(fā)送 sql 前,會將 jdbc 中的 Date 對象參數(shù),根據(jù) serverTimeZone 配置的時區(qū)轉(zhuǎn)化為日期字符串后,再發(fā)送 sql 請求給 mysql server,同樣在 mysql server 返回查詢結(jié)果后,結(jié)果中的日期值也是日期字符串,mysql 驅(qū)動會根據(jù) serverTimeZone 配置的時區(qū),將日期字符串轉(zhuǎn)化為 Date 對象。

因此,當(dāng) serverTimeZone 與數(shù)據(jù)庫實際時區(qū)不一致時,會發(fā)生時區(qū)轉(zhuǎn)換錯誤,導(dǎo)致時間偏差,如下:
a、比如 sql 參數(shù)是一個 Date 對象,時間值是東 8 區(qū)的 2020-02-23 08:00:00,注意它里面存儲的可不是 2020-02-23 08:00:00 這個字符串,它是 Date 對象(絕對時間),只是我用文字表達(dá)出來是東 8 區(qū)的 2020-02-23 08:00:00。
b、然后,由于 serverTimeZone 配置的是東 8 區(qū),mysql 驅(qū)動會將這個 Date 對象轉(zhuǎn)為 2020-02-23 08:00:00,注意這時已經(jīng)是字符串了,然后再將 sql 發(fā)送給 mysql,注意這里的 sql 里面已經(jīng)將 Date 參數(shù)替換為 2020-02-23 08:00:00 了,因為 Date 對象本身是無法走網(wǎng)絡(luò)的。
c、然后 mysql 數(shù)據(jù)庫接收到這個時間字符串 2020-02-23 08:00:00 后,由于數(shù)據(jù)庫時區(qū)配置是東 9 區(qū),它會認(rèn)為這個時間是東 9 區(qū)的,它會以東 9 區(qū)解析這個時間字符串,這時數(shù)據(jù)庫保存的時間是東 9 區(qū)的 2020-02-23 08:00:00,也就是東 8 區(qū)的 2020-02-23 07:00:00,保存的時間就偏差了 1 個小時。
d、查詢結(jié)果里時間為什么又對了呢,因為查詢結(jié)果返回了東 9 區(qū)的時間字符串,而 java 應(yīng)用又將其理解為是東 8 區(qū)的時間,負(fù)負(fù)得正了!

將 serverTimezone 與 mysql 時區(qū)保持一致

so,那么如果我們將 serverTimezone 配置改正確,即與數(shù)據(jù)庫保持一致時,應(yīng)該查詢到的時間就會是錯的,會少 1 個小時。

1、jdbc url 中使用與數(shù)據(jù)庫一樣的東 9 區(qū) GMT+9,如下:

url: jdbc:mysql://localhost:3306/testdb?serverTimezone=GMT%2B9 useUnicode=true characterEncoding=utf8

其中的 GMT%2B9,即是 GMT+9。

2、然后重啟 Java 應(yīng)用,再查詢一把看看,如下:

mysql 的 timestamp 存在的時區(qū)問題怎么解決

返回的是毫秒級時間綴 1582412400000,秒級就是 1582412400,使用 linux 的 date 命令轉(zhuǎn)換為時間字符串形式:

$  date  --date= @1582412400  + %F %T %z 
2020-02-23 07:00:00 +0800

看到?jīng)],它是東 8 區(qū)的 7 點,剛好差了 1 個小時。

3、所以,使用 mysql 的 timestamp 類型時,對于 java 應(yīng)用來說,一定要保證 jdbc url 中的 serverTimezone 與數(shù)據(jù)庫中的時區(qū)配置是一致的。
另外一點是,當(dāng)沒有配置 serverTimezone 時,mysql 驅(qū)動會自動讀取 mysql server 中配置的時區(qū),這里面也有坑!如下:

mysql 驅(qū)動自動讀取數(shù)據(jù)庫時區(qū)的坑

3.1 mysql 安裝好后,默認(rèn)時區(qū)是 SYSTEM,而 SYSTEM 指的是 system_time_zone 變量的時區(qū),如下:

mysql 的 timestamp 存在的時區(qū)問題怎么解決

3.2 當(dāng) mysql 驅(qū)動讀到 time_zone 變量是 SYSTEM 時,會再去讀取 system_time_zone 變量,而 system_time_zone 對于國內(nèi)來說,默認(rèn)是 CST,這是一個混亂的時區(qū),是 4 個不同時區(qū)的縮寫,如下:

mysql 的 timestamp 存在的時區(qū)問題怎么解決

對于 Linux 或 MySQL,會認(rèn)為 CST 是中國標(biāo)準(zhǔn)時間 (+8:00),但 Java 卻認(rèn)為 CST 是美國標(biāo)準(zhǔn)時間(-6:00)(注:可能和 Java 運行在 Windows 中有關(guān)):
如下,linux 中 CST 等于 +0800,即中國時區(qū):

$  date  + %F %T %Z %z 
2021-09-12 18:35:49 CST +0800

如下,java 中 CST 等于 -06:00,美國時區(qū):

mysql 的 timestamp 存在的時區(qū)問題怎么解決

3.3 因此 mysql 驅(qū)動取到 CST 這個時區(qū)值時,它會以為這是 -6:00 時區(qū),但 MySQL 卻理解為 +8:00 時區(qū),因此 MySQL 時區(qū)一定不要配置為 CST,而要配置為具體的時區(qū),如 +8:00,但如果 MySQL 時區(qū)為 CST 且不可修改的情況下,一定要配置 jdbc 的 serverTimezone 為清晰的時區(qū)(如:GMT+8)。

Entity 中日期屬性是 String 呢?

1、我們將 Entity 對象中的時間屬性改為 String(不推薦),如下:

mysql 的 timestamp 存在的時區(qū)問題怎么解決

2、然后也寫兩個接口,/insert2 與 /queryAll2,如下:

mysql 的 timestamp 存在的時區(qū)問題怎么解決

3、然后插入數(shù)據(jù),注意這時我是直接將無時區(qū)的 8 點,作為參數(shù)給到 sql 的,如下:

mysql 的 timestamp 存在的時區(qū)問題怎么解決

4、然后再查詢一把,如下:

mysql 的 timestamp 存在的時區(qū)問題怎么解決

如上所示,time_stamp 字段值是 8 點,但此時數(shù)據(jù)庫時區(qū)是東 9 區(qū),所以這是東 9 區(qū)的 8 點。
5、然后我將數(shù)據(jù)庫與 jdbc 中 serverTimezone 都改為東 8 區(qū)呢,改完后重啟 Java 應(yīng)用,如下:

mysql 的 timestamp 存在的時區(qū)問題怎么解決

url: jdbc:mysql://localhost:3306/testdb?serverTimezone=GMT%2B8 useUnicode=true characterEncoding=utf8

6、再次插入數(shù)據(jù),參數(shù)還是無時區(qū)的 8 點,如下:

mysql 的 timestamp 存在的時區(qū)問題怎么解決

7、再查詢一把,如下:

mysql 的 timestamp 存在的時區(qū)問題怎么解決

如上所示,time_stamp 字段值是 8 點,但現(xiàn)在數(shù)據(jù)庫時間是東 8 區(qū),所以這是東 8 區(qū)的 8 點。
8、然后我再將 jdbc url 上的 serverTimezone 調(diào)整為東 9 區(qū),然后重啟 Java 應(yīng)用,如下:

url: jdbc:mysql://localhost:3306/testdb?serverTimezone=GMT%2B9 useUnicode=true characterEncoding=utf8

現(xiàn)在 serverTimezone 與數(shù)據(jù)庫中不一致,數(shù)據(jù)庫是東 8 區(qū),serverTimezone 是東 9 區(qū)。
9、我們再次插入無時區(qū)的 8 點,如下:

mysql 的 timestamp 存在的時區(qū)問題怎么解決

10、然后再查詢一把,如下:

mysql 的 timestamp 存在的時區(qū)問題怎么解決

time_stamp 字段值還是 8 點,數(shù)據(jù)庫是東 8 區(qū),所以這是東 8 區(qū)的 8 點,但我們 serverTimezone 與數(shù)據(jù)庫的時區(qū)不一致啊,沒看到時間有偏差,為什么?

解釋一下
前面說過了,對于 jdbc 中的 Date 對象,在發(fā)送給 mysql 前,會先根據(jù) serverTimezone 轉(zhuǎn)換為相應(yīng)時區(qū)的時間字符串,但現(xiàn)在 Entity 中時間屬性是 String 類型,mysql 驅(qū)動不會進(jìn)行轉(zhuǎn)換,所以不管 serverTimezone 怎么配置,對 String 類型的時間串都沒影響。

這樣的話,似乎 java 中日期類型用時間字符串來存還好些,不容易出錯,但請再認(rèn)真考慮一下,調(diào)用方傳了一個無時區(qū)的 8 點,數(shù)據(jù)庫自作主張,就將其認(rèn)為是東 9 區(qū)的 8 點,但如果這個時間字符串實際是東 8 區(qū)的 8 點呢?這時如果保存到數(shù)據(jù)庫中為東 9 區(qū)的 8 點,那數(shù)據(jù)就存錯了!

那如果目前 api 接口就傳的無時區(qū)的時間串,Entity 中就定義的 String,怎么解決呢?
1、詢問接口定義人員,這個接口的時間串指的是哪個時區(qū)的,比如是東 8 區(qū)的 2020-02-23 08:00:00。
2、然后接口接收到時間后,要以東 8 區(qū)將時間字符串轉(zhuǎn)換為 Date 對象,如下:

SimpleDateFormat sdf = new SimpleDateFormat( yyyy-MM-dd HH:mm:ss 
sdf.setTimeZone(TimeZone.getTimeZone( GMT+8));
Date date = sdf.parse(2020-02-23 08:00:00

3、然后如果 Entity 中時間屬性定義的是 String,那么我們要再將 Date 對象以數(shù)據(jù)庫的時區(qū)格式化為對應(yīng)的時間字符串,比如數(shù)據(jù)庫時區(qū)是東 9 區(qū),那么格式化后就是 2020-02-23 09:00:00,如下:

SimpleDateFormat sdf = new SimpleDateFormat( yyyy-MM-dd HH:mm:ss 
sdf.setTimeZone(TimeZone.getTimeZone( GMT+9));
String dateStr = sdf.format(date);
entity.setTimeStamp(dateStr);

4、然后將 Entity 保存到 mysql 中的,就也會是東 9 區(qū)的 2020-02-23 09:00:00,結(jié)果正確。

所以,使用 String 類型來存儲時間數(shù)據(jù),要想將時間值保存正確,超級麻煩,不建議在實際開發(fā)中這種使用。

最佳實踐

1、大多數(shù)團(tuán)隊會規(guī)定 api 中傳遞時間要用 unix 時間綴,因為如果你傳一個 2020-02-23 08:00:00 時間值,它到底是哪個時區(qū)的 8 點呢?對于 unix 時間綴,就不會有此問題,因為它是絕對時間。而如果某些特殊原因,一定要使用時間字符串,最好使用 ISO8601 規(guī)范那種帶時區(qū)的時間串,比如:2020-02-23T08:00:00+08:00。

2、Mybatis 中 Entity 定義要與數(shù)據(jù)庫定義一致,數(shù)據(jù)庫中是 timestamp,那么 Entity 中要定義為 Date 對象,因為 mysql 驅(qū)動在執(zhí)行 sql 時,會自動根據(jù) serverTimezone 配置幫你轉(zhuǎn)換為數(shù)據(jù)庫時區(qū)的時間串,如果你自己來轉(zhuǎn)換,你極有可能因為忘記調(diào)用 setTimeZone()方法,而使用當(dāng)前 java 應(yīng)用所在機(jī)器的默認(rèn)時區(qū),一旦 java 應(yīng)用所在機(jī)器的時區(qū)與數(shù)據(jù)庫的時區(qū)不一致,就會出現(xiàn)時區(qū)問題。

3、jdbc 的 serverTimezone 參數(shù),要配置正確,當(dāng)不配置時,mysql 驅(qū)動會自動讀取 mysql server 的時區(qū),此時一定要將 mysql server 的時區(qū)指定為清晰的時區(qū)(如:+08:00),切勿使用 CST。

4、如果數(shù)據(jù)庫時區(qū)修改后,jdbc 的 serverTimezone 也要跟著修改,并重啟 Java 應(yīng)用,就算沒有配置 serverTimezone,也需要重啟,因為 mysql 驅(qū)動初始化連接時,會將當(dāng)前數(shù)據(jù)庫時區(qū)緩存到一個 java 變量中,不重啟 Java 應(yīng)用它不會變。

數(shù)據(jù)庫中用 timestamp 還是 int 來存儲時間?

如果用 int 型時間綴存儲,不管數(shù)據(jù)庫時區(qū)是啥,都不影響,因為存儲的是絕對時間,看起來完美解決了時區(qū)問題。
但從某些角度看,這種方案只是把時區(qū)問題從數(shù)據(jù)庫端推到應(yīng)用端去了,時區(qū)問題將出現(xiàn)在將時間字符串轉(zhuǎn)換為時間綴的過程中,比如某程序員從 api 接口中拿到時間字符串后,沒考慮時區(qū),直接轉(zhuǎn)為 unix 時間綴,就可能出現(xiàn)時區(qū)問題。
因此,對于不帶時區(qū)的時間串解析,一定要問清楚這是哪個時區(qū)的時間,并在代碼中顯式指定!

另外,用 int 存儲時間還有如下 3 個不好的點:

開發(fā)人員看到這個字段后,無法一目了然的了解到這個時間綴大概是個什么時間,需要去轉(zhuǎn)換一下,會很繁瑣。像 update_time 這樣的字段,數(shù)據(jù)庫提供了 DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP 的機(jī)制,這樣在更新任何字段時,update_time 會自動更新,而如果使用 int 存儲,就需要程序員每次更新表時,重新 set 這個字段,容易遺忘。由于 int 只有 4 個字節(jié),用它來存儲時間,會在 2038 年后溢出,而對于 timestamp 來說,MySQL 將其底層存儲統(tǒng)一修改為 8 個字節(jié),相對來說還是比較容易的。當(dāng)然,也并不是建議不用 int,這是見仁見智的,不管用 timestamp 還是 int,都沒有致命性問題的。

感謝各位的閱讀,以上就是“mysql 的 timestamp 存在的時區(qū)問題怎么解決”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對 mysql 的 timestamp 存在的時區(qū)問題怎么解決這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是丸趣 TV,丸趣 TV 小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

正文完
 
丸趣
版權(quán)聲明:本站原創(chuàng)文章,由 丸趣 2023-07-13發(fā)表,共計8997字。
轉(zhuǎn)載說明:除特殊說明外本站除技術(shù)相關(guān)以外文章皆由網(wǎng)絡(luò)搜集發(fā)布,轉(zhuǎn)載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 嘉善县| 五指山市| 新蔡县| 齐齐哈尔市| 玛曲县| 高雄市| 河源市| 揭阳市| 二手房| 施秉县| 肥东县| 白玉县| 乌拉特前旗| 疏附县| 新安县| 墨玉县| 潼南县| 榆社县| 满洲里市| 邹城市| 米林县| 伽师县| 平安县| 达尔| 朔州市| 达拉特旗| 平陆县| 鲜城| 大邑县| 荔浦县| 古蔺县| 万年县| 五大连池市| 金湖县| 迭部县| 荣成市| 沁源县| 辰溪县| 拜城县| 宜丰县| 荃湾区|