数据库笔记:DATETIME和TIMESTAMP
相同
- TIMESTAMP与DATETIME显示格式相同。显示宽度固定在19字符,格式为:YYYY-MM-DD HH:MM:SS。
- TIMESTAMP与DATETIME查询格式相同。都是以 column_name=’YYYY-MM-DD HH:MM:SS’ 或 column_name>=’YYYY-MM-DD HH:MM:SS’ 格式查询。
不同
1. 范围不同
DATETIME
支持的范围为 ‘1000-01-01 00:00:00’ 到 ‘9999-12-31 23:59:59’ 。DEFATUL值可以设置为范围内任意值,如 DEFAULT ‘1000-01-01 00:00:00’
TIMESTAMP
支持的范围为 ‘1970-01-01 00:00:00’ UTC 到 ‘2038-01-19 03:14:07’ UTC 。DEFATUL值可以设置为范围内任意值,还可以设置 DEFAULT ‘0000-00-00 00:00:00’
2. 储存方式不同
TIMESTAMP
- 4个字节储存
- 以UTC(Universal Time Coordinated,通用协调时)格式保存。
- 时区转化 ,因为以以UTC格式保存,因此存储时转换成UTC,查询时根据MySQL会话时区设置转换回当前的时区(因此读到的结果跟MySQL会话时区相关,一般没影响)。
DATETIME
- 8个字节储存,是TIMESTAMP的一倍。
- 实际格式储存,存的什么就写什么。
- 与时区无关,存的什么就读到什么。
TIMESTAMP 的一些其他的属性
- 字段不能定义DEFAULT NULL,也不能写入NULL(写入NULL会被转换成CURRENT_TIMESTAMP,或者DEFAULT值)。
- TIMESTAMP字段个数的问题:
- DEFAULT值为’0000-00-00 00:00:00’或’2008-01-01 12:12:12’等具体具体数值的TIMESTAMP字段可以有随意个数。
- 没有DEFAULT值或者设置如下DEFAULT值,一个表中只能有一个:
- 不设置 DEFAULT 值 (不设置 DEFAULT 值等同于 DEFAULT CURRENT_TIMESTAMP)
- DEFAULT CURRENT_TIMESTAMP
- DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
关于使用 int 直接存储 unix时间戳 的方式存储时间:
因为 unix时间戳 实际是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数(不考虑闰秒,timestamp底层实际就是存储这一秒数)。所以很多同学直接用 int unsigned(跟timestamp一样,4字节无符号)来存储 unix时间戳 的方式来存储时间。
相对于 timestamp 和 datetime 用 int unsigned来存储 unix时间戳 的方式来存储时间有什么优缺点呢?
优点
- 方便时间计算,直接 +/— 就能算出两个时间相差的秒数。
缺点
- 读取不方便,还需要转换一次才能得到人类能读懂的日期形式 YYYY-MM-DD HH:MM:SS ,但转换还算方便,MySQL 函数 from_unixtime(timestamp) 就能转换。
- 功能相对于 timestamp 弱很多,不能 DEFAULT CURRENT_TIMESTAMP 或 DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP。
总结
- 当对范围没有要求的时候 DATETIME 和 TIMESTAMP 使用一模一样,但是TIMESTAMP具有更省空间、更强功能等诸多特点,强烈建议以 TIMESTAMP 替换 DATETIME。
- 使用 int unsigned 存储时间戳的方式来存储时间不反对也不推荐(更推荐timestamp),但使用的时候注意比较也要跟 unix时间戳 进行比较如果跟 YYYY-MM-DD HH:MM:SS 进行比较可能走不上索引而进行全部扫描。