最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

關(guān)于MySQL日期類型的選擇建議

 更新時(shí)間:2024年10月24日 10:30:30   作者:遠(yuǎn)坂凜_  
在軟件開(kāi)發(fā)中,時(shí)間記錄是不可或缺的功能,如記錄操作時(shí)間、交易時(shí)間等,通常不建議使用字符串存儲(chǔ)日期,因?yàn)樗加每臻g大,并且效率低下,MySQL提供的Datetime和Timestamp是常用的時(shí)間存儲(chǔ)類型,Datetime沒(méi)有時(shí)區(qū)信息,而Timestamp與時(shí)區(qū)有關(guān)

MySQL日期類型的選擇

我們平時(shí)開(kāi)發(fā)中不可避免的就是要存儲(chǔ)時(shí)間,比如我們要記錄操作表中這條記錄的時(shí)間、記錄轉(zhuǎn)賬的交易時(shí)間、記錄出發(fā)時(shí)間、用戶下單時(shí)間等等。

你會(huì)發(fā)現(xiàn)時(shí)間這個(gè)東西與我們開(kāi)發(fā)的聯(lián)系還是非常緊密的,用的好與不好會(huì)給我們的業(yè)務(wù)甚至功能帶來(lái)很大的影響。所以,我們有必要重新出發(fā),好好認(rèn)識(shí)一下這個(gè)東西。

不要用字符串存儲(chǔ)日期

和絕大部分對(duì)數(shù)據(jù)庫(kù)不太了解的新手一樣,我在大學(xué)的時(shí)候就這樣干過(guò),甚至認(rèn)為這樣是一個(gè)不錯(cuò)的表示日期的方法。畢竟簡(jiǎn)單直白,容易上手。

但是,這是不正確的做法,主要會(huì)有下面兩個(gè)問(wèn)題:

  1. 字符串占用的空間更大!
  2. 字符串存儲(chǔ)的日期效率比較低(逐個(gè)字符進(jìn)行比對(duì)),無(wú)法用日期相關(guān)的 API 進(jìn)行計(jì)算和比較。

Datetime 和 Timestamp 之間的抉擇

Datetime 和 Timestamp 是 MySQL 提供的兩種比較相似的保存時(shí)間的數(shù)據(jù)類型,可以精確到秒。他們兩者究竟該如何選擇呢?

下面我們來(lái)簡(jiǎn)單對(duì)比一下二者。

時(shí)區(qū)信息

DateTime 類型是沒(méi)有時(shí)區(qū)信息的(時(shí)區(qū)無(wú)關(guān)) ,DateTime 類型保存的時(shí)間都是當(dāng)前會(huì)話所設(shè)置的時(shí)區(qū)對(duì)應(yīng)的時(shí)間。這樣就會(huì)有什么問(wèn)題呢?當(dāng)你的時(shí)區(qū)更換之后,比如你的服務(wù)器更換地址或者更換客戶端連接時(shí)區(qū)設(shè)置的話,就會(huì)導(dǎo)致你從數(shù)據(jù)庫(kù)中讀出的時(shí)間錯(cuò)誤。

Timestamp 和時(shí)區(qū)有關(guān)。Timestamp 類型字段的值會(huì)隨著服務(wù)器時(shí)區(qū)的變化而變化,自動(dòng)換算成相應(yīng)的時(shí)間,說(shuō)簡(jiǎn)單點(diǎn)就是在不同時(shí)區(qū),查詢到同一個(gè)條記錄此字段的值會(huì)不一樣。

下面實(shí)際演示一下!

建表 SQL 語(yǔ)句:

