MySQL时间设置注意事项的深入总结
作者:Kevin崔 发布时间:2024-01-16 04:39:52
时间真的存在吗?有观点认为,时间只是人类构想出来的一种概念,是用来衡量事物变化的标准。对于数据库来说时间伴随着数据并进。进入MySQL时间漩涡中看看。
1.时间类型的字段
MySQL时间类型字段:
下面的容易忽略的内容:
TIMESTAMP保存数据方式:
MySQL将TIMESTAMP值从当前时区转换为UTC进行存储,并从UTC返回到当前时区进行检索。
(这不适用于其他类型,比如DATETIME。)默认情况下,每个连接的当前时区是服务器的时间。时区可以在每个连接的基础上设置。只要时区设置保持不变,就会返回所存储的相同值。如果存储一个时间戳值,然后更改时区并检索该值,则检索到的值与存储的值不同。出现这种情况是因为没有在两个方向上使用相同的时区进行转换。当前时区可以作为time_zone系统变量的值。
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 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属性声明。这些属性必须显式指定。
测试:
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配置文件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不要轻易改动。
来源:https://www.modb.pro/db/53474


猜你喜欢
- 引文: 长期以来,多媒体信息在计算机中都是以文件形式存放,由操作系统管理的,但是随着计算机网络,分布式计算的发展,对多媒体信息进行高效的管理
- 本文实例为大家分享了Python KNN分类算法的具体代码,供大家参考,具体内容如下KNN分类算法应该算得上是机器学习中最简单的分类算法了,
- 这篇文章主要介绍了深入了解如何基于Python读写Kafka,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需
- 现在有一id=test的下拉框,怎么拿到选中的那个值呢? 分别使用javascript原生的方法和jquery方法 <select i
- 之前想爬取一些淘宝的数据,后来发现需要登录,找了很多的资料,有个使用request的sessions加上cookie来登录的,cookie的
- WITH ROLLUP 在生成包含小计和合计的报表时,ROLLUP 运算符很有用。ROLLUP 运算符生成的结果集类似于 CUBE 运算符所
- 在查询语句中使用 NOLOCK 和 READPAST 处理一个数据库死锁的异常时候,其中一个建议就是使用 NOLOCK 或者 READPAS
- 有时在处理不规则数据时需要提取文本包含的时间日期。dateutil.parser模块可以统一日期字符串格式。datefinder模块可以在字
- 一、JS介绍  Javascript是一种由Netscape(网景)的LiveScript发展而来的原型
- 多元正态分布(多元高斯分布)直接从多元正态分布讲起。多元正态分布公式如下:这就是多元正态分布的定义,均值好理解,就是高斯分布的概率分布值最大
- 模拟浏览器进行网页加载,当requests,urllib无法正常获取网页内容的时候一、声明浏览器对象注意点一,Python文件名或者包名不要
- 用于匹配的正则表达式为 :([1-9]\d*\.?\d*)|(0\.\d*[1-9])([1-9] :匹配1~9的数字;\d :匹配数字,包
- 对于regex库的使用不难,因为本身就是python中自带的库,所以在调用上也是常见的库使用类型,大部分时候都是用于搜索上下文信息的,但是有
- Pandas 按周、月、年、统计数据介绍将日期转为时间格式 并设置为索引import pandas as pddata=pd.read_ex
- 数组转换成切片a := [10]int{}fmt.Println(a) s1 := a[:10] //取前10个元素
- 作用:调用方法改为调用对象, 比如 : p.set_name() 改为 p.set_name区别:前者改变get方法,后者改变set方法效果
- 目录1、mysqldump执行过程:特点2、导出 CSV 文件(最灵活)执行过程特点3、物理拷贝(最快)过程局限总结1、mysqldump执
- 包的使用1.首次导入模块发生的事情3件事情先产生一个执行文件的名称空间:1.创建模块文件的名称空间2.执行模块文件中的代码 将产生的名字放入
- Python import的搜索路径import的搜索路径为:搜索「内置模块」(built-in module)搜索 sys.path 中的
- 使用python + shell 编写,是一个简易solaris系统巡检程序#!/usr/bin/python -u#-*- coding: