设计-Int(4)和Int(11)谁更美

【缘起】

        大家平时在进行数据库设计的时候,如果遇到需要存储整数类型的数据的时候,通常会优先使用Int这个整数类型,在处理20亿级别的正负数值存储上,Int类型是完全能够满足日常需求的了。

       但是在进行数据库建表语句书写的时候,大家经常会见到Int类型的后面会带上1个括号,里面跟上1个数值,通常要么是4,要么是11。如下:

      这Int括号里面的数值,究竟是什么意思呢?有的开发者认为,这个数值是用来限制Int类型能够存储的数字的长度的( 类似char、varchar括号数值 );有的开发者则认为,在存储相同数字的情况下,Int(4)会比Int(11)在存储上节省更多的存储空间。

      那么实际情况究竟是怎样的呢?在实际的数据库设计中,究竟应该使用Int(4)还是Int(11)呢?又或者是应该什么都不写呢,只用默认的Int呢?

      让我们开启今天的MySQL数据库之Int类型之旅。^_^

【存储比较】

      为了方便测试Int(4)、Int(11)、以及默认的Int,在存储上是否存在差别,我们分别创建t_int_four、t_int_eleven、t_int_default表,如下:

    接下来,我们向t_int_four表的my_int_four字段,插入Int( 有符号 )类型的最大值2147483647,如下:

      如上图,我们看到m_int_four字段的Int(4)类型,并没有影响到Int类型最大值2147483647的插入。可见这个Int括号中的数值4,并不是对数字长度的存储进行限制的,也就是说,只要不超过Int( 有符号 )类型的最小值和最大值的范围,都是可以正确存储的。

      接下来我们向t_int_eleven表的my_int_eleven字段,插入Int类型的最大值2147483647。如下:

      如上图,我们看到,my_int_eleven字段的Int(11),也成功存储了Int类型的最大值2147483647。

      接下来我们向t_int_default表的my_int_default字段,插入Int类型的最大值。如下:

      如上图,my_int_default字段的Int类型,也成功存储了Int类型的最大值。这也就进一步证明了,Int类型括号中的数值,对该列字段的数值的存储长度是没有任何影响的,只要不超出Int类型的数值范围,都是可以被正确存储的。

      这里我们发现Int类型的最大值2147483647,是一个10位长度的数字,那么my_int_eleven字段的Int(11),能否突破Int类型的最大值,存储11位长度的数值呢?

      我们存入一个11位的数字,如下:

      如上图,这里我们发现,即便设置了Int(11)的列字段,依然无法突破Int类型的数值范围存储限制,最终还是只允许存储Int( 有符号 )类型的有效数值范围。

      那么Int(4)、Int(11)、以及默认的Int,在存储空间的占用上是否存在差别呢?是否相同位数长度的数值,Int(4)就比Int(11)节省更多的物理存储空间呢?

      接下来,我们打开磁盘上的表t_int_four、t_int_eleven、t_int_default这3个表的表空间文件( 后缀名是.ibd ),打开进行对比,如下:

      从上图的元数据中,我们看到不管是t_int_four的Int(4),还是t_int_eleven的Int(11),甚至是t_int_default的Int,在存储空间占用上,都是用了4个字节的空间大小,这里的FF FF FF FF,就是我们所存储的Int类型的最大值2147483647,如下:

      由于我们的Int类型是有符号的,也就是能存储负数。所以这里的4294967295需要除以2,得到有符号的正数2147483647,就是Int( 有符号 )类型的最大值了。

      关于有符号整数的存储及计算方法,大家可以在网上自行查询脑补,这里就不再陈述了。