CREATE TABLE `time_zone_test` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `date_time` datetime DEFAULT NULL,
  `time_stamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

插入數(shù)據(jù):

INSERT INTO time_zone_test(date_time,time_stamp) VALUES(NOW(),NOW());

查看數(shù)據(jù):

select date_time,time_stamp from time_zone_test;

結(jié)果:

+---------------------+---------------------+
| date_time           | time_stamp          |
+---------------------+---------------------+
| 2020-01-11 09:53:32 | 2020-01-11 09:53:32 |
+---------------------+---------------------+

現(xiàn)在我們運(yùn)行

修改當(dāng)前會(huì)話的時(shí)區(qū):

set time_zone='+8:00';

再次查看數(shù)據(jù):

+---------------------+---------------------+
| date_time           | time_stamp          |
+---------------------+---------------------+
| 2020-01-11 09:53:32 | 2020-01-11 17:53:32 |
+---------------------+---------------------+

擴(kuò)展:一些關(guān)于 MySQL 時(shí)區(qū)設(shè)置的一個(gè)常用 sql 命令

# 查看當(dāng)前會(huì)話時(shí)區(qū)
SELECT @@session.time_zone;
# 設(shè)置當(dāng)前會(huì)話時(shí)區(qū)
SET time_zone = 'Europe/Helsinki';
SET time_zone = "+00:00";
# 數(shù)據(jù)庫(kù)全局時(shí)區(qū)設(shè)置
SELECT @@global.time_zone;
# 設(shè)置全局時(shí)區(qū)
SET GLOBAL time_zone = '+8:00';
SET GLOBAL time_zone = 'Europe/Helsinki';

占用空間

下圖是 MySQL 日期類型所占的存儲(chǔ)空間

在 MySQL 5.6.4 之前,DateTime 和 Timestamp 的存儲(chǔ)空間是固定的,分別為 8 字節(jié)和 4 字節(jié)。

但是從 MySQL 5.6.4 開(kāi)始,它們的存儲(chǔ)空間會(huì)根據(jù)毫秒精度的不同而變化,DateTime 的范圍是 5~8 字節(jié),Timestamp 的范圍是 4~7 字節(jié)。

表示范圍

Timestamp 表示的時(shí)間范圍更小,只能到 2038 年:

  • DateTime:1000-01-01 00:00:00.000000 ~ 9999-12-31 23:59:59.499999
  • Timestamp:1970-01-01 00:00:01.000000 ~ 2038-01-19 03:14:07.499999

性能

由于 TIMESTAMP 需要根據(jù)時(shí)區(qū)進(jìn)行轉(zhuǎn)換,所以從毫秒數(shù)轉(zhuǎn)換到 TIMESTAMP 時(shí),不僅要調(diào)用一個(gè)簡(jiǎn)單的函數(shù),還要調(diào)用操作系統(tǒng)底層的系統(tǒng)函數(shù)。

這個(gè)系統(tǒng)函數(shù)為了保證操作系統(tǒng)時(shí)區(qū)的一致性,需要進(jìn)行加鎖操作,這就降低了效率。

DATETIME 不涉及時(shí)區(qū)轉(zhuǎn)換,所以不會(huì)有這個(gè)問(wèn)題。

為了避免 TIMESTAMP 的時(shí)區(qū)轉(zhuǎn)換問(wèn)題,建議使用指定的時(shí)區(qū),而不是依賴于操作系統(tǒng)時(shí)區(qū)。

數(shù)值時(shí)間戳是更好的選擇嗎?

很多時(shí)候,我們也會(huì)使用 int 或者 bigint 類型的數(shù)值也就是數(shù)值時(shí)間戳來(lái)表示時(shí)間。

這種存儲(chǔ)方式的具有 Timestamp 類型的所具有一些優(yōu)點(diǎn),并且使用它的進(jìn)行日期排序以及對(duì)比等操作的效率會(huì)更高,跨系統(tǒng)也很方便,畢竟只是存放的數(shù)值。

缺點(diǎn)也很明顯,就是數(shù)據(jù)的可讀性太差了,你無(wú)法直觀的看到具體時(shí)間。

時(shí)間戳的定義如下:

  • 時(shí)間戳的定義是從一個(gè)基準(zhǔn)時(shí)間開(kāi)始算起,這個(gè)基準(zhǔn)時(shí)間是「1970-1-1 00:00:00 +0:00」,從這個(gè)時(shí)間開(kāi)始,用整數(shù)表示,以秒計(jì)時(shí),隨著時(shí)間的流逝這個(gè)時(shí)間整數(shù)不斷增加。
  • 這樣一來(lái),我只需要一個(gè)數(shù)值,就可以完美地表示時(shí)間了,而且這個(gè)數(shù)值是一個(gè)絕對(duì)數(shù)值,即無(wú)論的身處地球的任何角落,這個(gè)表示時(shí)間的時(shí)間戳,都是一樣的,生成的數(shù)值都是一樣的,并且沒(méi)有時(shí)區(qū)的概念,所以在系統(tǒng)的中時(shí)間的傳輸中,都不需要進(jìn)行額外的轉(zhuǎn)換了,只有在顯示給用戶的時(shí)候,才轉(zhuǎn)換為字符串格式的本地時(shí)間。

數(shù)據(jù)庫(kù)中實(shí)際操作:

mysql> select UNIX_TIMESTAMP('2020-01-11 09:53:32');
+---------------------------------------+
| UNIX_TIMESTAMP('2020-01-11 09:53:32') |
+---------------------------------------+
|                            1578707612 |
+---------------------------------------+
1 row in set (0.00 sec)

mysql> select FROM_UNIXTIME(1578707612);
+---------------------------+
| FROM_UNIXTIME(1578707612) |
+---------------------------+
| 2020-01-11 09:53:32       |
+---------------------------+
1 row in set (0.01 sec)

總結(jié)

MySQL 中時(shí)間到底怎么存儲(chǔ)才好?Datetime?Timestamp?還是數(shù)值時(shí)間戳?

并沒(méi)有一個(gè)銀彈,很多程序員會(huì)覺(jué)得數(shù)值型時(shí)間戳是真的好,效率又高還各種兼容,但是很多人又覺(jué)得它表現(xiàn)的不夠直觀。

每種方式都有各自的優(yōu)勢(shì),根據(jù)實(shí)際場(chǎng)景選擇最合適的才是王道。

下面再對(duì)這三種方式做一個(gè)簡(jiǎn)單的對(duì)比,以供大家實(shí)際開(kāi)發(fā)中選擇正確的存放時(shí)間的數(shù)據(jù)類型:

類型存儲(chǔ)空間日期格式日期范圍是否帶時(shí)區(qū)信息
DATETIME5~8 字節(jié)YYYY-MM-DD hh:mm:ss[.fraction]1000-01-01 00:00:00[.000000] ~ 9999-12-31 23:59:59[.999999]
TIMESTAMP4~7 字節(jié)YYYY-MM-DD hh:mm:ss[.fraction]1970-01-01 00:00:01[.000000] ~ 2038-01-19 03:14:07[.999999]
數(shù)值型時(shí)間戳4 字節(jié)全數(shù)字如 15787076121970-01-01 00:00:01 之后的時(shí)間

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • MySQL壓測(cè)神器HammerDB的部署及使用詳解

    MySQL壓測(cè)神器HammerDB的部署及使用詳解

    HammerDB?是一個(gè)開(kāi)源的數(shù)據(jù)庫(kù)負(fù)載測(cè)試和基準(zhǔn)測(cè)試工具,同時(shí)支持?Windows?和?Linux?平臺(tái),這篇文章主要介紹了MySQL壓測(cè)神器HammerDB的部署及使用,需要的朋友可以參考下
    2022-08-08
  • MYSQL多表聯(lián)查on和where的區(qū)別小結(jié)

    MYSQL多表聯(lián)查on和where的區(qū)別小結(jié)

    在使用left join時(shí)過(guò)濾條件放到on后面還是where后面是有區(qū)別的,如果沒(méi)有搞清楚他們的區(qū)別,連表匯總的結(jié)果就會(huì)變少或者變多,本文就來(lái)詳細(xì)介紹一下兩者的區(qū)別,感興趣的可以了解一下
    2023-11-11
  • MySQL 鎖機(jī)制全解析從鎖的分類到并發(fā)更新是否阻塞(最新推薦)

    MySQL 鎖機(jī)制全解析從鎖的分類到并發(fā)更新是否阻塞(最新推薦)

    本文介紹了MySQL的鎖機(jī)制,包括全局鎖、表鎖和行鎖,并詳細(xì)分析了這些鎖在并發(fā)場(chǎng)景下的表現(xiàn)和影響,感興趣的朋友跟隨小編一起看看吧
    2025-12-12
  • 基于proxysql實(shí)現(xiàn)MySQL讀寫分離的實(shí)現(xiàn)實(shí)例

    基于proxysql實(shí)現(xiàn)MySQL讀寫分離的實(shí)現(xiàn)實(shí)例

    這篇文章主要介紹了基于proxysql實(shí)現(xiàn)MySQL讀寫分離,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-11-11
  • Mysql 如何查詢時(shí)間段交集

    Mysql 如何查詢時(shí)間段交集

    這篇文章主要介紹了Mysql 查詢時(shí)間段交集的方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • 在SQL中對(duì)同一個(gè)字段不同值,進(jìn)行數(shù)據(jù)統(tǒng)計(jì)操作

    在SQL中對(duì)同一個(gè)字段不同值,進(jìn)行數(shù)據(jù)統(tǒng)計(jì)操作

    這篇文章主要介紹了在SQL中對(duì)同一個(gè)字段不同值,進(jìn)行數(shù)據(jù)統(tǒng)計(jì)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-10-10
  • MySQL定義異常和異常處理詳解

    MySQL定義異常和異常處理詳解

    這篇文章主要為大家詳細(xì)介紹了MySQL定義異常和異常處理,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • MySQL子查詢的實(shí)現(xiàn)示例

    MySQL子查詢的實(shí)現(xiàn)示例

    MySQL中的子查詢是一個(gè)強(qiáng)大的功能,本文主要介紹了MySQL子查詢的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-08-08
  • Mysql數(shù)據(jù)庫(kù)存儲(chǔ)過(guò)程基本語(yǔ)法講解

    Mysql數(shù)據(jù)庫(kù)存儲(chǔ)過(guò)程基本語(yǔ)法講解

    本文通過(guò)一個(gè)實(shí)例來(lái)給大家講述一下Mysql數(shù)據(jù)庫(kù)存儲(chǔ)過(guò)程基本語(yǔ)法,希望你能喜歡。
    2017-11-11
  • MySQL查看日志簡(jiǎn)單易懂保姆級(jí)教程

    MySQL查看日志簡(jiǎn)單易懂保姆級(jí)教程

    這篇文章主要給大家介紹了關(guān)于MySQL查看日志簡(jiǎn)單易懂保姆級(jí)教程的相關(guān)資料,在操作MySQL數(shù)據(jù)庫(kù)的時(shí)候會(huì)留下每一個(gè)步驟的痕跡,那怎么查看呢?就可以用日志去查看,需要的朋友可以參考下
    2023-08-08

最新評(píng)論

和龙市| 兴城市| 东乌珠穆沁旗| 璧山县| 蒲江县| 安达市| 观塘区| 德庆县| 廉江市| 梓潼县| 东乡| 上思县| 滁州市| 怀化市| 文昌市| 南阳市| 成武县| 从化市| 光泽县| 鸡东县| 霍林郭勒市| 洪雅县| 阿拉善右旗| 广丰县| 东至县| 礼泉县| 方山县| 沙湾县| 石城县| 高邑县| 资中县| 溧阳市| 汉源县| 汝阳县| 甘肃省| 通江县| 安丘市| 佛坪县| 达孜县| 易门县| 霞浦县|