MySQL中時(shí)區(qū)參數(shù)time_zone解讀
前言
MySQL 時(shí)區(qū)參數(shù) time_zone 有什么用?修改它有什么影響?
如何設(shè)置該參數(shù),本篇文章會(huì)詳細(xì)介紹。
1.時(shí)區(qū)參數(shù)影響
time_zone 參數(shù)影響著 MySQL 系統(tǒng)函數(shù)還有字段的 DEFAULT CURRENT_TIMESTAMP 的屬性。
查詢(xún)當(dāng)前的時(shí)區(qū),+8:00 就代表國(guó)內(nèi)的時(shí)區(qū):
root@mysql 15:08: [(none)]>select @@time_zone; +-------------+ | @@time_zone | +-------------+ | +08:00 | +-------------+
查詢(xún)當(dāng)前時(shí)間:
root@mysql 15:09: [(none)]>select now(); +---------------------+ | now() | +---------------------+ | 2024-12-12 15:09:44 | +---------------------+
修改時(shí)區(qū),為 UTC -8:00 美國(guó)時(shí)間:
root@mysql 15:09: [(none)]>set global time_zone = '-08:00'; Query OK, 0 rows affected (0.00 sec)
查詢(xún)當(dāng)前時(shí)間:
root@mysql 15:09: [(none)]>select now(); +---------------------+ | now() | +---------------------+ | 2024-12-11 23:09:55 | +---------------------+
另外,需要注意的是 timestamp 類(lèi)型,會(huì)隨著 time_zone 的值產(chǎn)生變化,而 datetime 類(lèi)型則不會(huì),請(qǐng)看下方演示。
確認(rèn)當(dāng)前 time_zone 參數(shù)值:
select @@time_zone; +-------------+ | @@time_zone | +-------------+ | +08:00 | +-------------+
創(chuàng)建測(cè)試表結(jié)構(gòu),兩張表的區(qū)別是 created_at、updated_at 分別為 datetime 和 timestamp 類(lèi)型。
CREATE TABLE `api_datetime` ( `id` bigint(64) NOT NULL AUTO_INCREMENT, user varchar(10), `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間', `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時(shí)間', `enabled` bit(1) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8; CREATE TABLE `api_timestamp` ( `id` bigint(64) NOT NULL AUTO_INCREMENT, user varchar(10), `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間', `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時(shí)間', `enabled` bit(1) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;
模擬數(shù)據(jù)插入:
insert into api_timestamp(user, enabled) values ('+08:00', b'1');
insert into api_datetime(user, enabled) values ('+08:00', b'1');查詢(xún)表數(shù)據(jù):
root@mysql 16:21: [test]>select user,created_at, updated_at from api_datetime; +--------+---------------------+---------------------+ | user | created_at | updated_at | +--------+---------------------+---------------------+ | +08:00 | 2024-12-12 16:20:34 | 2024-12-12 16:20:34 | +--------+---------------------+---------------------+ 1 row in set (0.00 sec) root@mysql 16:21: [test]>select user,created_at, updated_at from api_timestamp; +--------+---------------------+---------------------+ | user | created_at | updated_at | +--------+---------------------+---------------------+ | +08:00 | 2024-12-12 16:20:33 | 2024-12-12 16:20:33 | +--------+---------------------+---------------------+
修改 time_zone 參數(shù)值,為 -8:00:
set global time_zone = '-8:00';
插入測(cè)試數(shù)據(jù):
insert into api_timestamp(user, enabled) values ('-08:00', b'1');
insert into api_datetime(user, enabled) values ('-08:00', b'1');root@mysql 16:25: [test]>select user,created_at, updated_at from api_datetime; +--------+---------------------+---------------------+ | user | created_at | updated_at | +--------+---------------------+---------------------+ | +08:00 | 2024-12-12 16:20:34 | 2024-12-12 16:20:34 | | -08:00 | 2024-12-12 00:25:52 | 2024-12-12 00:25:52 | +--------+---------------------+---------------------+ 2 rows in set (0.00 sec) root@mysql 16:25: [test]>select user,created_at, updated_at from api_timestamp; +--------+---------------------+---------------------+ | user | created_at | updated_at | +--------+---------------------+---------------------+ | +08:00 | 2024-12-12 00:20:33 | 2024-12-12 00:20:33 | | -08:00 | 2024-12-12 00:25:52 | 2024-12-12 00:25:52 | +--------+---------------------+---------------------+ 2 rows in set (0.00 sec)
由上方測(cè)試,我們發(fā)現(xiàn)如果字段設(shè)置為 CURRENT_TIMESTAMP 無(wú)論是 datetime 還是 timestamp 類(lèi)型,都會(huì)隨 time_zone 參數(shù)影響,不過(guò) datetime 類(lèi)型的歷史數(shù)據(jù)不會(huì)受影響,timestamp 類(lèi)型的歷史數(shù)據(jù),會(huì)隨著 time_zone 的調(diào)整而發(fā)生變化。
2.如何設(shè)置
推薦直接寫(xiě)在 MySQL 的配置文件中,需要重啟生效。
[mysqld] default-time-zone='+08:00'
該參數(shù)默認(rèn)為 SYSTEM 表示該參數(shù)值,取自操作系統(tǒng)的時(shí)區(qū)設(shè)置。不過(guò)還是建議在 MySQL 參數(shù)文件中設(shè)置一下,因?yàn)椴僮飨到y(tǒng)可能可能不完全歸 DBA 管理,萬(wàn)一有人突然調(diào)整了,可能會(huì)引起線(xiàn)上問(wèn)題。
另外,如果 time_zone 使用默認(rèn)的 system 值,表示默認(rèn)使用操作系統(tǒng)的時(shí)區(qū),則每次通過(guò)時(shí)區(qū)計(jì)算時(shí)間時(shí),要調(diào)用操作系統(tǒng)底層系統(tǒng)函數(shù) __tz_convert(),而這個(gè)函數(shù)需要額外的加鎖操作,以確保這時(shí)操作系統(tǒng)時(shí)區(qū)沒(méi)有修改。高并發(fā)的時(shí)候會(huì)導(dǎo)致 TIMESTAMP 類(lèi)型的表和操作,性能降低。
3.字段類(lèi)型選擇
業(yè)務(wù)中盡量使用 datetime 類(lèi)型來(lái)存儲(chǔ)時(shí)間,除了歷史數(shù)據(jù)不會(huì)隨著時(shí)區(qū)發(fā)生變化外,還有一個(gè)最大值限制問(wèn)題。
TIMESTAMP 存儲(chǔ)的是 1970-01-01 00:00:00’ 到現(xiàn)在的毫秒數(shù),TIMESTAMP 占用 4 個(gè)字節(jié),因此其存儲(chǔ)的時(shí)間上限只能到 2038-01-19 03:14:07 已經(jīng)離現(xiàn)在不遠(yuǎn)了,是需要重視的,業(yè)務(wù)又將面臨一次類(lèi)似千年蟲(chóng)的問(wèn)題。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
MySQL之修改數(shù)據(jù)表存儲(chǔ)引擎的三種方式
這篇文章主要介紹了MySQL之修改數(shù)據(jù)表存儲(chǔ)引擎的三種方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
insert...on?duplicate?key?update語(yǔ)法詳解
本文主要介紹了insert...on?duplicate?key?update語(yǔ)法詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01
使用MySQL的LAST_INSERT_ID來(lái)確定各分表的唯一ID值
MySQL數(shù)據(jù)表結(jié)構(gòu)中,一般情況下,都會(huì)定義一個(gè)具有‘AUTO_INCREMENT’擴(kuò)展屬性的‘ID’字段,以確保數(shù)據(jù)表的每一條記錄都可以用這個(gè)ID唯一確定2011-08-08
mysql分區(qū)表的增刪改查的實(shí)現(xiàn)示例
增刪查改在數(shù)據(jù)庫(kù)中是很常見(jiàn)的操作,本文主要介紹了mysql分區(qū)表的增刪改查的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-01-01
windows下mysql中binlog日志分析和數(shù)據(jù)恢復(fù)問(wèn)題
這篇文章主要介紹了windows下mysql中binlog日志分析和數(shù)據(jù)恢復(fù)問(wèn)題,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06
MYSQL數(shù)據(jù)庫(kù)Innodb?引擎mvcc鎖實(shí)現(xiàn)原理
這篇文章主要介紹了MYSQL數(shù)據(jù)庫(kù)Innodb?引擎mvcc鎖實(shí)現(xiàn)原理,但是mvcc?的實(shí)現(xiàn)原理是什么呢?下文我們就來(lái)實(shí)例說(shuō)明來(lái)mvcc?的實(shí)現(xiàn)原理,感興趣的小伙伴可以參考一下2022-05-05
在講MySQL的Join語(yǔ)法前還是先回顧一下聯(lián)結(jié)的語(yǔ)法,呵呵,其實(shí)連我自己都忘得差不多了,那就大家一起溫習(xí)吧,這里我有個(gè)比較簡(jiǎn)便的記憶方法,內(nèi)外聯(lián)結(jié)的區(qū)別是內(nèi)聯(lián)結(jié)將去除所有不符合條件的記錄,而外聯(lián)結(jié)則保留其中部分。外左聯(lián)結(jié)與外右聯(lián)結(jié)的區(qū)別在于如果用A左聯(lián)結(jié)B則A中所有記錄都會(huì)保留在結(jié)果中,此時(shí)B中只有符合聯(lián)結(jié)條件的記錄,而右聯(lián)結(jié)相反,這樣也就不會(huì)混淆了。2014-05-05

