当我尝试创建具有非空时间戳的表时,它要求我向其中添加默认时间戳或使用隐式默认值。但我不确定为什么这是必要的。
看看https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=c615bce0cd1009b0c597593e73fdd794,
其中以下 SQL
create table t3 (
id int not null,
d1 timestamp not null,
num double not null)
engine=innodb;
Run Code Online (Sandbox Code Playgroud)
将转变为
CREATE TABLE `t3` (
`id` int(11) NOT NULL,
`d1` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`num` double NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Run Code Online (Sandbox Code Playgroud)
使用此类工具时,我们可以清楚地看到 int 和 double 不会自动为其生成默认值,但 timestamp 会自动生成默认值。为什么时间戳需要默认值,而另一个不需要默认值,这背后的原因是什么?
就我个人而言,我希望没有默认值,并且当最终用户将数据插入没有d1时间戳的行时,将引发异常,并且此类行将无法注入到表中。但显然这似乎并不是 MySQL 所采取的想法。
在explicit_defaults_for_timestamp上特别提到
如果禁用explicit_defaults_for_timestamp,服务器将启用非标准行为并按如下方式处理TIMESTAMP列:
表中的第一个 TIMESTAMP 列,如果未使用 NULL 属性或显式 DEFAULT 或 ON UPDATE 属性显式声明,则会自动使用 DEFAULT CURRENT_TIMESTAMP 和 ON UPDATE CURRENT_TIMESTAMP 属性进行声明。
仅当禁用explicit_defaults_for_timestamp 时,才会在第一个TIMESTAMP 列中发生此行为。
mysql> select version();
+-----------------------------+
| version() |
+-----------------------------+
| 5.7.16-0ubuntu0.16.04.1-log |
+-----------------------------+
mysql> show variables like "%explicit_defaults_for_timestamp%";
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| explicit_defaults_for_timestamp | OFF |
+---------------------------------+-------+
mysql> create table t3 (
-> id int not null,
-> d1 timestamp not null,
-> d2 timestamp not null,
-> num double not null)
-> engine=innodb;
Query OK, 0 rows affected (0.31 sec)
mysql> show create table t3;
CREATE TABLE `t3` (
`id` int(11) NOT NULL,
`d1` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`d2` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`num` double NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Run Code Online (Sandbox Code Playgroud)
根据问题
使用此类工具时,我们可以清楚地看到 int 和 double 不会自动为其生成默认值,但 timestamp 会自动生成默认值。为什么时间戳需要默认值,而另一个不需要默认值,这背后的原因是什么?
MySQL 处理时间戳的方式与其他数据类型不同。
就个人而言,我希望没有默认值,并且当最终用户将数据插入没有 d1 时间戳的行时
这可以通过启用来完成 explicit_defaults_for_timestamp
mysql> set session explicit_defaults_for_timestamp = 1;
Query OK, 0 rows affected (0.00 sec)
mysql> show session variables like "%explicit_defaults_for_timestamp%";
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| explicit_defaults_for_timestamp | ON |
+---------------------------------+-------+
1 row in set (0.00 sec)
mysql> drop table t3;
Query OK, 0 rows affected (0.09 sec)
mysql> create table t3 (
-> id int not null,
-> d1 timestamp not null,
-> num double not null)
-> engine=innodb;
Query OK, 0 rows affected (0.18 sec)
mysql> show create table t3;
CREATE TABLE `t3` (
`id` int(11) NOT NULL,
`d1` timestamp NOT NULL,
`num` double NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4720 次 |
| 最近记录: |