【MySql系列1】数值类型长度问题

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 上周和荣哥讨论DB字段的创建时,有个字段只存储整型状态值,因为状态值只能取值0和1,所以我用的是tinyint(1),然后荣哥说“你用这个1和用11,其实是一样的”,我心里顿时嘀咕“这个1不就是长度1么?”。后来网上查了一下相关资料,发现我和他的理解都错了。

8JS]7HX0RLXPT]UI]D0TD}L.jpg

你知道tinyint(1)、tinyint(11)、int(1)和int(5)的区别么?不懂?那你就要好好看看这篇文章了。


前言


上周和荣哥讨论DB字段的创建时,有个字段只存储整型状态值,因为状态值只能取值0和1,所以我用的是tinyint(1),然后荣哥说“你用这个1和用11,其实是一样的”,我心里顿时嘀咕“这个1不就是长度1么?”。后来网上查了一下相关资料,发现我和他的理解都错了。


整型类型


基础知识

整数类型又称数值型数据,数值型数据类型主要用来存储数字。MySQL 提供了多种数值型数据类型,不同的数据类型提供不同的取值范围,可以存储的值范围越大,所需的存储空间也会越大。

MySQL 主要提供的整数类型有 TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT,其属性字段可以添加 AUTO_INCREMENT 自增约束条件。下表中列出了 MySQL 中的数值类型。

image.gifM2M5B{XJ[S8X[C%}K7%YNPJ.png

从上表中可以看到,不同类型的整数存储所需的字节数不相同,占用字节数最小的是 TINYINT 类型,占用字节最大的是 BIGINT 类型,占用的字节越多的类型所能表示的数值范围越大。

根据占用字节数可以求出每一种数据类型的取值范围。例如,TINYINT 需要 1 个字节(8bit)来存储,那么 TINYINT 无符号数的最大值为 28-1,即 255;TINYINT 有符号数的最大值为 27-1,即 127。其他类型的整数的取值范围计算方法相同,如下表所示:

image.gifAVCFY0IFM2MZ1OYEE3KJQEX.png


最大显示宽度

比如int(5),这个5就是M值,表示的是最大显示宽度,这个值有什么含义呢?

细心的朋友应该有注意到过MySQL手册上有这么一句话:M指示最大显示宽度。最大有效显示宽度是255。显示宽度与存储大小或类型包含的值的范围无关;

这句话看上去不太容易理解,因为这里有个关键词容易让我们混淆,"最大显示宽度"我们第一反应是该字段的值最大能允许存放的值的宽度。以为我们建了int(1),就不能存放数据10了,其实不是这个意思。

这个M=5我们可以简单的理解成为,我们建立这个长度是为了告诉MySQL数据库我们这个字段的存储的数据的宽度为5位数, 当然如果你不是5位数(只要在该类型的存储范围之内)MySQL也能正常存储。

那问题又来了,既然“显示宽度与存储大小或类型包含的值的范围无关”,也就是实际使用时,int(1)和int(5)没有任何区别,那为啥还要指定这个“最大显示宽度”呢?

有网友给出如下解释:我推测当字段类型为数值时,设置M其实是在告诉数据库,我们预设该字段宽度是M,用来方便数据库做优化之类的东西,因为数值型都有其数值范围,所以在我们想存入超过M宽度的数值时,数据库会扩展字段空间来存储。

下面是整型的默认显示宽度:

TINYINT[(M)] [UNSIGNED] [ZEROFILL]  M默认为4
SMALLINT[(M)] [UNSIGNED] [ZEROFILL] M默认为6
MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL] M默认为9
INT[(M)] [UNSIGNED] [ZEROFILL]   M默认为11
BIGINT[(M)] [UNSIGNED] [ZEROFILL] M默认为20


问题讨论


tinyint(1) vs tinyint(11)

再回到“前言”中提到的问题,就很好解决了,先看看荣哥提的那个问题“tinyint(1)和tinyint(11)是一样的”,这里存在2个问题,首先tinyint的M值默认是4,所以你指定11是没有意义的,因为tinyint无符号的最大范围是[0,255]。

所以对于tinyint,你可以指定M=1,也可以不指定M值,即采用默认值,指定M=11是不符合规范的,当然你如果偏要这么做,系统也不会报错,比如:

(W_$0JBLGQE_HF8OD54A%ZB.png

但是插入大于225的数据时,提示越界,只有插入小于225的数据时,才能插入成功:

TP(8U`53S}CCJ%T5M1Q@PZN.png

这里有个有趣的点,我没有指定id_1为无符号整型tinyint,但是依然可以插入255的值,所以整型插入时,最大值可插入的是无符号最大范围值255,不是有符号最大范围值127。

其它的整型类型同理。


int(1) vs int(5)

对于int(1)和int(5),我们也可以演示一下,我们先创建表:

image.gif$PSQH4Z{P{(T0AA9}1XYKCU.png

int的无符号整型最大取值为4294967295:

image.gif)UGL9T`1)7)Q)Z_@3Z24__I.png

