背景

之前有业务反馈表中start_time,end_time时间字段随着时间的推移被自动更新,这可不是业务意愿,说的严重点是要出故障的。

MySQL中有DATE,DATETIME,TIMESTAMP时间类型

看看官方文档怎么说

The DATE type is used for values with a date part but no time part. MySQL retrieves and displays DATE values in 'YYYY-MM-DD' format. The supported range is '1000-01-01' to '9999-12-31'.
The DATETIME type is used for values that contain both date and time parts. MySQL retrieves and displays DATETIME values in 'YYYY-MM-DD HH:MM:SS' format. The supported range is '1000-01-01 00:00:00' to '9999-12-31 23:59:59'.
The TIMESTAMP data type is used for values that contain both date and time parts. TIMESTAMP has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC.

这里我们重点介绍下DATATIME和TIMESTMAP

业务反馈start_time,end_time缺失就使TIMESTAMP类型,结合TIMESTAMP的特性,我们来分析原因。

Automatic Initialization and Updating for TIMESTAMP

One TIMESTAMP column in a table can have the current timestamp as the default value for initializing the column, as the auto-update value, or both.
If the column is auto-initialized, it is set to the current timestamp for inserted rows that specify no value for the column.
If the column is auto-updated, it is automatically updated to the current timestamp when the value of any other column in the row is changed from its current value.

什么意思呢?

create table gbtest_with_force_default_val
(
id bigint AUTO_INCREMENT,
t_null_1 timestamp,
t_null_2 timestamp,
t_with_not_null timestamp not null,
t_with_not_null_default timestamp not null default '2016-12-21',
primary key(id)
); mysql> show create table gbtest_with_force_default_val; CREATE TABLE `gbtest_with_force_default_val` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`t_null_1` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`t_null_2` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`t_with_not_null` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`t_with_not_null_default` timestamp NOT NULL DEFAULT '2016-12-21 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

在MySQL5.5版本中,TIMESTAMP特性

  1. TIMESTAMP字段默认为NOT NULL,如果你在定义“t_null_1 TIMESTAMP DEFAULT NULL” 会提升“ERROR 1067 (42000): Invalid default value for 't_null_1'”。 可以指定为空 null ,“t_null_1 TIMESTAMP NULL" ,这时可以再添加语句改变默认值。
  2. 如果不做特殊说明,同一个表中会对第一个TIMESTAMP字段设置DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP属性,第二个字段设置DEFAULT '0000-00-00 00:00:00',如果对两个字段都显示指定“DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP”是会被告知“ERROR 1293 (HY000): Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause”,测试发现在MySQL5.6版本中并没有该限制。
mysql> select version();
+------------------+
| version() |
+------------------+
| 5.6.16.7-rc0-log |
+------------------+
1 row in set (0.00 sec) CREATE TABLE `gbtest_with_force_default_val_null` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`t_null_1` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`t_null_2` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`t_with_not_null` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`t_with_not_null_default` timestamp NOT NULL DEFAULT '2016-12-21 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

那如何解决业务遇到的问题呢,其实很简单,既然“DEFAULT CURRENT_TIMESTAMP”有限制,那不用好了,换成NULL DEFAULT CURRENT_TIMESTAMP去掉自动更新属性,或者显式的允许这两个字段为NULL。

create table gbtest_with_force_default_val_null (
id bigint AUTO_INCREMENT,
t_null_1 timestamp NULL CURRENT_TIMESTAMP,
t_null_2 timestamp NULL DEFAULT 0,
t_with_not_null timestamp not null,
t_with_not_null_default timestamp not null default '2016-12-21', primary key(id) ); mysql> show create table gbtest_with_force_default_val_null; CREATE TABLE `gbtest_with_force_default_val_null` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`t_null_1` timestamp NULL CURRENT_TIMESTAMP,
`t_null_2` timestamp NULL DEFAULT '0000-00-00 00:00:00',
`t_with_not_null` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`t_with_not_null_default` timestamp NOT NULL DEFAULT '2016-12-21 00:00:00',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

MySQL5.6版本中TIMESTAMP特性

经过学习,发现在5.6版中中多了一个叫“explicit_defaults_for_timestamp”的系统变量,但默认是OFF的,但是也可以支持一个表中多个字段的同时更新。

mysql> show variables like '%explicit_defaults_for_timestamp%';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| explicit_defaults_for_timestamp | OFF |
+---------------------------------+-------+
1 row in set (0.00 sec)

那将这个参数打开会有什么不同?

