导读:本期聚焦于创作的《MySQL BIGINT主键深度解析:BIGINT与BIGINT(20)的真正区别与性能比较》,敬请观看详情。很多MySQL开发者在建表时习惯写成BIGINT(20),却不太清楚括号里的20到底起什么作用。本文从底层存储、数值范围、显示机制以及MySQL版本的演变等多个角度,详细剖析BIGINT与BIGINT(20)作为自增主键时的异同。你会发现,两者在存储和性能上完全没有区别,括号里的数字只是早期版本用来控制显示宽度的修饰符,而且在新版MySQL中已经被废弃。文章还会结合实际案例说明ZEROFILL的效果,并给出当前推荐的主键定义写法,帮助你写出更规范、更易于维护的表结构。

MySQL BIGINT主键深度解析:BIGINT与BIGINT(20)的真正区别与性能比较

MySQL中BIGINT与BIGINT(20)主键自增的真正区别:存储、显示与最佳实践

在MySQL数据库设计过程中,BIGINT是一种非常常用的整数类型,尤其适合作为自增主键。不少开发者在创建表时会习惯性地写成BIGINT(20),并且以为括号里的20代表了某种长度限制。其实这里面有一个常见的误解。今天我们就来彻底搞清楚BIGINT和BIGINT(20)到底有什么区别,以及在自增主键的场景下应该如何选择。

一、核心结论:存储空间与数值范围完全相同

首先要明确最关键的结论:无论是BIGINT还是BIGINT(20),它们在MySQL的磁盘上占用的存储空间都是8个字节,也就是64位。这意味着它们能表示的最大值和最小值完全一样,自增主键能够达到的上限也毫无差别。

具体数值范围如下:

  • 有符号(默认):从-92233720368547758089223372036854775807
  • 无符号(加上UNSIGNED):从018446744073709551615

这么大的范围对于绝大多数业务表的主键来说绰绰有余,即使每秒插入几万条记录,也需要数亿年才能用完。所以,从存储和自增能力的角度看,BIGINTBIGINT(20)是完全等价的。

很多开发者可能会想,那括号里的20是不是代表可以存储20位数字?其实不是。BIGINT本身最大可以容纳19位(有符号)或20位(无符号)的数字,但括号里的数字并不是用来限制输入位数的。它只是一个显示相关的修饰符,和存储无关。

二、括号里的数字到底是什么

在MySQL 8.0之前的版本中,整数类型后面可以跟一个括号数字,比如INT(11)BIGINT(20)。这个数字被称为“显示宽度”(display width)。它的作用仅仅是在查询结果显示时,如果数值的位数不够指定的宽度,并且同时使用了ZEROFILL属性,那么MySQL会在数值前面补零,直到总长度等于显示宽度。

举个例子就很容易理解了:

CREATE TABLE test_width (
    col1 BIGINT,
    col2 BIGINT(20),
    col3 BIGINT(20) ZEROFILL
);

INSERT INTO test_width VALUES (123, 123, 123);

执行查询后,你会看到:

  • col1显示为123
  • col2显示为123(因为没有ZEROFILL,显示宽度不生效)
  • col3显示为00000000000000000123(因为指定了ZEROFILL,不足20位时左边补零)

看到了吗?只有当你显式地加上ZEROFILL关键字时,显示宽度才有意义。如果不加ZEROFILL,那么写BIGINT(20)和直接写BIGINT在查询结果上完全一样,没有任何区别。

所以,如果你在建表时只写了BIGINT(20)而没有写ZEROFILL,那么这个20就是多余的,它不会对数据产生任何实质影响。

三、显示宽度的由来与现状

显示宽度这个特性是从MySQL早期版本继承下来的,最初的设计目的是为了让报表或命令行输出看起来更整齐。比如在旧式的管理工具中,所有数字都按固定宽度显示,方便对齐。但随着图形化管理工具和ORM框架的普及,这个特性逐渐失去了实际用途。

更重要的是,从MySQL 8.0.17版本开始,官方已经正式将整数类型的显示宽度标记为废弃(deprecated),并且在未来的版本中可能会完全移除。也就是说,在新的MySQL版本里,你再写BIGINT(20),虽然语法上还能通过,但MySQL会发出警告,提示你该特性即将被移除。

因此,现在的最佳实践是:不要再使用整数类型后面的显示宽度声明,直接写BIGINT即可。这样既符合未来版本的兼容性,也让代码更简洁、语义更清晰。

四、作为自增主键时的最佳实践

既然BIGINTBIGINT(20)在功能和性能上没有区别,那么在定义自增主键时应该怎么写呢?

推荐的做法是使用BIGINT UNSIGNED AUTO_INCREMENT。理由如下:

  1. 使用UNSIGNED:主键通常都是非负整数,加上UNSIGNED可以让取值范围翻倍,从0开始到约1844京,比有符号的上限大了将近一倍。虽然实际中用不到那么多,但这是一个良好的习惯,也避免了负数主键的歧义。
  2. 省略显示宽度:不再写括号和数字,避免误导和未来兼容性问题。
  3. 明确AUTO_INCREMENT:自增属性要放在最后。

一个典型的主键定义如下:

CREATE TABLE user (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100)
);

这样的写法清晰明了,任何人都能一眼看出这是一个无符号的、自增的BIGINT主键,没有任何冗余信息。

五、常见误区与解答

误区一:BIGINT(20)比BIGINT占用更多空间

完全错误。两者都占用8个字节,括号里的数字不影响存储。

误区二:BIGINT(20)只能存20位数字

BIGINT最多可以存19位(有符号)或20位(无符号),但括号里的20并不是限制位数。实际上,即使你往BIGINT(20)里插入一个21位的数字(如果超出范围会报错),也不会被截断。位数限制是由数据类型本身决定的,不是由括号数字决定的。

误区三:显示宽度会影响索引或排序性能

不会。显示宽度只是一个客户端显示的属性,和索引结构、排序算法没有任何关系。

误区四:新项目中仍然沿用BIGINT(20)的习惯

建议尽快改正。既然官方已经废弃该特性,继续使用只会增加代码的混乱度和未来迁移的成本。养成直接写BIGINT的习惯,既简洁又与时俱进。

六、总结

BIGINT和BIGINT(20)在MySQL中作为自增主键使用时,存储空间、数值范围、自增上限以及性能表现完全一致。括号里的20是早期版本用于控制显示宽度的修饰符,只有在配合ZEROFILL时才会在查询结果中补零,否则没有任何效果。从MySQL 8.0.17开始,显示宽度已被废弃,未来版本将不再支持。

因此,在现在的数据库设计工作中,推荐直接使用BIGINT UNSIGNED AUTO_INCREMENT来定义自增主键,省略任何不必要的显示宽度声明。这样不仅能写出更规范的SQL语句,也能让你的代码更好地适应MySQL的未来发展。希望这篇文章能帮你彻底告别对BIGINT(20)的疑惑,写出更专业、更高效的数据库表结构。

MySQLBIGINT自增主键显示宽度ZEROFILL修改时间:2026-08-02 06:15:16

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。