MySQL日期和時間類型筆記

  • 2019 年 10 月 13 日
  • 筆記

最近在看《MySQL技術內幕:SQL編程》並做了筆記,這是一篇筆記類型部落格,分享出來方便自己複習,也可以幫助其他人

一、日期時間類型所佔空間對比

各種日期時間數據類型所佔的空間:

類型 所佔空間
DATETIME 8位元組
DATE 3位元組
TIMESTAMP 4位元組
YEAR 1位元組
TIME 3位元組

二、DATETIME和DATE對比

  • DATETIME佔用8位元組,既顯示了日期也顯示時間,可以表示的日期範圍為「1000-01-01 00:00:00」到「9999-12-31 23:59:59」
  • DATE佔用3位元組,只顯示日期,不顯示具體時間,可顯示的日期範圍為「1000-01-01」到「9999-12-31」

ok,這裡特意介紹一下TIMESTAMP秒的小數部分問題

備註:5.6.4+版本才支援秒的小數部分,之前版本是不支援的

# 查詢MySQL版本  select version();  # 建表驗證問題  create table t (a datetime);  # 寫數據秒後面加上小數  insert into t select '2019-10-11 17:16:12.55555';  # 查詢,發現並沒有查出秒之後的小數  select * from t ;  # 使用microsecond,讀取秒之後的小數  select microsecond('2019-10-11 17:16:12.55555') ;  # CAST讀取,驗證了5.7+版本查詢時候會出現四捨五入,如下sql得到2019-10-11 17:16:12,而低版本就不會  SELECT CAST('2019-10-11 17:16:12.5555' AS DATETIME) ;  # CAST讀取,5.7+版本查詢,四捨五入得到,2019-10-11 17:16:12,低版本正常顯示,具體哪個版本開始的不知道,我在5.7+版本驗證都是會出現四捨五入的情況  select cast('2019-10-11 17:16:12.1234' as datetime) ;  # 5.6.4+版本支援秒的小數部分  # 支援的類型有TIME、DATETIME、TIMESTAMP,寫法是type(size),size為小數部分精度,最大為6  # 刪表,再驗證一下  DROP TABLE t;  # 這裡指定精度  CREATE TABLE t (a DATETIME(4));  # 秒後加小數,寫數據  INSERT INTO t SELECT '2019-10-11 17:16:12.55555';  # 查詢,發現可以正常寫數據,不過精度只有4  SELECT * FROM t ;  

三、TIMESTAMP類型介紹

TIMESTAMP佔4個位元組,顯示的範圍為「1970-01-01」UTC 到 「2038-01-19 03:14:07」UTC
備註:UTC:協調世界時間、又稱世界統一時間、世界標準時間和國際協調時間

注意:

  • 更新表時,可以設置TIMESTAMP類型的列,自動更新時間為當前時間
  • 列為TIMESTAMP的日期類型可以設置一個默認值,而DATETIME不支援

例子,驗證一下,設置默認值和自動更新時間

# 新增一張表  CREATE TABLE t (    a INT,    b TIMESTAMP DEFAULT CURRENT_TIMESTAMP  ) ENGINE = INNODB ;  # 寫一條數據  INSERT INTO t (a) VALUES (1);  # 查詢,發現自動賦默認值時間  SELECT * FROM t;  

在這裡插入圖片描述

驗證自動更新時間問題

# 修改欄位為自動更新(數據有改變時候才會自動更新)  ALTER TABLE t MODIFY COLUMN b TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;  # 刪一下表數據  DELETE FROM t;  # 寫初始化數據  INSERT INTO t SELECT 1,CURRENT_TIMESTAMP;  # 查詢,先記錄下原來時間  SELECT * FROM t;  

在這裡插入圖片描述

  # 修改數據  UPDATE t SET a =2;  # 如果修改為1,是不會改變時間的  SELECT * FROM t;

在這裡插入圖片描述

四、YEAR和TIME類型對比

  • YEAR類型佔用1位元組,書中介紹定義時可以指定顯示的寬度為YEAR(2)或者YEAR(4),不過在我的mysql版本5.7+驗證,發現只能定義為YEAR或者YEAR(4),也就是新版是不支援YEAR(2)這種形式的
    對於YEAR(4),其顯示年份的範圍為1901~2155;然後超過這個範圍的話,mysql還可以寫,不過被賦值為0000
  • TIME類型只佔3位元組,顯示的範圍為「-838:59:59」~"838:59:59",TIME的小時是可以大於23也可以為負值的,因為time也可以用來保存時間間隔

五、日期時間函數

  • NOW、CURRENT_TIMESTAMP和SYSDATE函數

介紹一下MySQL比較常用的NOW、CURRENT_TIMESTAMP和SYSDATE函數

給個例子,用sleep函數,然後對比sleep函數執行前後,這幾個函數獲取的時間對比

SELECT NOW(),CURRENT_TIMESTAMP(),SYSDATE(),SLEEP(2),NOW(),CURRENT_TIMESTAMP(),SYSDATE();

在這裡插入圖片描述
從圖對比可知,NOW()其實就是CURRENT_TIMESTAMP()的近意函數,例子里使用了sleep(2),隔2秒繼續執行,可以對比得知,NOW、CURRENT_TIMESTAMP其實獲取的都是整條sql開始執行的時間,不管在sleep函數執行前後,而SYSDATE獲取的其實執行sysdate這個函數時候的時間,並非整條sql開始執行的時間,所以在sleep函數執行前後獲取的時間是不同的

  • DATE_ADD和DATE_SUB函數

DATE_ADD(date , INTERVAL expr type)和DATE_SUB(datte , INTTERVAL expr type),expr可以為負數,所以DATE_ADD既可以用於日期相加,也可以用於日期相減。type可以為YEAR、MONTH、DAY、HOUR、MINUTE、SECOND

SELECT NOW()AS NOW,DATE_ADD(NOW(),INTERVAL 1 DAY) AS tomorrow,DATE_SUB(NOW(),INTERVAL 1 DAY);

在這裡插入圖片描述

備註:閏月問題,如果是閏月就返回29日,不是閏月就返回28日

SELECT DATE_ADD('2004-2-29',INTERVAL 1 YEAR);  SELECT DATE_ADD('2004-2-29',INTERVAL 4 YEAR);

在這裡插入圖片描述
在這裡插入圖片描述

  • DATE_FORMAT函數
    DATE_FROMAT和Oracle中的to_char功能有點類型,作用是按照用戶定義的格式列印數據
SELECT DATE_FORMAT(NOW(),'%Y%m%d');