datetime
支持时间区间 1000-01-01 00:00:00
到9999-12-31 23:59:59
,timestamp
只支持'1970-01-01 00:00:01' UTC
到'2038-01-19 03:14:07' UTC
datetime
直接保存不需要转换,timestamp
会转变为UTC时间保存在数据库,当select的时候再转变为当前时区的时间datetime
存储需要更多的字节,在mysql支持毫秒之前,datetime
需要8
字节,而timestamp
只需要4
个字节。细节可以参考TIMESTAMP vs. DATETIME, which should I be using?;支持毫秒之后,存储空间有两次变化,细节参见MySQL: DATETIME vs TIMESTAMP 网上有一些描述存在错误
datetime
不支持建立索引,其实是支持的。如下:person | CREATE TABLE `person` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL,
`create_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`modify_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `ctime` (`create_time`),
KEY `mtime` (`modify_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
datetime
和timestamp
没有明显的优劣之分,如果选择要看实际场景,这里总结一些自己和别人的经验
timestamp
;不过如果希望不同时区也显示同一个时间,则使用datetime
(看具体应用吧)timestamp
满足不了的,只能选择datetime
。比如历史时间或者未来时间。datetime
和timestamp
的影响mysql> show create table person;
+--------+---------------------------------------------------------------------------+
| Table | Create Table |
+--------+---------------------------------------------------------------------------+
| person | CREATE TABLE `person` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL,
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`modify_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+--------+---------------------------------------------------------------------------+
1 row in set (0.00 sec)
表person
的create_time
字段是datetime
类型,modify_time
是timestamp
类型
mysql> show variables like '%time_zone%';
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| system_time_zone | CST |
| time_zone | SYSTEM |
+------------------+--------+
2 rows in set (0.06 sec)
mysql> select * from person;
+----+------+---------------------+---------------------+
| id | name | create_time | modify_time |
+----+------+---------------------+---------------------+
| 1 | tim | 2018-07-14 17:42:40 | 2018-07-14 17:42:40 |
+----+------+---------------------+---------------------+
1 row in set (0.00 sec)
可以看出表中的create_time
和modify_time
的时间都是2018-07-14 17:42:40
mysql> set time_zone='+00:00';
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like '%time_zone%';
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| system_time_zone | CST |
| time_zone | +00:00 |
+------------------+--------+
2 rows in set (0.00 sec)
mysql> select * from person;
+----+------+---------------------+---------------------+
| id | name | create_time | modify_time |
+----+------+---------------------+---------------------+
| 1 | tim | 2018-07-14 17:42:40 | 2018-07-14 09:42:40 |
+----+------+---------------------+---------------------+
1 row in set (0.00 sec)
如果设置时区为0
时区,则可以看到create_time
不变,但是modify_time
发生了变化,这是因为timestamp
的保存是与时区无关的,当显示的时候,则会自动转变为当前时区的时间
China Standard Time
,但是大部分情况下都是代表美国中部标准时间Central Standard Time
如果有一点帮助,麻烦点一个赞,如果没有,也期待你的反馈