MySQL—聊聊时间那点事儿
背景
最近一个工单系统使用django+MySQL开发接口,本来一切都是那么美好,django的ORM用起来的确简直不要太爽,更新models,然后采用自带的migrate,速度飞起呀。直到预上线时才发现原来公司是不允许直接操作数据库创建表的,想建表好说,一切工单流。所以我只能抛弃django自带migrate,采用手写sql的方式建表啦。那么问题来了,当时建立models时采用的是auto_now和auto_now_add 来自动更新和初始化时间,所以代码里根本不会主动更新时间,然后只好依托于MySQL自己的自动更新时间的功能了。
MySQL的timestamp
- 占用4个字节
- 存储UTC时间,在存入时对当前的时区转化成UTC时间,取出时再转成本时区时间
- 时间戳,只能存储1970年之后的时间
- 默认不能为空 ,但可以设置默认时间
timestamp的自动初始化和更新
创建测试表test_ts
,并查询表创建语句
create table `test_ts` (id int(10) primary key, created timestamp);
show create table test_ts;
可以看到我们默认第一个timestamp类型字段会设置为NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
,即自动初始化并自动更新。其中CURRENT_TIMESTAMP
指的是当前时间,它和CURRENT_TIMESTAMP()
、NOW()
、LOCALTIME
、LOCALTIME()
、LOCALTIMESTAMP
、LOCALTIMESTAMP()
都指的是当前的时间。
然后再增加一个timestamp字段,然后查看创建语句
alter table test_ts add column updated timestamp;
show create table test_ts \G
我们发现MySQL只会对第一个timestamp添加NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
。
MySQL5.6.5的分水岭
一般我们会记录数据的创建时间,和最后更新时间。在MySQL5.6.5
之前若想使用timestamp达到这种效果,比如
create table `test_ts2` (
id int(10) primary key,
created timestamp not null default current_timestamp ,
updated timestamp not null default current_timestamp on update current_timestamp
) ENGINE=InnoDB default charset=utf8;
在MySQL 5.6.5
之前是不允许的,你大概会得到这样的错误信息
还好在
MySQL 5.6.5
做出了更新,允许创建多个timestamp能够自动更新
As of MySQL 5.6.5, the
[DATETIME](http://www.mysqltutorial.org/mysql-datetime/)
columns also have automatic initialization and updating features. In addition, theDEFAULT_CURRENT_TIMESTAMP
andON UPDATE CURRENT TIMESTAMP
can be applied to multiple columns.
既然MySQL 5.6.5
这么好,我们还是使用MySQL 5.7
吧!