赞
踩
1、存储空间不同
在MySQL,timestamp在内部存储为整型,占用4个字节,而datetime占用8个字节。
2、存储方式不同
timestamp存储时,会从插入时间的客户端时区转换为UTC(世界标准时间)时间存储,而datetime不会做时间的转换直接存储。
3、存储的时间范围不同
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时间转换为时区时间即可。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。