Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >MySQL datetime 类型精度设置踩坑

MySQL datetime 类型精度设置踩坑

作者头像
wayn
发布于 2025-05-26 03:35:43
发布于 2025-05-26 03:35:43
21200
代码可运行
举报
文章被收录于专栏:wayn的程序开发wayn的程序开发
运行总次数:0
代码可运行

数据库设计与开发过程中,时间类型的精度问题常常是引发数据错误的“隐形炸弹”。MySQLdatetime 类型作为常见的日期时间存储字段,其默认行为和精度设置对业务逻辑的影响尤为关键。

本文也是作者实际踩坑后结合实际案例,深入剖析 datetime 类型的精度问题,并提供解决方案和最佳实践。

一、datetime 类型的精度问题

1.1 默认精度限制

MySQL 的 datetime 类型默认仅精确到秒级(即不包含毫秒或微秒)。例如,插入值 2025-05-26 10:14:59.999 时,实际存储的值会被截断为 2025-05-26 10:15:00。这种行为在 MySQL 5.6.4 之前的版本中尤为常见,即使字段名显示为 datetime,实际存储时也会丢失小数部分的精度。

1.2 四舍五入与进位问题

当插入的毫秒值超过 0.5 秒时,MySQL 会自动进位。例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
INSERT INTO t_user (join_time) VALUES ('2025-05-26 10:14:59.765');

若字段未声明精度(即 datetime 而非 datetime(3)),存储结果将变为 2025-05-26 10:15:00,而非预期的 2025-05-26 10:14:59.765。这种行为可能导致业务逻辑中的时间计算错误(如订单超时判断、日志时间戳分析等)。

1.3 实际案例:毫秒级精度丢失引发的业务异常

某电商平台在处理订单结算时,发现部分订单的 end_time 字段在插入 TiDB 后,值从 2022-11-03 23:59:59.999 被进位为 2022-11-04 00:00:00。由于系统依赖此字段判断订单是否在当日有效,最终导致大量订单被错误标记为“过期”,造成客户投诉和财务损失。

二、问题根源分析

2.1 MySQL 版本差异

MySQL 5.6.4 之前datetime 类型不支持毫秒精度,插入值的小数部分会被直接丢弃或四舍五入。

MySQL 5.6.4 及之后:支持通过 datetime(fsp) 设置精度,其中 fsp 表示小数秒位数(0-6),例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE TABLE t_user (
    join_time DATETIME(3)  -- 精确到毫秒
);

2.2 客户端工具的显示误导

某些常用的客户端工具(如 Navicat)在设计表时默认将 datetime 的精度默认设置为 0,稍不注意就会踩坑。这种设计缺陷容易导致开发者误以为字段支持高精度存储。

没错,说的就是我 😂

2.3 时区与跨数据库兼容性

datetime 类型存储的是绝对时间(不包含时区信息),而 timestamp 类型会自动转换为当前会话的时区。在跨数据库迁移(如 MySQL 到 TiDB)时,若未统一时区设置,可能导致时间解析错误。

三、解决方案与最佳实践

3.1 显式声明精度

在设计表时,应根据业务需求显式声明 datetime 的精度

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ALTER TABLE t_user MODIFY join_time DATETIME(3);  -- 精确到毫秒
  • DATETIME(0):秒级精度(默认)。
  • DATETIME(3):毫秒级精度(3 位小数)。
  • DATETIME(6):微秒级精度(6 位小数)。

3.2 使用 TIMESTAMP 替代方案

若业务对时区敏感且需高精度,可考虑使用 TIMESTAMP 类型(支持毫秒级精度):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ALTER TABLE t_user MODIFY join_time TIMESTAMP(3);

但需注意 TIMESTAMP 的存储范围较小(1970-01-01 至 2038-01-19),且受服务器时区影响。

3.3 Java 中 Date 类型支持

Java 中 Date 类型默认支持毫秒级时间

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Date now = new Date();
System.out.println(DateUtil.format(now, "yyyy-MM-dd HH:mm:ss.SSS"));
输出:2025-05-26 10:39:15.002

而如果 MySql 中 datetime 类型没有设置精度,就很容易遇到 datetime 类型的自动进位问题,也是建议大家搭配 datetime(3),避免此问题。

四、性能与兼容性优化

4.1 索引优化

datetime 字段上创建索引时,需注意:

  • 避免全表扫描:对范围查询(如 WHERE join_time BETWEEN ...)使用索引。
  • 分区表:对大表按时间分区,提升查询效率。

4.2 时区一致性

尽量在代码层统一处理时区转换,避免依赖数据库的自动转换。

4.3 跨数据库兼容性

  • 在迁移数据库时(如 MySQL 到 TiDB),需验证目标数据库是否支持 datetime(fsp) 语法。
  • 对于 TiDB,需升级到 5.4 及以上版本以支持 DATETIME(6)

