MySQL:datetime與timestamp的區別及使用選擇

datetime與timestamp的區別

1、存儲空間不同
在MySQL,timestamp在內部存儲爲整型,佔用4個字節,而datetime佔用8個字節。

2、存儲方式不同
timestamp存儲時,會從插入時間的客戶端時區轉換爲UTC(世界標準時間)時間存儲,而datetime不會做時間的轉換直接存儲。

3、存儲的時間範圍不同

  • timestamp:UTC時間,1970-01-01 00:00:01.000000到 2038-01-19 03:14:07.999999
  • datetime:與時區無關,1000-01-01 00:00:00.000000 到 9999-12-31 23:59:59.999999

4、自動更新
在同一個表裏,允許有一個字段自動更新時間。如

CREATE TABLE `tb` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `mydatetime` datetime DEFAULT NULL,
 `mytimestamp` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

其中,mytimestamp爲自動更新時間,ON UPDATE CURRENT_TIMESTAMP。

使用選擇

在datetime和timestamp這幾個不同裏,存儲方式和時間範圍的不同會影響到我們對兩個類型的選擇。

timestamp始終會存儲爲UTC時間,也就是說它是一個固定時間,只是在不同的時區表示不同而已。而datetime則是一個靜態的時間,與時區無關。

在使用選擇上需要知道不同的存儲方式會帶來的問題

問題一

在跨時區做數據遷移,datetime類型的數據不能自動修正,需要我們使用其他方式做數據修正。因爲它是一個靜態的時間。

示例

CREATE TABLE `time_test` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `mydatetime` datetime DEFAULT NULL,
 `mytimestamp` timestamp NULL DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

查看系統時區

mysql> show variables like '%time_zone%';
+------------------+--------+
| Variable_name  | Value |
+------------------+--------+
| system_time_zone | CST  |
| time_zone    | SYSTEM |
+------------------+--------+

往time_test插入數據

mysql>INSERT INTO time_test (mydatetime,mytimestamp) VALUES (NOW(),NOW());
mysql>SELECT * FROM time_test;
+----+---------------------+---------------------+
| id | mydatetime       | mytimestamp      |
+----+---------------------+---------------------+
| 1 | 2017-12-08 22:14:56 | 2017-12-08 22:14:56 |
+----+---------------------+---------------------+

修改時區

mysql>SET time_zone='+9:00';
mysql>SELECT * FROM time_test;
+----+---------------------+---------------------+
| id | mydatetime       | mytimestamp      |
+----+---------------------+---------------------+
| 1 | 2017-12-08 22:14:56 | 2017-12-08 23:14:56 |
+----+---------------------+---------------------+

把時區修改爲“+9:00”,即東九區,mytimestamp時間顯示比之前多了一個小時。而mydatetime沒有變化

繼續插入一行數據

mysql>INSERT INTO time_test (mydatetime,mytimestamp) VALUES (NOW(),NOW());
mysql>SELECT * FROM time_test;
+----+---------------------+---------------------+
| id | mydatetime       | mytimestamp      |
+----+---------------------+---------------------+
| 1 | 2017-12-08 22:14:56 | 2017-12-08 23:14:56 |
| 2 | 2017-12-08 23:17:53 | 2017-12-08 23:17:53 |
+----+---------------------+---------------------+

注意,此時爲東九區,mydatetime插入的也是東九區當時的時間,而第一行數據仍然爲舊的數據。

修改爲東八區

mysql>SET time_zone='+8:00';
mysql>INSERT INTO time_test (mydatetime,mytimestamp) VALUES (NOW(),NOW());
mysql>SELECT * FROM time_test;
+----+---------------------+---------------------+
| id | mydatetime       | mytimestamp      |
+----+---------------------+---------------------+
| 1 | 2017-12-08 22:14:56 | 2017-12-08 22:14:56 |
| 2 | 2017-12-08 23:17:53 | 2017-12-08 22:17:53 |
+----+---------------------+---------------------+

此時,mytimestamp兩個時間都顯示爲東八區的時間,而mydatetime還是原來插入的時間。

問題二

timestamp所能表示的時間範圍小:UTC時間,1970-01-01 00:00:01.000000到 2038-01-19 03:14:07.999999

解決

timestamp所能表示的時間範圍小是MySQL設計上決定的,我們在應用層解決不了。datetime在跨時區的問題我們可以在應用層解決。

解決的思路和存儲timestamp的方式是一樣的,在應用層把datetime的時間統一轉爲UTC,然後我們再存進MySQL。如果需要在不同時區顯示,只需要在應用層把UTC時間轉換爲時區時間即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章