MySQL时间设置注意事项的深入总结


Posted in MySQL onMay 06, 2021

时间真的存在吗?有观点认为,时间只是人类构想出来的一种概念,是用来衡量事物变化的标准。对于数据库来说时间伴随着数据并进。进入MySQL时间漩涡中看看。

1.时间类型的字段

MySQL时间类型字段:

MySQL时间设置注意事项的深入总结

下面的容易忽略的内容:

TIMESTAMP保存数据方式:

MySQL将TIMESTAMP值从当前时区转换为UTC进行存储,并从UTC返回到当前时区进行检索。
(这不适用于其他类型,比如DATETIME。)默认情况下,每个连接的当前时区是服务器的时间。时区可以在每个连接的基础上设置。只要时区设置保持不变,就会返回所存储的相同值。如果存储一个时间戳值,然后更改时区并检索该值,则检索到的值与存储的值不同。出现这种情况是因为没有在两个方向上使用相同的时区进行转换。当前时区可以作为time_zone系统变量的值。

MySQL时间设置注意事项的深入总结

TIMESTAMP和SQL_MODE组合

sql_mode也会影响timestamp值:

mysql> CREATE TABLE ts (
         id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
         col TIMESTAMP NOT NULL
     ) AUTO_INCREMENT = 1;

mysql> SHOW VARIABLES LIKE  '%sql_mode%';
+---------------+---------------------+
| Variable_name | Value               |
+---------------+---------------------+
| sql_mode      | STRICT_TRANS_TABLES |
+---------------+---------------------+
mysql>  INSERT INTO ts (col) VALUES ('1969-01-01 01:01:10');
ERROR 1292 (22007): Incorrect datetime value: '1969-01-01 01:01:10' for column 'col' at row 1

