MySQL int(10) 与 int(11) 的区别

每次给有个列添加 int(11) 的时候都会想,会不会是 int(10) ,偶尔也会发神经的想,如果 int(32) 这样的可否?

索性,我们就先来解决这个问题吧。

int 类型的底层存储采用的是 4 字节,也就是 32 位,这样能够存储的实际最大值为 4 294 967 296,大家数数一下这个数字,总共有多少位 ?

对的,没错,就是 10 位,所以,感觉 int(11) 这个应该是错误的 ? 实际上,真的错了吗 ?

没有,因为我们演示的是无符号整型的情况,而对于有符号整型,范围是 -2 147 483 648 到 2147483648,大家数一数最小值,是不是就 11 位了

所以,int(11) 就是这么来的,而且也不会错。

但这到底是什么道理呢 ?

为了搞清楚弄明白,我们就必须去了解 MySQL 是如何对待数据类型上的属性的。

数值类型的宽度显示属性

对于所有的数值类型,MySQL 通过扩展的方式,可以有选择性的在类型的 base 关键字后面的括号中指定 「 整数 」 数据类型的 「 显示宽度 」 。

注意: 我们使用 「」 括号扩起来的 整数 和 显示宽度 两个词。

例如,例如,INT(4) 指定显示宽度为 4 位的 INT。对于一个类型为 INT(4) 的列,实际存储仍然使用 4 个字节,但显示的时候就有有细微的差别:

如果给该列传递的值大于等于四位,比如 5201314,那么显示的时候会使用原值,也就是显示 5201314

但如果给该列传递的值小于四位,比如 520 ,那么显示的时候就会在左边填充 0,也就是显示位 0520

我们举一个例子,假设我们有一个表如下

CREATE TABLE na (

n1 INT(4) NOT NULL DEFAULT '0',

n2 INT(4) ZEROFILL NOT NULL DEFAULT '0'

);

然后插入一些数据

mysql> INSERT INTO na VALUES(520,520),(5201314,5201314);

Query OK, 2 rows affected (0.04 sec)

Records: 2 Duplicates: 0 Warnings: 0

最后我们看看显示的结果

mysql> SELECT * FROM na;

+---------+---------+

| n1 | n2 |

+---------+---------+

| 520 | 0520 |

| 5201314 | 5201314 |

+---------+---------+

2 rows in set (0.01 sec)

对比下 n1 和 n2 ,n1 是不是在位数不满足的时候会填充前导的 0。

从演示结果上来看,显示宽度不会限制可以存储在列中的值的范围,也不会阻止比列显示宽度更宽的值正确显示。例如刚刚的范例,指定为 INT(4) 的列的取值范围为 -2 147 483 648 到 2147483648 ,超过四位数允许范围之外的值将使用四位数以上显示

当列添加了 ZEROFILL 约束时 ( 注意,这并不是 SQL 标准的一部分 ),会使用 0 代替默认的默认的空格 ' ' 。例如,对于声明为 INT(4) ZEROFILL 的列,会将值 5 显示为 0005

注意

在表达式或 UNION 查询中涉及列时,会自动忽略 ZEROFILL 属性。

使用 ZEROFILL 属性时要注意,如果将大于显示宽度的值存储在具有 ZEROFILL 属性的整数列中,为某些复杂连接生成临时表时可能会遇到问题。因为在这些情况下,MySQL 会假定数据值符合列显示宽度

数值类型的 UNSIGNED 显示属性

所有整数类型都可以具有可选 ( 非标准 ) 属性 UNSIGNED 。无符号类型可用于仅允许列中的非负数或当需要更大的列的上限数字范围时。例如,如果 INT 列为 UNSIGNED,则列的范围大小相同,终端显示时范围从 -2147483648 和 2147483647 更改为 0 和 4294967295。

从某些方面说,就是 UNSIGNED 属性并不会更改底层的数据存储格式,仍然是 SIGNED 有符号整数,但在显示时,会将有符号的值自动转换为无符号的值。也就是说 UNSIGNED 也是一个显示属性

浮点和精确精度类型也可以是 UNSIGNED ,与整数类型一样,此属性可防止负值存储在列中。但与整数类型不同,列值的上限范围保持不变。

数值类型的 ZEROFILL 显示属性

ZEROFILL 列的属性,我们刚刚介绍过了,这里就不重复介绍了。

如果为数值列指定了 ZEROFILL ,MySQL 会自动添加 UNSIGNED 属性到列中。

数值类型的 AUTO_INCREMENT 属性

整数或浮点数据类型可以添加附加属性 AUTO_INCREMENT。如果某个列添加了 AUTO_INCREMENT 属性,那么在插入数据的时候,如果不指定该列或者指定该列的值为 NULL ,那么 MySQL 会自动将该列的值设置为下一个序列值

通常,值为 value+1 ,其中 value 是表中当前列的最大值。

注意:AUTO_INCREMENT 序列以 1 开始而不是 0

另一个需要注意的是,将 0 存储到 AUTO_INCREMENT 列与存储 NULL 具有相同的效果,除非启用了 NO_AUTO_VALUE_ON_ZERO SQL 模式。

而对于插入 NULL 以生成 AUTO_INCREMENT 值需要将列声明为 NOT NULL。如果列声明为 NULL,那么插入 NULL 将存储 NULL 。

还有一个需要注意的是,当你将任何其它值插入 AUTO_INCREMENT 列时,该列将设置为该值并重置序列,以便从插入的值开始按顺序执行下一个自动生成的值。所以千万要避免在 AUTO_INCREMENT 指定列值插入,很大概率会发生主键重复的问题

在 MySQL 8.0 及以上的版本, AUTO_INCREMENT 列会自动添加一个隐式的 UNSIGNED 属性来保证插入的值非负。

相关推荐
余槐i6 小时前
PostgreSQL 函数索引报错 must be immutable:3种绕法与代价
数据库·后端·sql·postgresql·性能优化
数据库小学妹6 小时前
PostgreSQL表膨胀怎么办?autovacuum清不动的根因与排查命令
数据库·postgresql·表膨胀·mvcc·数据库运维
mister_guo6 小时前
MySQL-1267错误:排序规则冲突的原因与解决方案
数据库·mysql
骇客野人6 小时前
在麒麟操作系统上 分别安装 jdk1.8, 达梦数据库,redis ,memcache 的操作实施方案和步骤
数据库·redis·memcached
美狐美颜SDK开放平台8 小时前
直播APP如何实现美白滤镜功能?视频美颜SDK技术开发方案详解
前端·数据库·人工智能·音视频·美颜sdk·直播美颜sdk·视频美颜sdk
Lost_the_wind8 小时前
MySQL学习笔记五
mysql
花间相见9 小时前
【计算基础|MySQL01】【上手】安装连接、数据类型与建库建表
数据库·后端
花间相见9 小时前
【计算基础|MySQL02】【上手】SQL 增删改查
数据库·后端
ITxiaobing202310 小时前
IP 库与 AppsFlyer 国家/地区数据不一致,如何系统地对账?
数据库·网络协议·tcp/ip
这个DBA有点耶10 小时前
从时间到语义:时序数据库与向量数据库的核心机制、选型与多模融合趋势
数据库·mysql·架构