【方向盘】MySql数据类型---日期时间类型的使用(含datetime和timestamp的区别) 0000-00-00 00:00:00问题解释(下)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 【方向盘】MySql数据类型---日期时间类型的使用(含datetime和timestamp的区别) 0000-00-00 00:00:00问题解释(下)

附:mysql中的date类型直接比较大小是按照字符串比较还是时间戳


Mysql在比较两种不同数据类型时,第一步是将他们转化为同一种类型,然后在比较。那么Date和String在比较的时候,一定是把String转化为Date吗?答案是Yes.


例子:


select * FROM test.orders where ceate_record_time > '2019'


结果截图:


image.png


为什么会出现 2018 的字符串?


再举个例子:如果是用字符串比较,“2004-04-31"这个string应该比2004-01-01这个date来得大,但是4-31是一个invalid的日期(4月是小月),会被转化成"0000-00-00”,所以2004-01-01 (日期) > “2014-04-31”。


所以,在存储方面:如果你是表示的时间,请尽量不要采用str类型来存储(虽然大多数情况下存入的效果一样,但不建议)。


在查询方面:如果你确实遇到的存储的是字符串,那么请用STR_TO_DATE函数转成日期格式在查询,形如:


select * from orders where date(str_to_date(`ceate_record_time`.`publish_date`,'%Y-%m-%d')) > '2019-0-0'

附:unsigned解释


整型的每一种都分有无符号(unsigned)和有符号(signed)两种类型(float和double总是带符号的),在默认情况下声明的整型变量都是有符号的类型。


如果需声明无符号类型的话就需要在类型前加上unsigned。无符号版本和有符号版本的区别就是无符号类型能保存2倍于有符号类型的正整数数据,比如16位系统中一个int能存储的数据的范围为-3276832767,而unsigned能存储的数据范围则是065535。由于在计算机中,整数是以补码形式存放的。根据最高位的不同,如果是1,有符号数的话就是负数;如果是无符号数,则都解释为正数。


简而言之就是由于Int型占4字节,也就是16位,2^16 = 65535,如果有符号位就+ -两边均分,如果没有就全给+


因此下面建表语句是被推荐的:


CREATE TABLE `fast_group_task` (
  `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  ...
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='批量组建班级的任务';


Java中的 '0000-00-00 00:00:00’问题


在我们的数据库定义中,经常可以看到类似这样的定义:

`start_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'


这样定义的隐患其实是比较大的。如果我们链接Mysql的Url参数上不作为,那么查询就会报错如下:


java.sql.SQLException: Value '0000-00-00 00:00:00' can not be represented as java.sql.Timestamp

通过此报错我们其实应该很敏感的得出两个结论:


1MySql是允许0000-00-00 00:00:00这样的值存在的(否则就会报SQL执行的错,而不是现在的封装成java.sql.Timestamp的错)


2.Java中(至少java.sql.Timestamp这个类)是不能支持到0000-00-00 00:00:00这个时间的。


// 这句语句报错,也能说明我们的Timestamp根本就不能表示这个时间~~~ 
// 最主要的是,这种时间没有任何实际意义,就连MySql存储它都采用的是假时间来存储的,强烈不建议使用
System.out.println(Timestamp.valueOf("0000-00-00 00:00:00")); 


我们的解决方案有两种:

1、jdbc的url后面,追加上参数:?zeroDateTimeBehavior=convertToNull,这样子Sql查出来的结果是null,Java进行封装就没有问题了

2、修改timestamp字段的默认值,不再采用0000-00-00 00:00:00(一般用当前时间)


总的来说,不要给数据库字段默认值设置为0000-00-00 00:00:00,完全是给自己找麻烦。


另外,JDK8已经完全普及了,强烈建议不再使用Date和Timestamp来表示时间,而使用JSR310的新规范,比老的更好用且功能更强大



相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
16天前
|
关系型数据库 MySQL
Mysql 中日期比较大小的方法有哪些?
在 MySQL 中,可以通过多种方法比较日期的大小,包括使用比较运算符、NOW() 函数、DATEDIFF 函数和 DATE 函数。这些方法可以帮助你筛选出特定日期范围内的记录,确保日期格式一致以避免错误。
|
30天前
|
存储 自然语言处理 关系型数据库
mysql 8.0 日期维度表生成(可运行)
mysql 8.0 日期维度表生成(可运行)
43 2
|
1月前
|
关系型数据库 MySQL 数据库
MySQL数据库基础(数据库操作,常用数据类型,表的操作)
MySQL数据库基础(数据库操作,常用数据类型,表的操作)
34 5
|
17天前
|
SQL NoSQL 关系型数据库
|
1月前
|
存储 关系型数据库 MySQL
MySQL支持多种数据类型
MySQL支持多种数据类型
99 3
|
1月前
|
存储 关系型数据库 MySQL
什么是mysql的数据类型?
什么是mysql的数据类型?
47 2
|
1月前
|
存储 关系型数据库 MySQL
MySQL数据类型
MySQL数据类型
52 2
|
1月前
|
关系型数据库 MySQL 数据处理
企业级应用 mysql 日期函数变量,干货已整理
本文详细介绍了如何在MySQL8.0中使用DATE_FORMAT函数进行日期格式的转换,包括当日、昨日及不同时间段的数据获取,并提供了实际的ETL应用场景和注意事项,有助于提升数据处理的灵活性和一致性。
41 0
|
9天前
|
SQL 关系型数据库 MySQL
go语言数据库中mysql驱动安装
【11月更文挑战第2天】
23 4
|
7天前
|
SQL 关系型数据库 MySQL
12 PHP配置数据库MySQL
路老师分享了PHP操作MySQL数据库的方法,包括安装并连接MySQL服务器、选择数据库、执行SQL语句(如插入、更新、删除和查询),以及将结果集返回到数组。通过具体示例代码,详细介绍了每一步的操作流程,帮助读者快速入门PHP与MySQL的交互。
20 1