MySQL数据库常用的时间类型有timestamp和datetime,两者主要区别是占用存储空间长度不一致、可存储的时间也有限制,但针对不同版本下,timestamp字段类型的设置需要慎重,因为不注意的可能会被“坑死”。

一、TIMESTAMP和DATETIME字段类型对比

字段类型

存储长度

时间范围

备注

timestamp

4字节

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

datetime

8字节(5.7占5字节)

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

1.timestamp注意事项

(1)5.7版本之前,没有explicit_defaults_for_timestamp 参数(5.7默认开启,timestamp不会设置default值属性),timestamp字段默认存在default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP属性,默认值针对的主要是以下函数产生的时间

These are CURRENT_TIMESTAMP(), NOW(), LOCALTIME, LOCALTIME(), LOCALTIMESTAMP, and LOCALTIMESTAMP().

(2)mysql的timestamp值自动从当前时区转换到utc时区存储,并且自动从utc时区转换为当前系统时区检索返回

官方参考文档:https://dev.mysql.com/doc/refman/5.7/en/datetime.html

MySQL converts TIMESTAMP valuesfrom 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.) By default, the current time zone for each connection is the server's time.

2.datetime注意事项:

在mysql5.7之后,datetime字段也可以指定默认值,并且格式和timestamp一样

CREATE TABLE t1 (

ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

dt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

);

DEFAULT0 or DEFAULT '2000-01-01 00:00:00'

二、数据库时区参数

1.system_time_zone

数据库实例启动,从my.cnf配置参数timezone=timezone_name获取,若my.cnf未设置则从操作系统获取环境变量TZ获取

2.time_zone

数据库当前实际使用的时区,默认为system,即系统时区,其设置可以通过set global time_zone=''设置,其中参数值有以下三种形式:'SYSTEM' 、'+10:00' 、'Europe/Helsinki'

Linux时区知识扩展:

Linux将时钟分为系统时钟(System Clock)和硬件(Real Time Clock,简称RTC)时钟两种。系统时间是指当前Linux Kernel中的时钟,

而硬件时钟则是主板上由电池供电的那个主板硬件时钟,这个时钟可以在BIOS的"Standard BIOS Feture"项中进行设置。

系统时钟:

所有操作系统命令、函数依赖的时钟,独立于硬件时钟运行,可通过date设置

设置系统时间:date-s "2017-08-22 22:58:00"查看时区:date-R

硬件时钟:

Linux启动从系统配置获取

查看硬件时钟:clock--show 、 hwclock --show

设置硬件时钟:hwclock/clock --set --date="月/日/年 时:分:秒"系统时钟同步到硬件:/sbin/clock -w

硬件时钟同步到系统:/sbin/clock -s

时区设置:

修改/etc/sysconfig/clock

ZONE=Asia/Shanghai

rm/etc/localtime

链接到上海时区文件

ln-sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

执行完上述过程后,重启机器,即可看到时区已经更改。

三、实际使用实例

1.不同版本下timestamp和datetime使用实例

(1)测试timestamp和datetime创建带默认值的表

同时执行创建带默认值的SQL语句,发现5.6(不含5.6)之前版本datetime不支持带DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

CREATE TABLE test (

ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

dt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

);

5.0.67版本ERROR1067 (42000): Invalid default value for 'dt'

5.5.20版本ERROR1067 (42000): Invalid default value for 'dt'

5.6.22版本Query OK,0 rows affected (0.02sec)5.7.18版本Query OK,0 rows affected (0.00 sec)

(2)测试timestamp和datetime创建表结构类型

不指定默认值的情况下创建表结构,发现5.6(不含5.6)timestamp默认值是CURRENT_TIMESTAMP并且随着记录更新而更新

CREATE TABLE test01 (

ts TIMESTAMP ,

dt DATETIME

);5.0.67版本

CREATE TABLE `test01` (

`ts` timestamp NOT NULLdefaultCURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,

`dt` datetimedefaultNULL

) ENGINE=InnoDB DEFAULT CHARSET=latin15.5.20版本

