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

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 上周和荣哥讨论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会起到一定的优化作用。


后记


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

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
关系型数据库 MySQL
Mysql基础第十九天,使用不同类型的链接
Mysql基础第十九天,使用不同类型的链接
25 0
Mysql基础第十九天,使用不同类型的链接
|
2月前
|
存储 关系型数据库 MySQL
MySQL - 索引类型详解
MySQL - 索引类型详解
|
2月前
|
关系型数据库 MySQL Docker
MySQL 5.7 timestamp类型设置default value为'0000-00-00 00:00:00'报错的解决方法
MySQL 5.7 timestamp类型设置default value为'0000-00-00 00:00:00'报错的解决方法
|
4月前
|
存储 关系型数据库 MySQL
MySQL中的列类型之字符串类型总结
MySQL中的列类型之字符串类型总结
77 1
|
1月前
|
弹性计算 安全 关系型数据库
rds网络类型选取
云数据库RDS的网络类型选择包括经典网络、专有网络(VPC)、公共网络和私有网络。推荐使用VPC以实现高安全隔离,私有网络增加安全性且节省公网费用。根据业务需求和安全策略选择,如需内部访问选择同一VPC,外部访问则需公网并配以严格安全措施。最新阿里云RDS建议使用VPC并结合安全组、网络ACL和白名单保障安全,通过CEN实现跨地域通信。
17 7
|
1月前
|
存储 关系型数据库 MySQL
MySQL中常见的存储引擎类型
【2月更文挑战第18天】
49 7
|
2月前
|
关系型数据库 MySQL
Mysql注入 -- 注入类型
Mysql注入 -- 注入类型
16 1
|
2月前
|
SQL 运维 关系型数据库
MySQL中常见的几种日志类型
MySQL中常见的几种日志类型
|
3月前
|
SQL 关系型数据库 MySQL
MySQL 数值函数,字符串函数与多表查询
MySQL 数值函数,字符串函数与多表查询
15 0
|
3月前
|
JSON 关系型数据库 MySQL
这个问题是由于Flink的Table API在处理MySQL数据时,将MULTISET类型的字段转换为了JSON格式
【1月更文挑战第17天】【1月更文挑战第84篇】这个问题是由于Flink的Table API在处理MySQL数据时,将MULTISET类型的字段转换为了JSON格式
34 1