mysql> set @@global.explicit_defaults_for_timestamp=ON;
ERROR 1238 (HY000): Variable 'explicit_defaults_for_timestamp' is a read only variable
该参数并不支持动态修改!!! create table gbtest_with_noforce(
id bigint AUTO_INCREMENT,
t_null_1 timestamp,
t_null_2 timestamp,
t_with_not_null timestamp not null,
t_with_not_null_default timestamp not null default '2016-12-21',
primary key(id)
); CREATE TABLE `gbtest_with_noforce` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`t_null_1` TIMESTAMP NULL DEFAULT NULL,
`t_null_2` TIMESTAMP NULL DEFAULT NULL,
`t_with_not_null` TIMESTAMP NOT NULL,
`t_with_not_null_default` TIMESTAMP NOT NULL DEFAULT '2016-12-21 00:00:00',
PRIMARY KEY (`id`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8
;

发现如下改变:

  1. 默认参数为NULL
  2. 并不会自动添加DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP等属性

结论

那考虑的版本的兼容性,测试发现,在5,5版本中按默认属性创建的表,在5.6版本中迁移是没有任何问题的,是完全兼容的。这说明,使用Mysql5.6以后的版本,应立即将explicit_defaults_for_timestamp参数设置为True,并及时反馈开发TIMESTAMP的行为。

【MySQL】探究之TIMESTAMP的更多相关文章

  1. MySQL 时间戳(Timestamp)函数

    1. MySQL 获得当前时间戳函数:current_timestamp, current_timestamp() mysql> select current_timestamp, curren ...

  2. mysql的时间戳timestamp精确到小数点后六位

    1.mysql的时间戳timestamp精确到小数点后六位. 公司业务使用到Greenplun数据库,根据查询的时间戳来不断的将每个时间段之间的数据,进行数据交换,但是今天发现,mysql的时间戳没有 ...

  3. MySQL 时间戳(Timestamp)函数

    1. MySQL 获得当前时间戳函数:current_timestamp, current_timestamp() mysql> select current_timestamp, curren ...

  4. Mysql sql_mode设置 timestamp default 0000-00-00 00:00:00 创建表失败处理

    往数据库里创建新表的时候报错: [Err] 1067 - Invalid default value for 'updateTime' DROP TABLE IF EXISTS `passwd_res ...

  5. MySQL datetime 和 timestamp 的区别

    [转载]:MySQL中有关TIMESTAMP和DATETIME的总结 1. datetime 和 timestamp 的相同点 两者都可以用来表示YYYY-MM-DD HH:MM:SS[.fracti ...

  6. mysql多个TimeStamp设置

    mysql多个TimeStamp设置 2012-11-02 12:58  轩脉刃  阅读(39590)  评论(3)  编辑  收藏 timestamp设置默认值是Default CURRENT_TI ...

  7. MySQL中有关TIMESTAMP和DATETIME的总结

    一.MySQL中如何表示当前时间? 其实,表达方式还是蛮多的,汇总如下: CURRENT_TIMESTAMP CURRENT_TIMESTAMP() NOW() LOCALTIME LOCALTIME ...

  8. mysql中的timestamp类型时间比较:unix_timestamp函数

    在mysql中,某字段的类型设置为了timestamp,那么我们现在希望取出指定时间段的记录,该如何做呢? 在php中有time()和strtotime()来进行日期和时间戳的格式化,而在mysql中 ...

  9. mysql 添加[取消]timestamp的自动更新

    创建自动更新的 timestamp (插入或修改时 uptime都会自动更新) CREATE TABLE `hello` (`id` int(11) NOT NULL,`uptime` timesta ...

随机推荐

  1. tab选项卡(选择上面的菜单,下面出现对应的不同的内容)

    使用jQuery完成 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

  2. mysql 中关于周和月份的表示

    本周:YEARWEEK(date_format(create_time,'%Y-%m-%d')) = YEARWEEK(now()) 上周:YEARWEEK(date_format(create_ti ...

  3. leetcode算法思想快速一览

    整理了一下思路,想深入了解还得多去写,无奈时间紧迫的情况下抛砖引玉也不失为下策: 1.Two Sum Easy 给出一个数组,找出其中两个和为目标值的坐标.思路: [1]排序. 和为目标值,一般的思路 ...

  4. PHP基础示例:商品信息管理系统v1.1[转]

      实现目标:使用php和mysql写一个商品信息管理系统,并带有购物车功能 一.创建数据库和表 1.创建数据库和表:demodb 2.创建表格:goods 字段:商品编号,商品名称,商品类型,商品图 ...

  5. dos2unix,去掉Linux下文件中的^M

    Windows系统下使用VS2010编写好的CPP文件,想放到Linux上进行编译.发现Linux上文件中的每行代码末尾都跟着^M这个符号. 为什么同一份文件在windows上和Linux上显示的不一 ...

  6. 原生态AJAX详解和jquery对AJAX的封装

    AJAX: A :Asynchronous [eI`sinkrenes] 异步 J :JavaScript    JavaScript脚本语言 A: And X :XML 可扩展标记语言 AJAX现在 ...

  7. 一张图让你看懂各开源License[转]

    你是否遇到过开源License,精炼而又晦涩的文字通常要读半天才能理解,而且大多数License差别不大,容易混淆.下面这张图让你段时间迅速掌握各种开源的License. 图片来源:阮一峰的博客. f ...

  8. 利用OVER开窗函数分页

    在SQL Server中,利用SQL进行分页的方法也有很多,今天要总结的是SQL Server 2005中引入的OVER开窗口函数,然后利用开窗函数进行分页. 示例代码如下: -- 设置数据库上下文 ...

  9. Appium移动自动化测试(一)--安装Appium

    Appium 自动化测试是很早之前就想学习和研究的技术了,可是一直抽不出一块完整的时间来做这件事儿.现在终于有了. 反观各种互联网的招聘移动测试成了主流,如果再不去学习移动自动化测试技术将会被淘汰. ...

  10. warning C4305: “=”: 从“int”到“unsigned char”截断解决方法[zz]

    在控制台程序中定义: float x; x=22.333; 编译会出现 warning C4305: “初始化”: 从“double”到“float”截断 系统默认此浮点数是22.333是double ...