[mysql] timestamp自动更新和初始化

[mysql] timestamp自动更新和初始化

1.概述html

在咱们设计表的时候,考虑将行数据的建立时间和最后更新时间记录下来是很好的实践。尤为是可能须要作数据同步或者对数据新鲜度有要求的表。举些应用场景,更新距上次更新超过2小时的行数据,或者是将一个月前的订单数据归档等等。咱们想把这个的需求丢给数据库服务器管理,而不是在应用程序中对每一条语句设置建立时间和最后更新时间字段。在mysql中,这实现起来很容易。咱们须要借助于DEFAULT CURRENT_TIMESTAMP  ON UPDATE CURRENT_TIMESTAMPmysql

2.简单示例sql

复制代码

 1 --建立测试表 
 2 CREATE TABLE `timestampTest` ( 
 3   `id` int(11) NOT NULL AUTO_INCREMENT, 
 4   `name` varchar(20) DEFAULT NULL, 
 5   `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
 6   `last_modify_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
 7   PRIMARY KEY (`id`) 
 8 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 
 9 
 10 --检测默认值,插入测试数据
 11 INSERT INTO timestampTest (name) VALUES ('aa'),('bb'),('cc');
 12 
 13 --检测自动更新,更新某条数据
 14 UPDATE timestampTest SET name = 'ab' WHERE id = 1;

复制代码

例子很是简单,结果也很明显,我就不加赘述了。数据库

3.思考服务器

  • 执行update语句,并未改变列值(或者说设置值为当前值),on update current_timestamp列是否会更新?ide

    不会,你们能够看一下执行完update后出现的提示——Rows matched: 1 Changed: 0 Warnings: 0。官方文档的解释是post

An auto-updated column remains unchanged if all other columns are set to their current values. To prevent an auto-updated column from updating when other columns change, explicitly set it to its current value. To update an auto-updated column even when other columns do not change, explicitly set it to the value it should have测试

    

  • CURRENT_TIMESTAMP,CURRENT_TIMESTAMP(),LOCALTIME,LOCALTIME(),LOCALTIMESTAMP,LOCALTIMESTAMP(),NOW()的关系?url

    这七个是同义词关系spa

  • Timestamp类型的默认值

    咱们讨论默认状况(严格模式)下mysql对timestamp类型的处理:


  1. mysql不会给timestamp设置默认值,除非显式设置default约束或者可空null。特例:mysql会给表第一个timestamp类型的字段同时添加default current_timestamp和on update timestamp

  2. 禁止mysql的特例处理有两个办法

    1. 设置explicit_defaults_for_timestamp为enable

    2. 显式设置该字段default或者null

  3. timestamp列默认not null。没有显式指定nullable,那么default null不合法

  4. 其余状况均会引发不合法报错

举一些例子,帮助理解

复制代码

#语句不合法,出现了两个未显示设置default或null的timestamp
CREATE TABLE `tt1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20),
  `t1` timestamp ,
  `t2` timestamp ,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

#语句合法,t1字段 not null default current_timestamp on update current_timestamp,t2可空
CREATE TABLE `tt2` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20),
  `t1` timestamp ,
  `t2` timestamp null,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

#语句不合法 t2字段没有设置default或null,也非表的第一个timestamp字段
CREATE TABLE `tt3` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20),
  `t1` timestamp null,
  `t2` timestamp ,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

#语句不合法,这个看起来貌似合法,套用咱们的规则,能够发现t2字段没有显示指定null/default,尽管指定了not null也不行
CREATE TABLE `tt4` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20),
  `t1` timestamp null,
  `t2` timestamp not null,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

#语句不合法 t1,t2均合法,问题出在t3上,timestamp 默认not null,在没有显式指定null的时候,default null是不合法的
CREATE TABLE `tt5` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20),
  `t1` timestamp not null,
  `t2` timestamp null,
  `t3` timestamp DEFAULT null,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

复制代码

  小技巧:能够使用show create table `tablename` 来查看mysql处理后的表定义,下面是tt2这张表的定义,验证了咱们的结论

  

  • Timestamp和datetime的异同


timestamp datetime
可自动更新和初始化,默认显示格式相同YYYY-MM-dd HH:mm:ss

'1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC

自动时区转化,实际存储毫秒数,4字节存储

'1000-01-01 00:00:00' to '9999-12-31 23:59:59'

不支持时区,8字节存储

4.参考

1.Automatic Initialization and Updating for TIMESTAMP and DATETIME

2.Date and Time Functions

做者: zhaoyanghoo 
出处: http://www.cnblogs.com/zhaoyanghoo/ 本文版权归做者和博客园共有,欢迎转载,但未经做者赞成必须保留此段声明,且在文章页面明显位置给出原文链接,不然保留追究法律责任的权利。

相关文章
相关标签/搜索