数据库不要设置自动更新时间


数据库不要设置自动更新时间


正文

有时DBA会建议给表加上自动填写创建时间和自动更新更新时间,这样会防止程序员漏写时间的问题。

初听之下,确实挺方便的,然后就加上了:

  `created_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '添加时间',
  `updated_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',

刚用之下,也没发现什么不好,逻辑里还不用写时间相关的代码了。随着时间的推移,业务逐渐复杂, 然后各种无奈和将就:

1、有时需要修改表中一个字段,但更新时间不能变。

2、日志表和记录表中创建时间不一致的问题。

先来说一下第一个问题:有时需要修改表中一个字段,但更新时间不能变。这就需要我们先拿到修改数据的更新时间, 然后在update时把拿到的时间重新赋值写回去。一条数据还好,多条数据呢?不能整体修改,必须循环一条一条去更新了!

再来说第二个问题:日志表和记录表中创建时间不一致的问题。有时我们会对这次操作记录操作日志, 如果数据操作写入数据库的时间和日志写入数据库的时间刚好错过1秒的分界线,这就会是两个时间, 为什么数据更新时间和日志中记录的写入时间不一致?是不是有一次操作漏写了?这种情况就比较严重了!

一般我们会对日志表和记录表的时间都用一个时间,也就是直接对时间赋值,然后才写入数据库,既然这样, 那为什么还要给数据表加自动填写创建时间和自动更新更新时间?而且还有第一种情况的存在。

其实一个严谨的程序员,所有相关时间都是自己赋值操作的,不会漏写相关时间。而且就数据库而言, 数据库只应该做数据存储的事情,不应参入任何逻辑;再者,程序必须占据主导地位, 具有数据操作的完全权限,不能外让相关权限,致使对数据的操作能力受损。

时间类型 DATE、DATETIME和TIMESTAMP

1.DATE、DATETIME和TIMESTAMP 表达的时间范围

Type Range Remark
DATE ‘1000-01-01’ to ‘9999-12-31’ 只有日期部分,没有时间部分
DATETIME ‘1000-01-01 00:00:00’ to ‘9999-12-31 23:59:59’ 时间格式为 YYYY-MM-DD hh:mm:ss,默认精确到秒
TIMESTAMP ‘1970-01-01 00:00:01’ UTC to ‘2038-01-19 03:14:07’UTC 默认精确到秒

2.DATETIME和TIMESTAMP 最大时间精确度

5.7 之后的版本(其实应该说5.6.5),在默认的秒精确度上,可以带小数,最多带6位小数,即可以精确到 microseconds (6 digits) precision。

Type Range Remark
DATETIME ‘1000-01-01 00:00:00.000000’ to ‘9999-12-31 23:59:59.999999’ ‘YYYY-MM-DD hh:mm:ss[.fraction]’
TIMESTAMP ‘1970-01-01 00:00:01.000000’ to ‘2038-01-19 03:14:07.999999’ ‘YYYY-MM-DD hh:mm:ss[.fraction]’

3.DATETIME和TIMESTAMP 区别

(1) 时间范围不一样,TIMESTAMP 要小很多 ,且最大范围为2038-01-19 03:14:07.999999,到期也不远了。

(2)对于TIMESTAMP,它把客户端插入的时间从当前时区转化为UTC(世界标准时间)进行存储。查询时,将其又转化为客户端当前时区进行返回。 而对于DATETIME,不做任何改变,基本上是原样输入和输出。

MySQL converts TIMESTAMP values from the current time zone to UTC for storage, 
and back from UTC to the current time zone for retrieval. (This does not occur for other types such as DATETIME.)<br>
By default, the current time zone for each connection is the server's time. 
The time zone can be set on a per-connection basis. <br>
As long as the time zone setting remains constant, you get back the same value you store. 
If you store a TIMESTAMP value, and then change the time zone and retrieve the value, <br>
the retrieved value is different from the value you stored. 
This occurs because the same time zone was not used for conversion in both directions. <br>
The current time zone is available as the value of the time_zone system variable.

查看这种显示的时区时间设置

查询命令

show variables like '%time_zone%';

4.TIMESTAMP在新旧版本上的重大区别

TIMESTAMP 在mysql 5.6.5之后,TIMESTAMP(fraction)中的fraction代表的是小数位数,即默认秒,以秒为单位的小数点位数。 up to microseconds (6 digits) precision,最大为6.

超过6则报错:

ERROR 1426 (42000): Too-big precision 7 specified for 'hiredate'. Maximum is 6.

在比较久的版本上,这个数字就代表不同的意义,以下内容为旧版本的关于TIMESTAMP的知识。

TIMESTAMP(fraction)中fraction值显示尺寸的格式如下表所示:

列类型     显示格式
TIMESTAMP(14)      YYYYMMDDHHMMSS
TIMESTAMP(12)      YYMMDDHHMMSS
TIMESTAMP(10)      YYMMDDHHMM
TIMESTAMP(8)      YYYYMMDD
TIMESTAMP(6)      YYMMDD
TIMESTAMP(4)      YYMM
TIMESTAMP(2)      YY

就版本中“完整”TIMESTAMP格式是14位,但TIMESTAMP列也可以用更短的显示尺寸,创造最常见的显示尺寸是6、8、12、和14。

在创建表时可以指定一个任意的显示尺寸,但是定义列长为0或比14大均会被强制定义为列长14。列长在从1~13范围的奇数值尺寸均被强制为下一个更大的偶数。






参考资料

MySQL 时间类型 DATE、DATETIME和TIMESTAMP https://www.cnblogs.com/xuliuzai/p/10901425.html


返回