五、总结

MySQL 数据库设计中,应显式声明 datetime 精度、验证版本兼容性与工具链一致性,并通过开文档化时区策略与测试环境模拟,系统性规避时间精度陷阱,确保业务逻辑的稳定性和数据准确性。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-05-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 waynblog 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
MySQL 保存日期,用哪种数据类型合适?datetime?timestamp?还是 int?
日期算是我们在日常开发中经常用到的数据类型,一般来说一张表都有 createTime 和 updateTime 字段,MySQL 中针对日期也提供了很多种不同的数据类型,如: datetime timestamp int 等等。甚至也有人直接将日期存为字符串的。 那么到底该用哪种类型来保存日期呢? 1. 字符串 在这些类型中,首先应该排除掉的就是字符串了,很多新手小伙伴爱用字符串存储日期,但实际上这并不是一个很好的方案。 使用字符串存储日期,第一个显而易见的问题就是无法使用 MySQL 中提供的日期函数,
江南一点雨
2022/04/15
2.2K0
MySQL 保存日期,用哪种数据类型合适?datetime?timestamp?还是 int?
每天一道面试题之-mysql中datetime和timestamp的区别
了不起翻了个白眼:我问你,MySQL里面的字段类型datetime和timestamp有什么区别?
灬沙师弟
2023/07/08
3180
每天一道面试题之-mysql中datetime和timestamp的区别
MySQL时间戳2038年灾难:你的数据还能撑过去吗?
Timestamp 类型在MySQL中通常用于存储日期和时间。然而,Timestamp类型的一个限制是其存储范围,它使用4字节(32位)整数来表示秒数,从而导致在2038年01月19日03:14:07之后无法正确存储时间戳。这是因为32位整数最大可表示的秒数是2^31 - 1,即2147483647秒,相当于约68年。因此,如果使用了timestamp类型则需要考虑在达到时间范围前进行相应处理。
俊才
2023/11/16
6.7K0
MySQL时间戳2038年灾难:你的数据还能撑过去吗?
一个MySQL时间戳精度引发的血案
最近工作中遇到两例mysql时间戳相关的问题,一个是mysql-connector-java和msyql的精度不一致导致数据查不到;另一例是应用服务器时区错误导致数据查询不到。
猿天地
2019/09/17
3K0
一个MySQL时间戳精度引发的血案
MySQL中DATETIME与TIMESTAMP
真理永远都不过时,今天由于工作的事情涉及到了这里,印象中只记得DATETIME类型占用8字节,TIMESTAMP类型占用4字节,心想这么久没有更新的知识万一过时了咋办,毕竟MySQL8都有了,于是翻开了MySQL的官网,决定查一查这两个字段的区别。
江湖安得便相忘
2019/08/21
2.7K0
Mysql - date、datetime、timestamp 的区别
datetime 没有时区概念,客户端传什么时间就存什么时间,省去了转换时区的步骤
小菠萝测试笔记
2021/11/16
7.2K1
数据库存储时间你用对了吗?
我们平时在开发中不可避免的要存储时间,比如我们要记录某条数据的创建时间、更新时间等等。数据库中有多种数据类型可以存储时间,那不同数据类型我们要怎么选择?
Java识堂
2021/01/22
2.5K0
数据库存储时间你用对了吗?
MySQL: datetime vs timestamp
表person的create_time字段是datetime类型,modify_time是timestamp类型
十毛
2019/03/27
5.4K0
Mysql 时间类型精度截取的bug
mysql-connector-java版本升级出现的一次问题。涉及到了时间精度的截取和四舍五入。 首先了解一点,timestamp,datetime如果不指定精度,默认的精度是秒。 当mysql-connector-java版本<=5.1.22时,db的客户端会将Datetime,Timestamp秒以下的精度丢弃。版本>5.1.22后,秒以下的值将不会截断 db的server端会对超出精度位数的数据进行四舍五入!! 举个例子:在db建表时没指定精度时,插入精确到毫秒级别的日期 如果使用mysql-con
欠扁的小篮子
2018/07/04
3.1K0
MySQL 时间类型 DATE、DATETIME和TIMESTAMP
5.7 之后的版本(其实应该说5.6.5),在默认的秒精确度上,可以带小数,最多带6位小数,即可以精确到 microseconds (6 digits) precision。
星哥玩云
2022/08/18
3.2K0
MySQL 时间类型 DATE、DATETIME和TIMESTAMP
MySQL 8.0中DATE,DATETIME和 TIMESTAMP类型和5.7之间的差异
MySQL中DATE,DATETIME和 TIMESTAMP类型都和时间有关。本文介绍MySQL 8.0和MySQL 5.7之间的差异;本文MySQL实验环境为8.0.23;
SEian.G
2021/04/29
8.1K0
网易MySQL微专业学习笔记(一)-mysql数据类型
这个系列属于个人学习网易云课堂MySQL数据库工程师微专业的相关课程过程中的笔记,本篇为其“MySQL数据库对象与应用”中的MySQL数据类型相关笔记。
WindCoder
2018/09/19
7810
网易MySQL微专业学习笔记(一)-mysql数据类型
Mysql数据类型
在MySQL中支持的主要整数类型是TINYINT,SMALLINT,MEDIUMINT,INT 和 BIGINT。这些类型在很大程度上是相同的,只有它们存储的值的大小是不相同的。MySQL以一个可选的显示宽度指示器的形式对 SQL 标准进行扩展。当从数据库检索一个值时,可以把这个值加长到指定的长度。例如,指定一个字段的类型为 INT(6),就可以保证所包含数字少于 6 个的值从数据库中检索出来时能够自动地用空格填充。需要注意的是,使用一个宽度指示器不会影响字段的大小和它可以存储的值的范围。万一我们需要对一个字段存储一个超出许可范围的数字,MySQL 会根据允许范围最接近它的一端截短后再进行存储。还有一个比较特别的地方是,MySQL 会在不合规定的值插入表前自动修改为 0。
用户3876103
2024/11/03
2190
mysql基本数据类型
mysql数据库分多钟数据类型,大类可以分为三种:数值类型、时间(日期)和字符(串)类型。
OECOM
2020/07/01
1.5K0
探秘 MySQL 数据类型的艺术:性能与存储的精妙平衡
在数据库设计中,选择合适的数据类型对性能、存储效率和数据完整性至关重要。MySQL 提供了丰富的数据类型,帮助开发者更灵活地处理不同的数据需求。然而,不同的数据类型各有优缺点,了解这些特性可以帮助我们更高效地设计和管理数据库。本篇文章将深入探讨 MySQL 的主要数据类型、使用场景和优化建议,帮助读者在开发过程中做出明智的选择。
suye
2025/05/29
1520
探秘 MySQL 数据类型的艺术:性能与存储的精妙平衡
MySQL中的时间类型
时间是一类重要的数据,MySQL中有多种关于时间的类型可以选择。这篇文章主要介绍MySQL中的时间类型,主要参考MySQL文档:https://dev.mysql.com/doc/refman/8.0/en/date-and-time-types.html
valineliu
2022/08/30
11.1K1
MySQL中的时间类型
警告!别再使用 TIMESTAMP 作为日期字段~
点击上方蓝色字体,选择“设为星标” 回复”学习资料“获取学习宝典 来源:JAVA日知录 在日常数据库设计中,几乎每张业务表都带有一个日期列,用于记录每条记录产生和变更的时间。比如用户表会有一个日期列记录用户注册的时间、用户最后登录的时间。又比如,电商行业中的订单表(核心业务表)会有一个订单产生的时间列,当支付时间超过订单产生的时间,这个订单可能会被系统自动取消。 日期类型虽然常见,但在表结构设计中也容易犯错,比如很多开发同学都倾向使用整型存储日期类型,同时也会忽略不同日期类型对于性能可能存在的潜在影响。
猿天地
2022/03/24
1.2K0
浅析TIMESTAMP类型
日期与时间是非常重要的信息,在我们的系统中,几乎所有的数据表都用得到。原因是客户需要知道数据的时间标签,从而进行数据查询、统计和处理。因此,日期与时间类型也是我们最常用到的类型之一,今天就来聊一聊日期与时间类型中的TIMESTAMP类型。
GreatSQL社区
2023/02/23
1.7K0
smalldatetime mysql_SQLSERVER中datetime和smalldatetime类型分析说明「建议收藏」
Microsoft SQL Server 用两个 4 字节的整数内部存储 datetime 数据类型的值。第一个 4 字节存储 base date (即 1900 年 1 月 1 日)之前或之后的天数。基础日期是系统参考日期。不允许早于 1753 年 1 月 1 日的 datetime 值。第一个4 字节:1900 年1 月1 日当日为0 ;之前的日期是负数;之后日期是正数。另外一个 4 字节存储以午夜后3 1/3 毫秒数所代表的每天的时间。
全栈程序员站长
2022/08/26
2.6K0
MySQL 数据类型深度全栈实战,天花板玩法层出不穷!
在 MySQL 数据库的世界里,数据类型是构建高效、可靠数据库的基石。选择合适的数据类型,不仅能节省存储空间,还能提升数据查询和处理的性能
羑悻的小杀马特.
2025/05/11
790
MySQL 数据类型深度全栈实战,天花板玩法层出不穷!
相关推荐
MySQL 保存日期,用哪种数据类型合适?datetime?timestamp?还是 int?
更多 >
LV.5
安徽省刀锋网络科技有限公司后台开发
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验