我们发现无论是int(1)还是int(5),在int范围外的数据插入失败,在int范围内的数据插入成功。

我之前想插入一个微秒的时间戳,之前用的是int(11),发现插入越界,后来我改成int(20),发现仍然越界,最后改成bigint(20),就可以了,现在终于知道原因了,原来存储数据的场景,和M根本没有关系,只和具体的类型有关系!

不过还是建议M的取值,在该类型的范围内,填写你认为最合理的值,这样可能有利于MySQL做一些优化操作,具体啥优化,我现在也不知道,只是猜测M对MySQL会起到一定的优化作用。


后记


一个简单的表字段整型类型创建,就可以牵扯出这么多有趣的知识,换做之前的我,可能就随便用用,估计是现在年纪大了,对很多事情喜欢较真,希望这种“较真”的精神能一直保持下去。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
9月前
|
存储 SQL 关系型数据库
【YashanDB知识库】MySQL迁移至崖山char类型数据自动补空格问题
**简介**:在MySQL迁移到崖山环境时,若字段类型为char(2),而应用存储的数据仅为'0'或'1',查询时崖山会自动补空格。原因是mysql的sql_mode可能启用了PAD_CHAR_TO_FULL_LENGTH模式,导致保留CHAR类型尾随空格。解决方法是与应用确认数据需求,可将崖山环境中的char类型改为varchar类型以规避补空格问题,适用于所有版本。
|
9月前
|
关系型数据库 MySQL Java
【YashanDB知识库】崖山BIT类型对MYSQL兼容问题
【YashanDB知识库】崖山BIT类型对MYSQL兼容问题
|
9月前
|
自然语言处理 关系型数据库 MySQL
MySQL索引有哪些类型?
● 普通索引:最基本的索引,没有任何限制。 ● 唯一索引:索引列的值必须唯一,但可以有空值。可以创建组合索引,则列值的组合必须唯一。 ● 主键索引:是特殊的唯一索引,不可以有空值,且表中只存在一个该值。 ● 组合索引:多列值组成一个索引,用于组合搜索,效率高于索引合并。 ● 全文索引:对文本的内容进行分词,进行搜索。
|
11月前
|
机器学习/深度学习 关系型数据库 MySQL
mysql bit对gorm使用何种类型?
在GORM中使用MySQL的BIT类型时,通常使用 `bool`类型来处理BIT(1),使用 `[]byte`类型来处理BIT(N)(N > 1)。通过正确的类型映射和位操作,可以高效地处理位字段数据。确保在定义结构体字段时,明确指定字段类型,以便GORM能够正确地处理数据库交互。
261 18
|
10月前
|
存储 SQL 关系型数据库
【YashanDB 知识库】MySQL 迁移至崖山 char 类型数据自动补空格问题
问题分类】功能使用 【关键字】char,char(1) 【问题描述】MySQL 迁移至崖山环境,字段类型源端和目标端都为 char(2),但应用存储的数据为'0'、'1',此时崖山查询该表字段时会自动补充空格 【问题原因分析】mysql 有 sql_mode 控制,检查是否启用了 PAD_CHAR_TO_FULL_LENGTH SQL 模式。如果启用了这个模式,MySQL 才会保留 CHAR 类型字段的尾随空格,默认没有启动。 #查看sql_mode mysql> SHOW VARIABLES LIKE 'sql_mode'; 【解决/规避方法】与应用确认存储的数据,正确定义数据
|
12月前
|
存储 关系型数据库 MySQL
mysql怎么查询longblob类型数据的大小
通过本文的介绍,希望您能深入理解如何查询MySQL中 `LONG BLOB`类型数据的大小,并结合优化技术提升查询性能,以满足实际业务需求。
484 6
|
分布式计算 关系型数据库 MySQL
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型 图像处理 光通信 分布式计算 算法语言 信息技术 计算机应用
262 8
|
关系型数据库 MySQL
用dbeaver创建一个enum类型,并讲述一部分,mysql的enum类型的知识
这篇文章介绍了如何在DBeaver中创建MySQL表的枚举(ENUM)字段,并探讨了MySQL中ENUM类型的一些行为特点,例如ENUM值的默认排序和在插入重复值时的表现。
344 1
用dbeaver创建一个enum类型,并讲述一部分,mysql的enum类型的知识
|
关系型数据库 MySQL 数据库
Python MySQL查询返回字典类型数据的方法
通过使用 `mysql-connector-python`库并选择 `MySQLCursorDict`作为游标类型,您可以轻松地将MySQL查询结果以字典类型返回。这种方式提高了代码的可读性,使得数据操作更加直观和方便。上述步骤和示例代码展示了如何实现这一功能,希望对您的项目开发有所帮助。
460 4
|
关系型数据库 MySQL Java
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型
261 0

推荐镜像

更多