当前位置: 首页 > news >正文

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

http://www.cnnetsun.cn/news/701501.html

相关文章:

  • 实测Cute_Animal_For_Kids_Qwen_Image:儿童绘本创作神器体验
  • 图解说明T触发器在脉冲捕捉电路中的应用
  • Qwen3-VL视频动态理解实战:数小时内容秒级索引系统搭建教程
  • 11.4 仿真平台实践:NVIDIA Isaac Sim与Habitat
  • 【Linux命令大全】006.网络通讯之httpd命令(实操篇)
  • 用 MySQL SELECT SLEEP() 优雅模拟网络超时与并发死锁
  • 详解Agent Skills:让AI拥有更多专业能力(什么是Agent Skills?如何创建?如何使用?如何获取?)
  • 车辆经济性MATLAB计算程序
  • 基于 verl 框架和 ScaleBox 的代码强化学习实践
  • 文科创业内卷严重?跟紧时代潮流,打造核心竞争力,脱颖而出
  • 2026年网文大神都在用的秘密武器!5款写小说软件深度实测(附避坑指南)
  • 费马大定律代码化和定理《计算机科学中的数学》外扩学习1
  • 测试测试03
  • 当遇到ftsrch.dll系统文件丢失损坏问题 免费下载方法分享
  • 当遇到fveapi.dll系统文件丢失损坏问题 免费下载方法分享
  • 科研效率革命:paperxie 开题报告功能如何拯救你的学术焦虑
  • 治安管理处罚法:骂人违法
  • 来自微小偶极天线的近场和远场,用于单频激励的时变电场强度平面(Matlab代码实现)
  • 加密数据模糊查询:鱼与熊掌能否兼得?
  • 网页控件怎么实现大文件分片上传及目录结构上传源码?
  • 70_Spring AI 干货笔记之 STDIO 与 SSE MCP 服务器
  • 基于AI+热门图书推荐系统与数据可视化分析开发与研究
  • 基于AI+Spring Boot+微信小程序的宠物走失信息系统
  • 二分搜索(七)744. 寻找比目标字母大的最小字母 二分搜索基本题型
  • 突破万份临床文档分析瓶颈:大模型驱动知识图谱实现大规模实时临床分析平台
  • 基于深度学习的虾病害检测系统(YOLOv10+YOLO数据集+UI界面+Python项目源码+模型)
  • 3大实战策略:轻松解决LightGBM模型Java部署难题
  • 7步实战:将闲置电视盒子变身高性能Armbian服务器
  • 游戏辅助工具终极配置手册:从零开始轻松掌握YimMenu
  • Anthropic重磅报告:学历越高越被代替,但你越聪明AI就越聪明