news 2026/5/15 17:44:20

VARCHAR 存日期的灾难

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
VARCHAR 存日期的灾难

VARCHAR 存日期的灾难

最近整理老项目代码,又看到有人把日期存在 VARCHAR 字段里,真的是血压都上来了。可能刚入行的朋友觉得,不就是存个日期吗?用字符串存还方便,想怎么写就怎么写,反正能显示出来就行。但只要你踩过一次坑,就知道这玩意儿有多坑人,今天就跟大家聊聊我踩过的这些雷。

先说说最直观的问题:格式乱成一锅粥。我见过的 VARCHAR 存日期的写法,没有一百种也有八十种。比如存2024年1月19日,有人写“2024-01-19”,有人写“2024/01/19”,还有人图省事写“20240119”,甚至还有“24-01-19”“2024年1月19日”这种写法。

你以为只是看着乱?实际用的时候才是真头疼。比如我要查2024年2月的所有数据,要是用 DATE 类型,一句WHERE create_time BETWEEN '2024-02-01' AND '2024-02-29'就搞定了。但如果是 VARCHAR 字段,你得把各种格式都考虑到,写出来的 SQL 能长到离谱:

-- VARCHAR存日期的查询,得兼容各种格式,还不一定能查全SELECT*FROMorder_infoWHEREcreate_timeLIKE'2024-02-%'ORcreate_timeLIKE'2024/02/%'ORcreate_timeLIKE'202402%'ORcreate_timeLIKE'24-02-%';

就这还不算完,要是有人手滑写成“2024-02-30”(2月根本没有30号),DATE 类型会直接报错不让存,但 VARCHAR 会照单全收,等你统计数据的时候才发现有这么个“幽灵日期”,排查半天都找不到问题在哪。

然后就是性能问题,这个我是真的深有体会。之前维护一个用户表,里面的 register_time 用 VARCHAR 存的,数据量到100万的时候,按时间范围查数据,慢得能等半分钟。后来改成 DATE 类型,加个索引,同样的查询1秒不到就出来了。

为啥差这么多?我认为核心原因是 VARCHAR 存的是字符串,数据库没法直接按时间大小排序、检索,只能全表扫描一个个比对;而 DATE 类型是有专门的存储格式的,索引能直接生效。给大家看个对比,同样是查近7天的数据:

-- VARCHAR字段,全表扫描,慢!EXPLAINSELECT*FROMuser_infoWHEREregister_time>='2024-01-12';-- 执行结果:type=ALL,rows=1000000(全表扫描100万行)-- DATE字段,走索引,快!EXPLAINSELECT*FROMuser_infoWHEREregister_time>='2024-01-12';-- 执行结果:type=range,rows=1000(只扫描符合条件的1000行)

而且 VARCHAR 存日期还特别占空间,比如“2024-01-19”是10个字符,占10个字节,而 DATE 类型只占3个字节,数据量越大,这个差距越明显,磁盘空间、内存都白白浪费了。

还有个容易被忽略的点:计算和排序会出问题。比如我想算两个日期之间的天数差,DATE 类型直接用 DATEDIFF 函数就行:

-- DATE类型计算天数差,简单准确SELECTDATEDIFF('2024-01-19','2024-01-10');-- 结果:9

但如果是 VARCHAR 字段,你得先把字符串转成日期类型,要是格式不统一,转换的时候直接报错:

-- VARCHAR类型计算,格式不对就报错SELECTDATEDIFF(STR_TO_DATE('2024/01/19','%Y/%m/%d'),STR_TO_DATE('24-01-10','%Y-%m-%d'));-- 报错:日期格式解析失败

排序就更坑了,字符串排序是按字符一个个比的,比如“2024-10-01”和“2024-02-01”,按 VARCHAR 排序,“2024-02-01”会排在“2024-10-01”后面,因为字符“0”比“1”小,但实际时间上2月明明在10月前面。

可能有人会说,我统一格式存 VARCHAR 不就行了?在我看来,这就是给自己找事。就算你定了规矩要存“YYYY-MM-DD”,也架不住有人手误写错,或者新来的同事不知道规矩乱存。数据库本身就提供了 DATE、DATETIME 这些专门存日期的类型,为啥非要用 VARCHAR 去凑活?

我们的经验是,只要是和时间相关的字段,不管是创建时间、更新时间还是业务日期,一律用 DATE/DATETIME/TIMESTAMP 类型。哪怕是一些特殊格式的时间,比如带时分秒的,用 DATETIME 存“2024-01-19 15:30:00”也比 VARCHAR 靠谱一万倍。

最后再总结下吧,用 VARCHAR 存日期,就像是用菜刀去拧螺丝,不是不能用,而是又慢又容易出问题,还伤自己。与其后期花大量时间排查格式、性能问题,不如一开始就选对数据类型,省下来的时间喝杯茶不香吗?

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/15 6:06:26

YOLOv8数据接口异常?API调用问题排查部署案例

YOLOv8数据接口异常?API调用问题排查部署案例 1. 引言:工业级目标检测的现实挑战 在智能制造、安防监控、零售分析等场景中,实时目标检测已成为不可或缺的技术能力。基于 Ultralytics YOLOv8 的“鹰眼目标检测”系统,凭借其高精…

作者头像 李华
网站建设 2026/5/9 17:55:57

通俗解释Zephyr驱动模型中的绑定与初始化流程

深入浅出 Zephyr 驱动初始化:从设备树到驱动就绪的全过程你有没有遇到过这样的问题?在写一个嵌入式驱动时,明明代码逻辑没问题,却因为某个外设还没初始化好就被调用了,导致系统卡死或数据异常。又或者,在移…

作者头像 李华
网站建设 2026/5/12 16:38:44

国产测试管理工具横向评测:从研发协同视角看Gitee Test的创新突破

国产测试管理工具横向评测:从研发协同视角看Gitee Test的创新突破 在数字化转型浪潮下,测试管理工具正从单一功能模块进化为贯穿研发全流程的协同中枢。近期行业调研显示,超过67%的科技企业正在评估或更换测试管理平台,其中研发协…

作者头像 李华
网站建设 2026/5/9 23:32:25

ESD管响应时间超ns级还能防静电击穿?

在消费电子的ESD测试中,常出现一种矛盾现象:ESD管标称响应时间1ns,却在8kV接触放电时后端IC击穿。问题根源在于对"响应时间"与"ESD速度"的错配理解。ESD脉冲的上升沿比多数工程师的认知快一个数量级,响应时间…

作者头像 李华
网站建设 2026/5/10 8:48:21

九款高效智能摘要与润色工具的性能评测及用户体验对比

核心工具对比速览 工具名称 主要功能 生成速度 适用场景 独特优势 AIBiye 论文全流程辅助 3-5分钟/万字 开题到定稿 实证研究自动生成 AICheck 文献综述专家 2分钟/篇 文献梳理阶段 知网文献智能解析 AskPaper 学术问答助手 实时响应 研究过程答疑 支持中英…

作者头像 李华
网站建设 2026/5/10 7:01:22

九大AI摘要生成与润色平台的性能评估及使用体验对比

核心工具对比速览 工具名称 主要功能 生成速度 适用场景 独特优势 AIBiye 论文全流程辅助 3-5分钟/万字 开题到定稿 实证研究自动生成 AICheck 文献综述专家 2分钟/篇 文献梳理阶段 知网文献智能解析 AskPaper 学术问答助手 实时响应 研究过程答疑 支持中英…

作者头像 李华