mysql> SET sql_mode="";
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW VARIABLES LIKE  '%sql_mode%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sql_mode      |       |
+---------------+-------+
mysql>  INSERT INTO ts (col) VALUES ('1969-01-01 01:01:10'),('2999-01-01 01:01:10');
Query OK, 2 rows affected, 2 warnings (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 2
mysql> show warnings;
+---------+------+----------------------------------------------+
| Level   | Code | Message                                      |
+---------+------+----------------------------------------------+
| Warning | 1264 | Out of range value for column 'col' at row 1 |
| Warning | 1264 | Out of range value for column 'col' at row 2 |
+---------+------+----------------------------------------------+

mysql> SELECT * FROM TS;
+----+---------------------+
| id | col                 |
+----+---------------------+
|  1 | 0000-00-00 00:00:00 |
|  2 | 0000-00-00 00:00:00 |
+----+---------------------+
2 rows in set (0.00 sec)

通过控制sql_mode,超出timestamp限制值还是插入进去了,但采用的是0填空方式。
对于STRICT_TRANS_TABLES, MySQL将一个无效的值转换为最接近的有效值,然后插入调整后的值。如果缺少一个值,MySQL将为列数据类型插入隐式的默认值。

2.explicit_defaults_for_timestamp时间处理机制

MySQL时间设置注意事项的深入总结

默认情况是启用。

在MySQL 8.0.22中,如果试图在声明为TIMESTAMP NOT NULL的列中插入NULL,将会被拒绝,并产生错误。

1.explicit_defaults_for_timestamp被禁用时:

  • 没有使用NULL属性显式声明的时间戳列将自动使用NOT NULL属性声明。允许为这样的列赋值为NULL,并将该列设置为当前时间戳。在MySQL 8.0.22中,如果试图在声明为TIMESTAMP NOT NULL的列中插入NULL,将会被拒绝,并产生错误。
  • 如果表中的第一列没有使用NULL属性或显式的DEFAULT或ON UPDATE属性进行声明,则会自动使用默认的CURRENT_TIMESTAMP属性和ON UPDATE CURRENT_TIMESTAMP属性进行声明。
  • TIMESTAMP 如果没有显式地使用NULL属性或显式默认属性声明,则自动声明为默认的'0000-00-00 00:00:00'(“零”时间戳)
  • 根据启用的是strict SQL模式还是NO_ZERO_DATE SQL模式,默认值“0000-00-00 00:00:00”可能无效。

2.explicit_defaults_for_timestamp被启用:

  • 不可能为TIMESTAMP指定NULL值来将其设置为当前时间戳。要指定当前时间戳,设置为CURRENT_TIMESTAMP或一个同义词,比如NOW()。
  • 没有使用not NULL属性显式声明的TIMESTAMP列将自动使用NULL属性声明并允许空值。
  • 使用NOT NULL属性声明的时间戳列不允许空值。对于为这样的列指定NULL的插入,如果启用了strict SQL模式,那么单行插入会出现错误,或者禁用了strict SQL模式的多行插入会插入'0000-00-00 00:00:00'。在任何情况下,为列赋值为NULL都不会将其设置为当前时间戳。
  • 使用NOT NULL属性显式声明且没有显式默认属性的时间戳列被视为没有默认值。对于未为此类列指定显式值的插入行,结果取决于SQL模式。如果启用了严格SQL模式,则会出现错误。如果没有启用严格的SQL模式,则使用默认隐式值'0000-00-00 00:00:00'声明该列,并出现警告。
  • timestamp类型字段 不会自动使用默认的CURRENT_TIMESTAMP属性或更新CURRENT_TIMESTAMP属性声明。这些属性必须显式指定。

MySQL时间设置注意事项的深入总结

测试:

CREATE TABLE `test1`(
id bigint not null AUTO_INCREMENT COMMENT '主键ID', 
name varchar(20) COMMENT '主键ID',
create_time TIMESTAMP  NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'cr time',
PRIMARY KEY(id)
)ENGINE=InnoDB  AUTO_INCREMENT=1 ;
SHOW VARIABLES LIKE 'explicit_defaults_for_timestamp';
SET  GLOBAL  explicit_defaults_for_timestamp=ON;
SET  GLOBAL  explicit_defaults_for_timestamp=OFF;
INSERT INTO test1(id,name,create_time) VALUES(1,'Kit',NULL);

3.mysql系统配置

系统相关事件参数包含3个:

mysql>show global variables where Variable_name like '%time_zone%' or Variable_name like 'log_timestamp%';
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| system_time_zone | CST    |
| time_zone        | SYSTEM |
| log_timestamps   | UTC    |
+------------------+--------+
3 rows in set (0.00 sec)

1.system time zone:当服务器启动时,它尝试自动确定主机的时区,并使用它来设置system_time_zone系统变量。此后该值不会改变。

2.time_zone:全time_zone表示服务器当前运行的时区。初始的time_zone值为“SYSTEM”,表示服务器时区与系统时区一致。

  • 如果设置为SYSTEM, 如MySQL函数调用都会调用一个系统库来确定当前的系统时区。这个调用可能被一个全局互斥锁保护,从而导致争用。CPU使用率高问题。
  • 设置会话时区会影响时区敏感的时间值的显示和存储。这包括NOW()或CURTIME()等函数显示的值,以及存储在时间戳列中的值和从时间戳列检索到的值。时间戳列的值将从会话时区转换为UTC用于存储,从UTC转换为会话时区用于检索。
  • 会话时区设置不影响UTC_TIMESTAMP()等函数显示的值,也不影响DATE、time或DATETIME列中的值。这些数据类型的值也不存储在UTC;时区仅在从时间戳值转换时适用它们。

备注:mysql还提供时区导入到mysql系统库的方法。通过mysql_tzinfo_to_sql程序加载/usr/share/zoneinfom下的时区信息。

mysql> SELECT COUNT(*) FROM mysql.time_zone_name;
+----------+
| COUNT(*) |
+----------+
|        0 |
+----------+

##mysql_tzinfo_to_sql工具导入时区值

shell>mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql
mysql> SELECT COUNT(*) FROM mysql.time_zone_name;
+----------+
| COUNT(*) |
+----------+
|     1780 |
+----------+

3.log_timestamps

这个变量控制写入错误日志的消息以及写入文件的一般查询日志和慢速查询日志消息中的时间戳的时区。

它不会影响一般查询日志的时区和慢速查询日志消息写入表(mysql。general_log mysql.slow_log)。

允许的log_timestamps值是UTC(默认值)和SYSTEM(本地系统时区)

备注:UTC一般指协调世界时。协调世界时,又称世界统一时间、世界标准时间、国际协调时间,就是UTC+8小时=中国时间

当然值 需要跟系统记录时间一致,才能更好的管理。

#设置时区,更改为东八区
SET GLOBAL time_zone = '+8:00';

MySQL时间设置注意事项的深入总结

建议:

mysql配置文件my.cnf

[mysqld]
log_timestamps=SYSTEM
default-time_zone                  = '+8:00'
mysql>show global variables where Variable_name like '%time_zone%' or Variable_name like 'log_timestamp%';
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| log_timestamps   | SYSTEM |
| system_time_zone | CST    |
| time_zone        | +08:00 |
+------------------+--------+

总结

从时间类型,参数,系统时区了解到,MySQL里时间应该怎样设置和使用。

特别是无特殊要求sql_mode不要轻易改动。

到此这篇关于MySQL时间设置注意事项的文章就介绍到这了,更多相关MySQL时间设置注意内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

MySQL 相关文章推荐
MySQL之高可用集群部署及故障切换实现
Apr 22 MySQL
MySQL8.0.24版本Release Note的一些改进点
Apr 22 MySQL
MySQL时间设置注意事项的深入总结
May 06 MySQL
新手入门Mysql--sql执行过程
Jun 20 MySQL
MySQL 服务和数据库管理
Nov 11 MySQL
一文带你探究MySQL中的NULL
Nov 11 MySQL
MySQL数据库如何使用Shell进行连接
Apr 12 MySQL
MySQL数据库事务的四大特性
Apr 20 MySQL
MySQL的意向共享锁、意向排它锁和死锁
Jul 15 MySQL
MySQL的表级锁,行级锁,排它锁和共享锁
Jul 15 MySQL
了解MySQL查询语句执行过程(5大组件)
Aug 14 MySQL
MySQL使用IF语句及用case语句对条件并结果进行判断 
Sep 23 MySQL
仅用一句SQL更新整张表的涨跌幅、涨跌率的解决方案
May 06 #MySQL
MySQL创建高性能索引的全步骤
将图片保存到mysql数据库并展示在前端页面的实现代码
MySQL的join buffer原理
Apr 29 #MySQL
Mysql服务添加 iptables防火墙策略的方案
Apr 29 #MySQL
MySQL数据迁移相关总结
MySQL慢查询的坑
You might like
php下载远程文件类(支持断点续传)
2008/11/14 PHP
php实现通用的从数据库表读取数据到数组的函数实例
2015/03/21 PHP
指定位置如果有图片显示图片,无图片显示广告的JS
2010/06/05 Javascript
jQuery实现的手机发送验证码倒计时效果代码分享
2015/08/24 Javascript
jQuery使用Selectator插件实现多选下拉列表过滤框(附源码下载)
2016/04/08 Javascript
AngularJS利用Controller完成URL跳转
2016/08/09 Javascript
jQuery中的100个技巧汇总
2016/12/15 Javascript
vue-router+vuex addRoutes实现路由动态加载及菜单动态加载
2017/09/28 Javascript
JQuery选中select组件被选中的值方法
2018/03/08 jQuery
jQuery+ajax实现动态添加表格tr td功能示例
2018/04/23 jQuery
webpack打包nodejs项目的方法
2018/09/26 NodeJs
JavaScript两种计时器的实例讲解
2019/01/31 Javascript
使用 node.js 模仿 Apache 小部分功能
2019/07/07 Javascript
JavaScript中的各种宽高属性的实现
2020/05/08 Javascript
vue.js实现点击图标放大离开时缩小的代码
2021/01/27 Vue.js
[47:42]Fnatic vs Liquid 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Python设计模式之单例模式实例
2014/04/26 Python
详解python之简单主机批量管理工具
2017/01/27 Python
Python虚拟环境项目实例
2017/11/20 Python
python实现将文件夹下面的不是以py文件结尾的文件都过滤掉的方法
2018/10/21 Python
python内置数据类型之列表操作
2018/11/12 Python
OpenCV图像颜色反转算法详解
2019/05/13 Python
Python集中化管理平台Ansible介绍与YAML简介
2019/06/12 Python
金牌葡萄酒俱乐部:Gold Medal Wine Club
2017/11/02 全球购物
REN Clean Skincare官网:英国本土有机护肤品牌
2019/02/23 全球购物
eBay爱尔兰站:eBay.ie
2019/08/09 全球购物
Monki官网:斯堪的纳维亚的独立时尚品牌
2020/11/09 全球购物
英语硕士生求职简历的自我评价
2013/10/15 职场文书
酒店公关部经理岗位职责
2013/11/24 职场文书
希特勒经典演讲稿
2014/05/19 职场文书
劳模事迹材料范文
2014/12/24 职场文书
房地产公司财务总监岗位职责
2015/04/03 职场文书
机关工会工作总结2015
2015/05/26 职场文书
第一书记观后感
2015/06/08 职场文书
护士医德医风心得体会
2016/01/25 职场文书
小学秋季运动会加油口号及加油稿
2019/08/19 职场文书