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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 上周和荣哥讨论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会起到一定的优化作用。


后记


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

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3天前
|
机器学习/深度学习 关系型数据库 MySQL
mysql bit对gorm使用何种类型?
在GORM中使用MySQL的BIT类型时,通常使用 `bool`类型来处理BIT(1),使用 `[]byte`类型来处理BIT(N)(N > 1)。通过正确的类型映射和位操作,可以高效地处理位字段数据。确保在定义结构体字段时,明确指定字段类型,以便GORM能够正确地处理数据库交互。
26 18
|
1月前
|
存储 关系型数据库 MySQL
mysql怎么查询longblob类型数据的大小
通过本文的介绍,希望您能深入理解如何查询MySQL中 `LONG BLOB`类型数据的大小,并结合优化技术提升查询性能,以满足实际业务需求。
127 6
|
2月前
|
分布式计算 关系型数据库 MySQL
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型 图像处理 光通信 分布式计算 算法语言 信息技术 计算机应用
69 8
|
3月前
|
关系型数据库 MySQL
用dbeaver创建一个enum类型,并讲述一部分,mysql的enum类型的知识
这篇文章介绍了如何在DBeaver中创建MySQL表的枚举(ENUM)字段,并探讨了MySQL中ENUM类型的一些行为特点,例如ENUM值的默认排序和在插入重复值时的表现。
72 1
用dbeaver创建一个enum类型,并讲述一部分,mysql的enum类型的知识
|
7月前
|
分布式计算 DataWorks MaxCompute
DataWorks产品使用合集之需要将mysql 表(有longtext类型字段) 迁移到odps,但odps好像没有对应的类型支持,该怎么办
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
|
2月前
|
关系型数据库 MySQL Java
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型
57 0
|
4月前
|
关系型数据库 MySQL 数据库
Python MySQL查询返回字典类型数据的方法
通过使用 `mysql-connector-python`库并选择 `MySQLCursorDict`作为游标类型,您可以轻松地将MySQL查询结果以字典类型返回。这种方式提高了代码的可读性,使得数据操作更加直观和方便。上述步骤和示例代码展示了如何实现这一功能,希望对您的项目开发有所帮助。
190 4
|
4月前
|
自然语言处理 算法 Java
Java如何判断两句话的相似度类型MySQL的match
【9月更文挑战第1天】Java如何判断两句话的相似度类型MySQL的match
29 2
|
5月前
|
存储 关系型数据库 MySQL
MySQL bit类型增加索引后查询结果不正确案例浅析
【8月更文挑战第17天】在MySQL中,`BIT`类型字段在添加索引后可能出现查询结果异常。表现为查询结果与预期不符,如返回错误记录或遗漏部分数据。原因包括索引使用不当、数据存储及比较问题,以及索引创建时未充分考虑`BIT`特性。解决方法涉及正确运用索引、理解`BIT`的存储和比较机制,以及合理创建索引以覆盖各种查询条件。通过`EXPLAIN`分析执行计划可帮助诊断和优化查询。
105 1
|
5月前
|
缓存 NoSQL Redis
一天五道Java面试题----第九天(简述MySQL中索引类型对数据库的性能的影响--------->缓存雪崩、缓存穿透、缓存击穿)
这篇文章是关于Java面试中可能会遇到的五个问题,包括MySQL索引类型及其对数据库性能的影响、Redis的RDB和AOF持久化机制、Redis的过期键删除策略、Redis的单线程模型为何高效,以及缓存雪崩、缓存穿透和缓存击穿的概念及其解决方案。