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 kill不掉线程的原因
May 07 MySQL
带你学习MySQL执行计划
May 31 MySQL
mysql外连接与内连接查询的不同之处
Jun 03 MySQL
MySQL 十大常用字符串函数详解
Jun 30 MySQL
mysql连接查询中and与where的区别浅析
Jul 01 MySQL
MySQL里面的子查询的基本使用
Aug 02 MySQL
SQL 聚合、分组和排序
Nov 11 MySQL
mysql中varchar类型的日期进行比较、排序等操作的实现
Nov 17 MySQL
MySQL优化及索引解析
Mar 17 MySQL
MySQ InnoDB和MyISAM存储引擎介绍
Apr 26 MySQL
mysql实现将字符串字段转为数字排序或比大小
Jun 14 MySQL
MySQL常用慢查询分析工具详解
Aug 14 MySQL
仅用一句SQL更新整张表的涨跌幅、涨跌率的解决方案
May 06 #MySQL
MySQL创建高性能索引的全步骤
将图片保存到mysql数据库并展示在前端页面的实现代码
MySQL的join buffer原理
Apr 29 #MySQL
Mysql服务添加 iptables防火墙策略的方案
Apr 29 #MySQL
MySQL数据迁移相关总结
MySQL慢查询的坑
You might like
163的邮件用phpmailer发送(实例详解)
2013/06/24 PHP
PHP获取文本框、密码域、按钮的值实例代码
2017/04/19 PHP
PHP实现负载均衡下的session共用功能
2018/04/17 PHP
基于jquery的实现简单的表格中增加或删除下一行
2010/08/01 Javascript
javascript arguments使用示例
2014/12/16 Javascript
javascript实现3D切换焦点图
2015/10/16 Javascript
jQuery Mobile操作HTML5的常用函数总结
2016/05/17 Javascript
JS中对Cookie的操作详解
2016/08/05 Javascript
AngularJs bootstrap搭载前台框架——准备工作
2016/09/01 Javascript
jQuery插件zTree实现单独选中根节点中第一个节点示例
2017/03/08 Javascript
纯js的右下角弹窗实例
2017/03/12 Javascript
VUE实现表单元素双向绑定(总结)
2017/08/08 Javascript
js构建二叉树进行数值数组的去重与优化详解
2018/03/26 Javascript
解决angularjs前后端分离调用接口传递中文时中文乱码的问题
2018/08/13 Javascript
vue+springboot实现项目的CORS跨域请求
2018/09/05 Javascript
vue引入axios同源跨域问题
2018/09/27 Javascript
详解mpvue中使用vant时需要注意的onChange事件的坑
2019/05/16 Javascript
Python的Django框架中自定义模版标签的示例
2015/07/20 Python
对numpy中数组元素的统一赋值实例
2018/04/04 Python
详解pyqt5 动画在QThread线程中无法运行问题
2018/05/05 Python
Pandas 合并多个Dataframe(merge,concat)的方法
2018/06/08 Python
Python理解递归的方法总结
2019/01/28 Python
Python用Try语句捕获异常的实例方法
2019/06/26 Python
HTML table 表格边框的实现思路
2019/10/12 HTML / CSS
html5自定义video标签的海报与播放按钮功能
2019/12/04 HTML / CSS
尤为Wconcept中国官网:韩国设计师品牌服饰
2019/01/10 全球购物
土耳其玩具商店:Toyzz Shop
2019/08/02 全球购物
运动会稿件300字
2014/02/14 职场文书
售后服务经理岗位职责
2014/02/25 职场文书
2014年毕业演讲稿范文
2014/05/13 职场文书
竞选学委演讲稿
2014/09/13 职场文书
初三学生语文考试作弊检讨书
2014/12/14 职场文书
迟到检讨书
2015/01/26 职场文书
2015年社区纪检工作总结
2015/04/21 职场文书
dubbo集成zipkin获取Traceid的实现
2021/07/26 Java/Android
Zabbix对Kafka topic积压数据监控的问题(bug优化)
2022/07/07 Servers