从 MySQL 5.6.5 开始,TIMESTAMP
列
DATETIME
可以自动初始化并更新为当前日期和时间(即当前时间戳)。在 5.6.5 之前,这仅适用于TIMESTAMP
,并且每个表最多一TIMESTAMP
列。以下说明首先介绍 MySQL 5.6.5 及以上版本的自动初始化和更新,然后介绍 5.6.5 之前版本的差异。
对于表中的任何TIMESTAMP
或
DATETIME
列,您可以将当前时间戳指定为默认值、自动更新值或两者:
对于没有为该列指定值的插入行,自动初始化列设置为当前时间戳。
当行中任何其他列的值从其当前值更改时,自动更新列将自动更新为当前时间戳。如果所有其他列都设置为其当前值,则自动更新的列将保持不变。要防止自动更新的列在其他列更改时更新,请将其显式设置为其当前值。要更新自动更新的列,即使其他列没有更改,请将其显式设置为应有的值(例如,将其设置为
CURRENT_TIMESTAMP
)。
此外,如果
explicit_defaults_for_timestamp
系统变量被禁用,您可以通过为其分配一个值来将任何
TIMESTAMP
(但不是
DATETIME
)列初始化或更新为当前日期和时间NULL
,除非它已被定义NULL
为允许NULL
值的属性。
要指定自动属性,请在列定义中使用DEFAULT
CURRENT_TIMESTAMP
and子句。ON UPDATE
CURRENT_TIMESTAMP
子句的顺序无关紧要。如果两者都存在于列定义中,则其中一个可以先出现。的任何同义词CURRENT_TIMESTAMP
都与 具有相同的含义
CURRENT_TIMESTAMP
。这些是
CURRENT_TIMESTAMP()
,
NOW()
,
LOCALTIME
,
LOCALTIME()
,
LOCALTIMESTAMP
和
LOCALTIMESTAMP()
。
DEFAULT CURRENT_TIMESTAMP
and
的
使用ON UPDATE CURRENT_TIMESTAMP
特定于
TIMESTAMP
and
DATETIME
。该
DEFAULT
子句还可用于指定常量(非自动)默认值(例如,
DEFAULT 0
or DEFAULT '2000-01-01
00:00:00'
)。
以下示例使用DEFAULT 0
, 一个默认值,它可以产生警告或错误,具体取决于是否
NO_ZERO_DATE
启用了严格 SQL 模式或 SQL 模式。请注意,
TRADITIONAL
SQL 模式包括严格模式和
NO_ZERO_DATE
. 请参阅
第 5.1.10 节,“服务器 SQL 模式”。
TIMESTAMP
或
DATETIME
列定义可以为默认值和自动更新值指定当前时间戳,为一个而不为另一个指定当前时间戳,或者两者都不指定。不同的列可以有不同的自动属性组合。以下规则描述了可能性:
对于
DEFAULT CURRENT_TIMESTAMP
和ON UPDATE CURRENT_TIMESTAMP
,该列的默认值具有当前时间戳,并自动更新为当前时间戳。CREATE TABLE t1 ( ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, dt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP );
有
DEFAULT
子句但没有ON UPDATE CURRENT_TIMESTAMP
子句,该列具有给定的默认值,并且不会自动更新为当前时间戳。默认值取决于
DEFAULT
子句指定CURRENT_TIMESTAMP
的还是常量值。对于CURRENT_TIMESTAMP
,默认值为当前时间戳。CREATE TABLE t1 ( ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP, dt DATETIME DEFAULT CURRENT_TIMESTAMP );
对于常量,默认值为给定值。在这种情况下,该列根本没有自动属性。
CREATE TABLE t1 ( ts TIMESTAMP DEFAULT 0, dt DATETIME DEFAULT 0 );
使用
ON UPDATE CURRENT_TIMESTAMP
子句和常量DEFAULT
子句,列会自动更新为当前时间戳并具有给定的常量默认值。CREATE TABLE t1 ( ts TIMESTAMP DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP, dt DATETIME DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP );
有
ON UPDATE CURRENT_TIMESTAMP
子句但没有DEFAULT
子句,该列会自动更新为当前时间戳,但没有当前时间戳作为其默认值。这种情况下的默认值取决于类型。
TIMESTAMP
除非使用属性定义,否则默认值为 0NULL
,在这种情况下,默认值为NULL
.CREATE TABLE t1 ( ts1 TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- default 0 ts2 TIMESTAMP NULL ON UPDATE CURRENT_TIMESTAMP -- default NULL );
DATETIME
NULL
除非使用属性定义, 否则NOT NULL
默认值为 0,在这种情况下默认值为 0。CREATE TABLE t1 ( dt1 DATETIME ON UPDATE CURRENT_TIMESTAMP, -- default NULL dt2 DATETIME NOT NULL ON UPDATE CURRENT_TIMESTAMP -- default 0 );
TIMESTAMP
DATETIME
除非明确指定,否则列没有自动属性,但以下情况除外:如果
系统
explicit_defaults_for_timestamp
变量被禁用,则第一
TIMESTAMP
列同时具有这两个
属性DEFAULT CURRENT_TIMESTAMP
,ON
UPDATE CURRENT_TIMESTAMP
如果两者都没有明确指定。要抑制第一
TIMESTAMP
列的自动属性,请使用以下策略之一:
启用
explicit_defaults_for_timestamp
系统变量。在这种情况下,指定自动初始化和更新的DEFAULT CURRENT_TIMESTAMP
和ON UPDATE CURRENT_TIMESTAMP
子句可用,但不会分配给任何TIMESTAMP
列,除非明确包含在列定义中。或者,如果
explicit_defaults_for_timestamp
禁用,请执行以下任一操作:DEFAULT
使用指定常量默认值 的子句定义列。指定
NULL
属性。这也会导致列允许NULL
值,这意味着您不能通过将列设置为来分配当前时间戳NULL
。分配NULL
将列设置为NULL
,而不是当前时间戳。要分配当前时间戳,请将列设置为CURRENT_TIMESTAMP
或同义词,例如NOW()
。
考虑这些表定义:
CREATE TABLE t1 (
ts1 TIMESTAMP DEFAULT 0,
ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP);
CREATE TABLE t2 (
ts1 TIMESTAMP NULL,
ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP);
CREATE TABLE t3 (
ts1 TIMESTAMP NULL DEFAULT 0,
ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP);
这些表具有以下属性:
在每个表定义中,第一
TIMESTAMP
列没有自动初始化或更新。这些表在
ts1
列处理NULL
值的方式上有所不同。对于t1
,ts1
isNOT NULL
并为其分配一个值,NULL
将其设置为当前时间戳。对于t2
andt3
,ts1
允许NULL
并为其赋值 将其NULL
设置为NULL
。t2
和t3
的默认值不同ts1
。对于t2
,ts1
被定义为 permitNULL
,因此默认也是NULL
在没有显式DEFAULT
子句的情况下。对于t3
,ts1
允许NULL
但具有明确的默认值 0。
如果TIMESTAMP
或
DATETIME
列定义在任何地方包含显式小数秒精度值,则必须在整个列定义中使用相同的值。这是允许的:
CREATE TABLE t1 (
ts TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)
);
这是不允许的:
CREATE TABLE t1 (
ts TIMESTAMP(6) DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(3)
);
MySQL 5.6.5 之前的自动时间戳属性
在 MySQL 5.6.5 之前,对自动初始化和更新的支持比较有限:
您可以选择是否使用这些属性以及
TIMESTAMP
应该在哪一列中使用这些属性。它不必是自动初始化或更新为当前时间戳的表中的第一个。要为不同的
TIMESTAMP
列指定自动初始化或更新,您必须抑制第一个列的自动属性,如前所述。然后,对于另一
TIMESTAMP
列,DEFAULT
和ON UPDATE
子句的规则与第一
TIMESTAMP
列相同,只是如果省略这两个子句,则不会发生自动初始化或更新。
TIMESTAMP 初始化和 NULL 属性
如果
explicit_defaults_for_timestamp
系统变量被禁用,
TIMESTAMP
列默认为
NOT NULL
, 不能包含
NULL
值,并且分配
NULL
分配当前时间戳。要允许TIMESTAMP
列包含
,请使用属性NULL
显式声明它
。NULL
在这种情况下,默认值也变为NULL
除非被DEFAULT
指定不同默认值的子句覆盖。DEFAULT NULL
可用于明确指定NULL
为默认值。(对于未用属性
TIMESTAMP
声明的列,无效。)如果
列允许
NULL
DEFAULT NULL
TIMESTAMP
NULL
值,分配
NULL
将其设置为NULL
,而不是当前时间戳。
下表包含多个
TIMESTAMP
允许
NULL
值的列:
CREATE TABLE t
(
ts1 TIMESTAMP NULL DEFAULT NULL,
ts2 TIMESTAMP NULL DEFAULT 0,
ts3 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP
);
TIMESTAMP
允许
NULL
值
的列在插入时不
采用当前时间戳,除非在以下情况之一:
它的默认值定义为
CURRENT_TIMESTAMP
并且没有为该列指定值CURRENT_TIMESTAMP
或其任何同义词,例如NOW()
is explicitly inserted into the column
换句话说,TIMESTAMP
定义为允许NULL
值的列只有在其定义包括以下内容时才会自动初始化
DEFAULT CURRENT_TIMESTAMP
:
CREATE TABLE t (ts TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP);
如果TIMESTAMP
列允许
NULL
值但其定义不包括DEFAULT CURRENT_TIMESTAMP
,则必须显式插入与当前日期和时间对应的值。假设表t1
和
t2
具有以下定义:
CREATE TABLE t1 (ts TIMESTAMP NULL DEFAULT '0000-00-00 00:00:00');
CREATE TABLE t2 (ts TIMESTAMP NULL DEFAULT NULL);
要TIMESTAMP
在插入时将任一表中的列设置为当前时间戳,请显式为其分配该值。例如:
INSERT INTO t2 VALUES (CURRENT_TIMESTAMP);
INSERT INTO t1 VALUES (NOW());
如果
explicit_defaults_for_timestamp
启用了系统变量,则
TIMESTAMP
列
仅在使用属性NULL
声明时才允许值
。NULL
此外,
TIMESTAMP
列不允许分配NULL
以分配当前时间戳,无论是用NULL
or
NOT NULL
属性声明的。要分配当前时间戳,请将列设置为
CURRENT_TIMESTAMP
或同义词,例如NOW()
。