【ZEROFILL】

      经过上面的示例,我们已经知道Int类型括号中的数值,并不是控制录入数据的数值位数长度的,那么它究竟是用来干什么的呢?

      在《MySQL中文参考手册》中,数值类型的列字段,都有一个叫做ZEROFILL的可选属性,如下:

      按照文档中的介绍,如果一个数值类型的列字段,加上了ZEROFILL的属性后,该列类型会自动变为Unsigned( 无符号 )类型,并具备自动补0的功能。

      那么究竟是什么样的效果呢?下面我们看一个示例。

      如上图,在t_int_zerofill表中,我们分别创建了表示Int(4)、Int(11)、Int的3个字段:my_int_four、my_int_eleven、my_int_default。

      我们在插入了1条每个字段值为数字1的数据后,发现查询出来的结果表中,自动在每个Int类型的字段列上,补了数字0。使得每一个数字列中的数值长度,正好等于该列字段Int括号中数值的长度。如下:

      上面表格中,我们发现,如果Int类型的列字段中,存储的数值的位长度,小于Int括号中的数值( 后面统一叫做ZEROFILL长度 ),MySQL在查询显示的时候,就会自动在该列的存储数值的左边,进行补0。使得整个显示值的总长度,等于Int列类型的ZEROFILL长度。如果使用的是Int默认类型,则按照Int( 无符号 )类型存储的最大数值的位长度进行补0,这里Int( 无符号 )类型的最大值为4294967295,也就是10位。所以my_int_default在显示数字1时,补9位0+1位数字(1),正好是10位。

      接下来,我们插入1条各字段数值为1234的数据,如下:

      如上图,这里我们看到,在插入1234之后,my_int_four的Int(4),就没有再进行补0了,因为数字1234的位长度,正好等于my_int_four列字段的ZEROFILL长度,也就是Int(4)。而其它列my_int_eleven和my_int_default,依然按照各自的ZEROFILL长度进行补0显示。

【混合示例】

      经过上面的示例,我们知道Int类型的ZEROFILL长度参数的用法,那么其他的数值类型,是否也同样使用ZEROFILL长度参数的用法规则呢?

      我们创建t_int_complex_zerofill表,并设置不同的数值类型的列字段,如下:

      接下来,插入1条测试数据,分别为每一个列字段,设置该数值列类型的无符号最大数值,如下:

      如上图,各种数值类型的ZEROFILL长度参数,依然对数值列类型本身的存储大小,是没有影响的。

      接下来我们插入1条,各列字段数值为1的测试数据,如下:

      如上图,各种数字类型的ZEROFILL长度参数都起到了预期的补0作用。

【总结】

      本篇主要针对MySQL数据库设计中,Int类型的列字段中,括号中不同补0长度的数值设置,以及其他具备相似特性的数值列类型,进行对了对比和分析。

      经过不同的示例分析,我们知道了数值列类型的补0长度的数值设置,也就是ZEROFILL的长度参数设置,对数值列类型本身的存储是没有任何影响的。

      在数值列类型的字段上,如果没有显示声明“ZEROFILL”标识的话,只要存储的数值不超过该数字列类型( 有符号 )的数值范围,就都可以正确存储。也就是说Int(4)和Int(11)在存储大小上,是没有任何差别和限制的。

      数值列类型的补0长度的数值设置,只有在该数值列类型的字段上,显示声明“ZEROFILL”标识之后,才会按照数值列类型的补0长度( ZEROFILL长度参数 ),进行补0显示。

      那么为什么在很多MySQL的建表语句中,会经常见到没有ZEROFILL标识的Int(4)和Int(11)的写法呢?

      阿K认为,这里可能主要有2种方向的考虑。

      Int(11):因为Int( 有符号 )类型的最大数值为2147483647,位长度是10。那么在存储的时候,就能从括号中看出来,在进行数据插入的时候,就不要输入11位长度的数字,比如:12345678901,就是超出范围的非法数据。用作数字插入的预警作用。

      Int(4):因为Int列类型的存储空间大小为4字节,在设计和存储的时候,就能够从括号中看出来Int列类型的占用空间大小,从而结合char、varchar等其它列的类型,方便的计算出来每条数据在插入的时候,所占用存储空间的大小,从而帮助开发者进行存储优化和数据库表优化。比如上面的t_int_complex_zerofill示例表,

我们很容易就能从各个数值列字段的ZEROFILL长度中,累加计算出,每向表中增加1条数据,就会用掉18个字节的存储空间,公式如下:

  TINYINT(1) + SMALLINT(2) + MEDIUMINT(3) + INT(4) + BIGINT(8) = 18字节

      在实际的数据库设计开发中,每位设计者的观点和想法都不尽相同,都有自己的设计考量。关于Int数值类型的字段设计,究竟Int(4)和Int(11)谁更好更美呢?作为开发人员的您,又是怎么看待它们的呢?

     欢迎留言与阿K进行交流讨论,希望本篇文章对您有所帮助,谢谢!

【示例】

   本文中提到的MySQL的示例文件,在阿K的Gitee中都可以找到,如下:

    https://gitee.com/Kival/mysql-work-demo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容