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


本文整理自网络,侵删。

时间真的存在吗?有观点认为,时间只是人类构想出来的一种概念,是用来衡量事物变化的标准。对于数据库来说时间伴随着数据并进。进入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属性声明。这些属性必须显式指定。

阅读剩余部分

相关阅读 >>

详解mysql8.0​ 字典表增强

mysql中关于触发器的操作实例详解

mysql数据库的事务隔离和mvcc的详细介绍(图文)

mysql实现字符串截取的图文教程

mysql实现添加用户并授权

centos7 mysql数据库安装及配置实现教程

图文详解mysql5.7安装教程

mysql多久可以学会?

mysql求2个或以上字段为null值的实例分享

mysql 语法整理介绍

更多相关阅读请进入《mysql》频道 >>


数据库系统概念 第6版
书籍

数据库系统概念 第6版

机械工业出版社

本书主要讲述了数据模型、基于对象的数据库和XML、数据存储和查询、事务管理、体系结构等方面的内容。



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...