CREATE TABLE `test01` (

`ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

`dt` datetime DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb45.6.22版本

CREATE TABLE `test01` (

`ts` timestamp NULL DEFAULT NULL,

`dt` datetime DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf85.7.18版本

CREATE TABLE `test01` (

`ts` timestamp NULL DEFAULT NULL,

`dt` datetime DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8

(3)、测试timestamp和datetime类型mysqldump导出导入影响

测试结论为,timestamp数据类型的记录导出会以utc时间格式导出,导入库中自动由UTC格式转为系统默认时区,所以看到导出文件timestamp内容时间戳和实际存储的不相符。

如果需要看到和导入与实际相符的时间戳,需要加入参数--tz-utc=false用于禁止timestamp时区转换,默认是开启的,即导出文件中开头设置的/*!40103 SET TIME_ZONE='+00:00' */;

系统默认是cst时区,数据库参数设置也是CST和SYSTEM,根据系统时间插入数据:

| system_time_zone | CST    |

| time_zone            | SYSTEM |

insert into test01 values(sysdate(),sysdate());5.0.67版本select * fromtest01;+---------------------+---------------------+

| ts | dt |

+---------------------+---------------------+

| 2018-01-12 14:15:19 | 2018-01-12 14:15:19 |

+---------------------+---------------------+

5.5.20版本select * fromtest01;+---------------------+---------------------+

| ts | dt |

+---------------------+---------------------+

| 2018-01-12 14:15:27 | 2018-01-12 14:15:27 |

+---------------------+---------------------+

5.6.22版本select * fromtest01;+---------------------+---------------------+

| ts | dt |

+---------------------+---------------------+

| 2018-01-07 20:13:22 | 2018-01-07 20:13:22 |

+---------------------+---------------------+

5.7.18版本select * fromtest01;+---------------------+---------------------+

| ts | dt |

+---------------------+---------------------+

| 2018-01-07 20:13:20 | 2018-01-07 20:13:20 |

+---------------------+---------------------+

然后将数据库表test01表利用mysqldump导出

mysqldump dbtest --tables test01 >test01.sql5.0.67版本-- MySQL dump 10.11

--

--Host: localhost Database: dbtest-- ------------------------------------------------------

-- Server version 5.0.67-percona-highperf-log/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE*/;/*!40103 SET TIME_ZONE='+00:00'*/;--

-- Table structure fortable `test01`--DROP TABLE IF EXISTS `test01`;

SET @saved_cs_client=@@character_set_client;

SET character_set_client=utf8;

CREATE TABLE `test01` (

`ts` timestamp NOT NULLdefaultCURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,

`dt` datetimedefaultNULL

) ENGINE=InnoDB DEFAULT CHARSET=latin1;

SET character_set_client=@saved_cs_client;--

-- Dumping data fortable `test01`--LOCK TABLES `test01` WRITE;/*!40000 ALTER TABLE `test01` DISABLE KEYS*/;

INSERT INTO `test01` VALUES ('2018-01-12 06:15:19','2018-01-12 14:15:19');/*!40000 ALTER TABLE `test01` ENABLE KEYS*/;

UNLOCK TABLES;/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE*/;-- Dump completed on 2018-01-12 6:22:25

5.5.20版本-- MySQL dump 10.13 Distrib 5.5.20, forLinux (x86_64)--

--Host: localhost Database: dbtest-- ------------------------------------------------------

-- Server version 5.5.20-rel24.1-log/*!40101 SET NAMES utf8*/;/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE*/;/*!40103 SET TIME_ZONE='+00:00'*/;--

-- Table structure fortable `test01`--DROP TABLE IF EXISTS `test01`;/*!40101 SET @saved_cs_client = @@character_set_client*/;/*!40101 SET character_set_client = utf8*/;

CREATE TABLE `test01` (

`ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

`dt` datetime DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;/*!40101 SET character_set_client = @saved_cs_client*/;--

-- Dumping data fortable `test01`--LOCK TABLES `test01` WRITE;/*!40000 ALTER TABLE `test01` DISABLE KEYS*/;

INSERT INTO `test01` VALUES ('2018-01-12 06:15:27','2018-01-12 14:15:27');/*!40000 ALTER TABLE `test01` ENABLE KEYS*/;

UNLOCK TABLES;/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE*/;-- Dump completed on 2018-01-12 14:22:32

5.6.22版本-- MySQL dump 10.13 Distrib 5.6.22-71.0, forLinux (x86_64)--

--Host: localhost Database: dbtest-- ------------------------------------------------------

-- Server version 5.6.22-71.0-log/*!40101 SET NAMES utf8*/;/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE*/;/*!40103 SET TIME_ZONE='+00:00'*/;--

-- Table structure fortable `test01`--DROP TABLE IF EXISTS `test01`;/*!40101 SET @saved_cs_client = @@character_set_client*/;/*!40101 SET character_set_client = utf8*/;

CREATE TABLE `test01` (

`ts` timestamp NULL DEFAULT NULL,

`dt` datetime DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8;/*!40101 SET character_set_client = @saved_cs_client*/;--

-- Dumping data fortable `test01`--LOCK TABLES `test01` WRITE;/*!40000 ALTER TABLE `test01` DISABLE KEYS*/;

INSERT INTO `test01` VALUES ('2018-01-07 12:13:22','2018-01-07 20:13:22');/*!40000 ALTER TABLE `test01` ENABLE KEYS*/;

UNLOCK TABLES;/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE*/;-- Dump completed on 2018-01-07 20:20:29

5.7.18版本-- MySQL dump 10.13 Distrib 5.7.18-15, forLinux (x86_64)--

--Host: localhost Database: dbtest-- ------------------------------------------------------

-- Server version 5.7.18-15-log/*!40101 SET NAMES utf8*/;/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE*/;/*!40103 SET TIME_ZONE='+00:00'*/;--

-- Table structure fortable `test01`--DROP TABLE IF EXISTS `test01`;/*!40101 SET @saved_cs_client = @@character_set_client*/;/*!40101 SET character_set_client = utf8*/;

CREATE TABLE `test01` (

`ts` timestamp NULL DEFAULT NULL,

`dt` datetime DEFAULT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8;/*!40101 SET character_set_client = @saved_cs_client*/;--

-- Dumping data fortable `test01`--LOCK TABLES `test01` WRITE;/*!40000 ALTER TABLE `test01` DISABLE KEYS*/;

INSERT INTO `test01` VALUES ('2018-01-07 12:13:20','2018-01-07 20:13:20');/*!40000 ALTER TABLE `test01` ENABLE KEYS*/;

UNLOCK TABLES;/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE*/;-- Dump completed on 2018-01-07 20:20:29

删除test01表,并用mysqldump导出文件还原

mysql -D dbtest -e "drop tables test01"mysql-D dbtest

| ts | dt |

+---------------------+---------------------+

| 2018-01-12 14:15:19 | 2018-01-12 14:15:19 |

+---------------------+---------------------+

5.5.20版本+---------------------+---------------------+

| ts | dt |

+---------------------+---------------------+

| 2018-01-12 14:15:27 | 2018-01-12 14:15:27 |

+---------------------+---------------------+

5.6.22版本+---------------------+---------------------+

| ts | dt |

+---------------------+---------------------+

| 2018-01-07 20:13:22 | 2018-01-07 20:13:22 |

+---------------------+---------------------+

5.7.18版本+---------------------+---------------------+

| ts | dt |

+---------------------+---------------------+

| 2018-01-07 20:13:20 | 2018-01-07 20:13:20 |

+---------------------+---------------------+

(4)ON UPDATE CURRENT_TIMESTAMP属性影响

如果包含ON UPDATE CURRENT_TIMESTAMP属性,则如果对表记录更新,此记录对应的timestamp类型记录也会更新

ts字段是timestamp类型且含有on update current_timestamp属性,dt字段是datetime类型且不含on update current_timestamp属性

更新前:

mysql-D dbtest -e "select * from test01;"

+---------------------+---------------------+------+

| ts | dt | id |

+---------------------+---------------------+------+

| 2018-01-12 14:15:19 | 2018-01-12 14:15:19 | NULL |

+---------------------+---------------------+------+更新:

mysql-D dbtest -e "update test01 set id=1 where id is null"更新后:

mysql-D dbtest -e "select * from test01;"Logging to file'/home/mysql/query.log'

+---------------------+---------------------+------+

| ts | dt | id |

+---------------------+---------------------+------+

| 2018-01-12 15:42:15 | 2018-01-12 14:15:19 | 1 |

+---------------------+---------------------+------+

2.不同版本下mysqldump结束时间分析

使用mysqldump备份的同仁都可能会注意到,正常备份结束的话,在文件结尾会有一条成功结束的表示,即 :-- Dump completed on 2018-01-12  6:22:25。

这个在mysql5.0后可以通过一些参数控制,例如可以加参数--comments=false来禁止添加comments信息,即所有--开头的comment会不记录在备份文件中,也可以增加--dump-date=false来禁止时间戳添加,即只包含-- Dump completed。

但特别需要注意的是,此时间戳的由来在mysqldump 10.11版本(mysql5.0.x版本对应MySQL dump 10.11, 含10.11版本)记录的是UTC时区时间戳,而在mysqldump 10.12版本之后(mysql 5.5对应的版本是MySQL dump 10.13,含10.13)记录的是系统当前时区时间戳。

所以大家看到的是mysqldump 10.11备份结束的时间总是比系统当前时间提前8小时,例如mysql5.0系统当前是CST时区:2018-01-12  14:22:25  而备份文件结束时间戳是-- Dump completed on 2018-01-12  6:22:25。这个只是记录的时间戳不同,不影响最终的数据记录时间。

源码片段如下:

./client/mysqldump.c

#define DUMP_VERSION "10.13"

static void write_footer(FILE *sql_file)

{if(opt_xml)

{

fputs("\n", sql_file);

check_io(sql_file);

}else if (!opt_compact)

{if(opt_tz_utc)

fprintf(sql_file,"/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;\n");

fprintf(sql_file,"\n/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;\n");if (!path)

{

fprintf(md_result_file,"\

/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS*/;\n\/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS*/;\n");

}if(opt_set_charset)

fprintf(sql_file,"/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;\n"

"/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\n"

"/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n");

fprintf(sql_file,"/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;\n");

fputs("\n", sql_file);if(opt_dump_date)

{char time_str[20];

get_date(time_str, GETDATE_DATE_TIME,0);

print_comment(sql_file, 0, "-- Dump completed on %s\n", time_str);

}elseprint_comment(sql_file,0, "-- Dump completed\n");

check_io(sql_file);

}

}/*write_footer*/

linux mysql timestamp_MySQL时间类型Timestamp和Datetime 的深入理解相关推荐

  1. mysql字段时间类型报异常Data truncation: Incorrect datetime value: ‘2099-01-01 00:00:00‘ for column

    更新某日期字段报如下异常: ### Cause: com.mysql.cj.jdbc.exceptions.MysqlDataTruncation: Data truncation: Incorrec ...

  2. mysql 数据库时间类型 datetime 数据在页面上显示一串数字, 用函数date_format( )转换格式 ;

    mysql 数据库时间类型 datetime 转换格式 数据库时间字段datetime可以使用date_format( )函数进行时间的转换. 数据库时间字段类型: 数据库查询结果: 没转换前页面显示 ...

  3. MySQL的时间类型

    MySQL的时间类型 首先可以将使用字符串类型来表示时间类型排除掉:字符串占用需要 19字节,占用的空间比较大.其次字符串表示的时间比较.处理比较麻烦,不能使用时间函数,比如:YEAR() 所以MyS ...

  4. MySQL数据库时间类型datetime、bigint、timestamp的查询效率比较

    以下文章来源方志朋的博客,回复"666"获面试宝典 来源:https://juejin.im/post/6844903701094596615 数据库中可以用datetime.bi ...

  5. mysql show timestamp_MySQL中有关TIMESTAMP和DATETIME的总结

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

  6. mysql date time类型_数据库datetime是什么类型

    展开全部 datetime类型:可用于需要同时包含日期和时间信息的值. datetime:MySQL 以 'YYYY-MM-DD HH:mm:ss'格式检32313133353236313431303 ...

  7. mysql 有always on么,mysql 关于时间类型的刨坑之路

    前两天有做一个基于binglog的数据库实时同步,一张老数据表里有DATETIME.TIMESTAMP不同的时间字段类型,看起来值都是一样的,并且默认值都设置的 0000-00-00 00:00:00 ...

  8. MySQL 日期时间类型怎么选?千万不要乱用!

    构建数据库写程序避免不了使用日期和时间,对于数据库来说,有多种日期时间字段可供选择,如 timestamp 和 datetime 以及使用 int 来存储 unix timestamp. 不仅新手,包 ...

  9. mysql中存储日期的类型_选择合适的 MySQL 日期时间类型来存储你的时间

    推荐阅读(点击即可跳转阅读) 构建数据库写程序避免不了使用日期和时间,对于数据库来说,有多种日期时间字段可供选择,如 timestamp 和 datetime 以及使用 int 来存储 unix ti ...

最新文章

  1. 模拟post请求--测试api是否可用--再交给ios开发
  2. 时间序列预测:I概述
  3. MyBatis-Oracle-selectKey返回主键
  4. 政企联手打造智慧城市产业
  5. EFI下WIN8.1和Ubuntu的双系统安装
  6. 计算机设计大赛无人车挑战赛
  7. ssh连接docker容器
  8. 胡因梦-生命的不可思议
  9. HTML5实现手机QQ表情功能
  10. 【C语言】打印杨辉三角形
  11. JS对浏览器地址的操作
  12. linux入门学习(3权限管理)
  13. 南怀瑾:如何静坐(附视频)
  14. webofscience入口注册_Web of Science科研数据库平台
  15. ThinkPHP 入手
  16. h5滚动时侧滑出现_HTML5移动端触摸事件以及滑动翻页效果
  17. Lind.DDD.IoC依赖注入与面向方面的实现
  18. 提权系列(一)----Windows Service 服务器提权初识与exp提权,mysql提权
  19. 基石为勤能补拙的迷宫之旅——第十天(Python函数参数)
  20. 新中大SE(ngpower)反月结、反记账

热门文章

  1. python修改密码业务_Python: 修改LDAP密码
  2. c语言中memcpy函数_带有示例的C中的memcpy()函数
  3. Log4j漏洞?一行代码都不改就能永久修复?
  4. 轮询锁使用时遇到的问题与解决方案!
  5. HashMap 为什么会导致 CPU 100%?文章看不懂?来看这个视频吧!——面试突击 006 期...
  6. linux localhost的修改
  7. WordPress网站搬家教程(根目录程序+ MySQL数据库)
  8. YOLOv3实现鱼类目标检测
  9. hive序列生成_常见的序列化框架及Protobuf原理
  10. ASP.NET Web API简单学习