TIMESTAMP和DATETIME
TIMESTAMP和DATETIME类型非常相似,显示出来都是YYYY-MM-DD hh:mm:ss[.小数]
。不同点在于,timestamp保存时是保存的utc时间,获取时,会根据当前会话时区或者系统时区进行转化;DATETIME是一个绝对值,不会随时区变化。另外这两者在表达范围和存储占用也稍有不同。
datetime和timestamp都支持6位小数。
表达范围
TIMESTAMP只能表示’1970-01-01 00:00:01′ UTC 到’2038-01-19 03:14:07′ UTC;DATETIME可以表达的范围是 ‘1000-01-01 00:00:00’ 到 ‘9999-12-31 23:59:59’(注意这里没有时区)
Zero Value
当遇到非法的值时,都会转成Zero Value,即 ‘0000-00-00 00:00:00’
SQL语句示例
`ts` TIMESTAMP(6) NULL DEFAULT NULL
以上SQL中(6)
表示该字段包含6位小数,即可精确到微秒(10^-6)。
存储差异
type | 5.6.4之前 | 5.6.4以后 |
---|---|---|
DATETIME | 8 bytes | 5 bytes + 小数部分 |
TIMESTAMP | 4 bytes | 4 bytes + 小数部分 |
小数部分存储:
小数长度 | 存储 |
---|---|
0 | 0 bytes |
1, 2 | 1 byte |
3, 4 | 2 bytes |
5, 6 | 3 bytes |
因此在 MySQL5.6.4以后,DATETIME最少占5个字节,最多占8个字节;TIMESTAMP最少占4个字节,最多占7个字节。
参考资料
- https://stackoverflow.com/questions/2012589/php-mysql-year-2038-bug-what-is-it-how-to-solve-it
- https://dev.mysql.com/doc/refman/5.7/en/date-and-time-types.html
INT类型
INT(11) 和 INT(3) 没有任何区别,在存储上都占 4 bytes,只有当指定ZEROFILL
时,才会体现出稍微的显示上的区别出来:
`id` INT(11) UNSIGNED ZEROFILL NOT NULL AUTO_INCREMENT
以上语句指定了ZEROFILL
,当保存一个文本长度不足11位的数字时,将会在数字前补充0,比如235,文本长度是3,因此追加8个0,显示出来时是00000000235。
navicate等GUI工具可能会把这些0去掉,导致没有显示差异。
即使指定了ZEROFILL
,但不影响数字的存储,以及它们的计算,仅仅是显示上有差异而已。