说说MySQL里int到底是啥,怎么用才不出错那种感觉
- 问答
- 2026-01-23 19:13:24
- 2
(主要观点来自《高性能MySQL》、MySQL 8.0官方手册“Integer Types”章节、以及众多资深开发者的实践经验分享)
好的,咱们就来聊聊MySQL里的int,把它当成一个身边的老朋友,而不是书本里冷冰冰的名词,你可能会想,int不就是用来存数字的吗?有啥可讲的?但就是这个最基础的东西,用对了顺风顺水,用错了后面全是坑,我今天要说的,就是怎么用它才能有种“不出错”的踏实感。
第一,int的本质是个“筐”,但筐有大小,别硬塞。
你可以把int想象成一个固定大小的储物箱,MySQL提供了几种不同大小的int,就是为了让你根据要放的东西来选合适的箱子,别小马拉大车,也别杀鸡用牛刀。
TINYINT:这是个迷你小筐,能放的范围是-128到127,或者0到255(无符号时),适合存一些状态码,比如性别(0未知,1男,2女)、是否删除(0否,1是)这种肯定在255以内的数,你用大箱子存,就浪费空间了。SMALLINT、MEDIUMINT:这是中号筐和大号筐,能放的范围更大一些,比如存一个城市的区号、存一些商品库存数量(只要你的商品不是像小米手机那样一秒卖几十万台,这个一般都够用)。INT:这是我们最常用的“标准筐”,它的范围大概是正负21亿左右,绝大多数情况,你的用户ID、订单ID、文章ID,用这个绰绰有余,你想想,21亿个用户,啥应用能达到这个量级?除非你有非常确凿的理由,否则主键ID之类需要大量存储的字段,无脑选INT通常不会错,这是很多老程序员的经验之谈。BIGINT:这是个巨无霸筐,范围大到天文数字,只有当你的业务真的像微信、淘宝那样,数据量以亿为单位飞速增长,担心INT将来某天会不够用了,才需要考虑它,但你要知道,用BIGINT做主键,每个索引都会占用更多空间,整体性能会有细微影响。不要盲目追求“大就是好”。
第二,给int加上“无符号”标签,相当于给筐贴个“只放正数”的纸条。
int默认是能存负数的,但像ID、年龄、数量这些,你永远不会存一个负数进去,这时候,就可以在定义字段时加上UNSIGNED关键字,比如INT UNSIGNED,这相当于告诉MySQL:“我这个筐,只放正数”,这样一来,同样大小的INT筐,能存的正数上限就翻倍了,从21亿变成了42亿多。对于自增主键ID,强烈建议总是使用INT UNSIGNED或者BIGINT UNSIGNED,这能让你在不知不觉中延长了数据表的“寿命”,避免了未来某天因为ID用完而需要紧急重构的尴尬,这是一种很重要的“不出错”的预防措施。
第三,int的“长度”坑最深,它不代表能存的数字位数!

这是最容易让人误解的地方,你在建表时可能会写INT(11),以为这表示最多能存11位长的数字。大错特错! 根据MySQL官方手册的解释,括号里的数字只是“显示宽度”,它和存储范围、存储空间一点关系都没有。INT本身永远占用4个字节,范围就是固定的正负21亿。
那这个(11)是干嘛的呢?它只是在某些特定的客户端工具(比如古老的命令行客户端)里,当数字位数不够时,会在前面用空格或零填充到指定宽度,让显示看起来整齐而已,在绝大多数现代数据库管理和编程环境里,这个设置是完全无效的,你写INT、INT(11)、甚至INT(20),在数据库底层都是一模一样的东西。为了避免团队里的新人困惑,现在很多规范都建议直接写INT,省略掉那个迷惑性的长度,记住这一点,能避免很多沟通和设计上的误会。
第四,用int存时间戳?三思而后行。
有时候你会看到有人用int来存时间戳,比如存一个从1970年1月1日到现在经过的秒数或毫秒数,这样做的好处是计算时间间隔特别快,因为是数字运算,但坏处也很明显:极度不直观,你看到数据库里一个数字1640995200,你能一眼看出这是2022年元旦那天吗?不能,你得手动转换,这给排查问题带来了巨大困难。

MySQL提供了专门的DATETIME和TIMESTAMP类型来存时间,它们表达清晰,查询方便,自带了很多日期函数支持。除非你在做极高并发、需要对时间进行大量数学运算的场景(比如高频金融交易),否则老老实实用专门的时间类型,这才是“不出错”的稳妥选择,用int存时间,往往是早期设计偷懒埋下的坑。
第五,int和索引是黄金搭档,但别乱用。
int因为其大小固定、比较运算速度快,是作为数据库索引最理想的数据类型之一,这也是为什么我们喜欢用自增int做主键,要注意两点:
- 不要用NULL:尽量把int字段定义为
NOT NULL并设置一个默认值(比如0),因为NULL值比较特殊,处理起来更复杂,可能会让索引效果打折扣,也容易在程序里产生空指针异常。 - 避免在int上做函数运算:比如你有一个
create_time是int类型的时间戳,如果你想查询某一天的数据,错误的写法是WHERE FROM_UNIXTIME(create_time) = '2022-01-01',因为这对索引字段用了函数,数据库就无法有效使用索引了,会导致全表扫描,正确的写法应该是计算出那天的起始和结束时间戳,用BETWEEN查询。让你的查询条件直接面对“干净”的int值,索引才能发挥最大威力。
总结一下那种“不出错”的感觉:
说白了,就是用int的时候,心里要门儿清:
- 量体裁衣:根据数据可能的最大范围,选择最合适的int类型,INT是万金油。
- 能正则正:对于不会出现负数的字段,果断加上
UNSIGNED。 - 看透本质:忘记
INT(M)里的M,它不限制长度,避免无用功和误解。 - 各司其职:时间是时间,用专门类型存,别让int越俎代庖。
- 发挥特长:让int干干净净地做索引,避免NULL和函数计算来拖后腿。
把这些原则变成一种本能,你再用int的时候,心里就是一种“我考虑周全了,这里以后不会出幺蛾子”的踏实感,数据库设计就是这样,基础打得牢,后面写代码才能跑得欢。
本文由雪和泽于2026-01-23发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://haoid.cn/wenda/84629.html
