DATETIME类型
- 存储范围:
DATETIME
类型可以存储从1000-01-01 00:00:00
到9999-12-31 23:59:59
的日期和时间值,精度可以达到微秒级别。 - 时区处理:
DATETIME
类型不与特定时区关联。它直接存储你提供的日期和时间值,不包含任何时区信息。这意味着存储和检索时,值是不变的,非常适合不需要时区转换的场景。 - 存储空间:通常情况下,
DATETIME
类型占用8字节的存储空间。
TIMESTAMP类型
- 存储范围:
TIMESTAMP
类型可以存储从1970-01-01 00:00:01
UTC到2038-01-19 03:14:07
UTC的日期和时间值。注意,TIMESTAMP
有一个固定的时间范围限制,且存在“2038年问题”,即在2038年后无法存储新的日期。 - 时区处理:与
DATETIME
不同,TIMESTAMP
是时区敏感的。当数据被插入或更新时,MySQL会根据系统的时区设置将客户端的时间转换为UTC(协调世界时)进行存储。当数据被检索时,这个过程会被逆向执行,将UTC时间转换回当前MySQL服务器的时区时间。这意味着,如果你在不同的时区查看同一个TIMESTAMP
字段,显示的时间可能会有所不同。 - 自动更新:
TIMESTAMP
列可以被设置为在行被创建或更新时自动更新到当前时间(使用ON UPDATE CURRENT_TIMESTAMP
)。这是它常被用来记录记录创建或最后修改时间的原因。 - 存储空间:
TIMESTAMP
类型通常占用4字节的存储空间(MySQL 5.6.4及以后版本可以存储到微秒,此时占用5字节或更多,具体取决于精度设置)。
应用场景
- DATETIME适用于需要宽泛日期范围且不需要时区转换的场景,如记录历史事件或维护长期的审计日志。
- TIMESTAMP则更适合需要考虑时区差异,或者利用其自动更新特性的场景,比如记录数据的创建和修改时间。
两者区别
特性 | DATETIME | TIMESTAMP |
---|---|---|
存储范围 | 从1000-01-01 00:00:00到9999-12-31 23:59:59 | 从1970-01-01 00:00:01到2038-01-19 03:14:07 |
时区敏感性 | 不敏感,直接存储指定的时间 | 敏感,存储时转换为UTC,检索时转换回系统时区 |
自动更新 | 不提供自动更新到当前时间的功能 | 可以设置ON UPDATE CURRENT_TIMESTAMP 自动更新 |
存储空间 | 8字节 | 通常为4字节(MySQL 5.6.4后,带微秒为5字节或以上) |
默认值 | NULL | 当前时间(CURRENT_TIMESTAMP ),除非明确设置 |
适用场景 | 需要宽泛日期范围,不关心时区转换 | 需要考虑时区差异,记录创建/修改时间戳 |
注意事项
https://dev.mysql.com/doc/refman/8.0/en/data-type-defaults.html
explicit_defaults_for_timestamp
是一个MySQL的系统变量,它的引入是为了改变MySQL中对TIMESTAMP
列的默认行为,特别是在MySQL 5.6版本中。这个变量的主要作用和影响如下:背景
在MySQL早期版本中,
TIMESTAMP
列有一些特殊的默认行为:
- 如果一个表定义中只有一个
TIMESTAMP
列,则该列自动设置为当前时间戳,无论是插入新行还是更新行。- 如果定义了两个
TIMESTAMP
列,其中一个可以指定为ON UPDATE CURRENT_TIMESTAMP
,另一个则默认为插入时设置为当前时间戳。explicit_defaults_for_timestamp 的作用
当
explicit_defaults_for_timestamp
系统变量设置为ON
时:
- 上述
TIMESTAMP
列的默认自动行为被取消,意味着所有的TIMESTAMP
列都需要明确指定是否需要自动填充当前时间戳,包括在插入和更新时。- 你需要显式地使用
DEFAULT CURRENT_TIMESTAMP
和ON UPDATE CURRENT_TIMESTAMP
来指定自动填充的行为。配置与影响
- 配置方式:可以通过在MySQL配置文件(如my.cnf或my.ini)中的
[mysqld]
部分设置explicit_defaults_for_timestamp=ON
,或者在启动MySQL服务时通过命令行参数--explicit-defaults-for-timestamp=ON
来启用此特性。- 影响:这一改变增强了对
TIMESTAMP
列的控制,使得数据库管理员和开发者可以更加精确地控制哪些列需要自动更新,避免了过去因默认行为可能引起的混淆或不符合预期的数据处理问题。版本注意事项
- 从MySQL 5.6.6开始引入了这个系统变量,但是默认值为
OFF
,意味着老的行为仍然保持。- MySQL 8.0中,
explicit_defaults_for_timestamp
已经被移除,因为8.0版本中TIMESTAMP
列的默认行为已经永久性地变为需要显式指定,这实际上默认启用了之前通过该变量开启的功能。
选择哪种类型取决于具体的应用需求,包括日期范围、时区处理需求以及是否需要自动更新特性。