改表的时候卡了半天,脑子里突然在想mysql数字类型有哪些,手边没有笔记,只能一点一点回忆之前写建表语句留下的印象,鼠标停在编辑器里,光标一闪一闪的,半天敲不出合适的字段类型。
最开始写的时候,随手就用int,不管存什么数值都往里面塞,订单编号、数量、积分,全部一股脑设成int,那时候根本没想过不同数字类型存的范围不一样,也没考虑过存储空间的差别。有一次做统计,存用户的点赞数量,预估不会太高,直接定了int,后面业务量涨上来,数值越堆越大,半夜收到告警,才意识到这个类型的上限快要摸到了,临时要改字段,锁表等了好一阵,线上接口断断续续卡着,那段时间心里一直悬着。
同事在旁边敲代码,瞥到我屏幕上的表语句,随口提了一句,很小的数字没必要都用int。
当时没太往心里去,还是习惯图省事,反正写起来都差不多,只是字段声明的单词换一下,谁能想到后面会多出一堆麻烦。存状态标识的时候,0和1就能搞定,依旧写int,后来翻别人的脚本,才看见有人用更小的类型,只是那时候分不清tinyint和smallint之间差在哪,只模糊记得一个能放的数更小一点。
浮点的类型是另外一桩糟心事。之前要存商品的单价,直接选了float,测试的时候看不出问题,加减计算的时候,结果时不时多出一串尾巴,对账的时候两边金额对不上,反复核对账单,查日志,排查了大半天,最后才发现是浮点存储自带的精度问题,不是业务逻辑写错了。那会才明白,涉及金额的数字,不能随便挑浮点类型,只是我也没有立刻记住对应的定点类型名字,只能打开本地库,建一张临时测试表,一个个试。
新建临时表,一行行添加字段,tinyint、smallint、mediumint、int、bigint挨个写上,再加上decimal和float、double,把注释简单写上,然后插不同大小的数据进去试。有的数字写进去直接报错,提示超出范围,有的可以正常写入,只是查询出来的样子和输入的时候不完全一样。来回插入删除,反复刷新查询结果,慢慢分得清它们各自容纳的区间差别,只是记不住精确的数值边界,隔上几天不碰,又会变得模糊。
decimal写的时候还要带上两个参数,总长度和小数位,第一次配的时候,两个数字填反了,存小数直接报错,改了好几次参数值,才顺利存进去金额数据。那段时间做表结构,只要是带小数的金额字段,优先考虑这个类型,只是每次写的时候,都要回想参数怎么摆放,不敢凭感觉乱写。
还有无符号的设定,也是试出来的。给int加上unsigned之后,负数就存不进去了,插入负数数据直接失败,一开始以为是代码传参出错,调试接口好久,才回头看到字段属性上多了这个修饰,之后存单纯的正数,才会考虑要不要开启,也清楚开了之后正数上限会拉高一些。
这些类型我没有一次性全部记牢,是在一次次建表、改表、修复数据异常的过程里慢慢接触到的,很多次都是遇到报错,才回头去确认该选哪一种。试过把超大数值塞进int,试过用float算账目,试过tinyint承载超出范围的状态值,每一次出错之后,才对对应的数字类型多一点印象。
其实到现在,也没法一口气完整说清mysql数字类型有哪些,只能顺着自己踩过的坑慢慢捋,很多细节只有在打开数据库,动手建表测试的时候才会清晰。仅代表我个人情况,不同场景、不同人的体验会存在差异,有的人天天和表结构打交道,早就熟稔于心,不像我,隔一段时间不写,就要重新对着测试表摸索一遍。
关掉数据库客户端的时候,桌面还留着刚才那张临时测试表的窗口,那些测试数据没有删掉,留着下次拿不准的时候,点开看一看。