MySQL 整型长度的含义

缘起

发现公司数据库中很多整型数据限定了长度, 明显不是为了 "Zerofill/补零功能". 推测大家可能是搞错了"整型长度"的含义, 误以为"整型"后面的数字代表的是"允许存储的最大宽度", 比如, 误以为 int(1) 不能存储 10.

PS. MySQL的 int 和 tinyint 的默认长度是 int(11)tinyint(4), 而boolean 型实际存储的是 tinyint(1).


先说结论

"浮点型"的长度是用来限制数字存储范围的. 比如 float(3,2) 只能够写入 0.00~999.99.

"整型"的长度并不会限制存储的数字范围. 比如, intint(3) 的存储范围都是 -2147483648 ~ 2147483647, int unsignedint(3) unsigned 的存储范围都是0 ~ 4294967295.

"整型"的长度实际上可以理解为"显示长度", 如果该字段开启 "Zerofill/补零"就能很明显地知道它的作用.

比如, a b c d 分别表示 int(1) int(2) int(3) int(3) zerofill, 那么实际存入数据库的数据是这样的:

| v  | a  |  b  |  c |  d |
+-----+-----+-----+-----+-----+
| 1  | 1  |  1  |  1 | 001 |
| 10  | 10  | 10  |  10 | 010 |
| 100 | 100 | 100 | 100 | 100 |

PS. 如果开启 "Zerofill/补零", 则自动会默认为 "Unsigned/非负数".


试验

试验 1 : 整型长度是否会限制存储范围

创建数据表:

CREATE TABLE test01 (
  with_length int(3),
  without_length int
) ENGINE=innodb, CHARSET=utf8

写入数据 1111:

insert into test01 (with_length, without_length) VALUE (1111, 1111);

可以发现 1111 是可以写入 int(3) 字段的:


试验 2 : 整型长度的补零作用

创建数据表:

CREATE TABLE test02 (
  with_length int(3) ZEROFILL,
  without_length int
) ENGINE=innodb, CHARSET=utf8

插入数字 1:

insert into test02 (with_length, without_length) VALUE (1, 1);

看看 "Zerofill/补零" 效果:


参考

"高性能MySQL" 的说明

"高性能MySQL" 书中在"4.1 选择优化的数据类型"中提到:

MySQL 可以为整数类型指定宽度, 例如 INT(11), 对大多数应用这是没有意义的: 它不会限制值的合法范围, 只是规定了 MySQL 的一些交互工具(例如 MySQL 命令行客户端)用来显示字符的个数. 对于存储和计算来说, INT(1) 和 INT(20) 是相同的


"MySQL 手册"的说明

MySQL 5.7 手册 "12.2.5 Numeric Type Attributes":

MySQL supports an extension for optionally specifying the display width of integer data types in parentheses following the base keyword for the type. For example, INT(4) specifies an INT with a display width of four digits. This optional display width may be used by applications to display integer values having a width less than the width specified for the column by left-padding them with spaces. (That is, this width is present in the metadata returned with result sets. Whether it is used or not is up to the application.)

MySQL 支持用括号包含的数字限定整型的显示长度. 比如 INT(4) 限定了整型的显示长度为 4 个字符, 对于小于 4 个字符的数字, 有些数据库软件会用"空格"来补齐小于 4 个位数的数字.

The display width does not constrain the range of values that can be stored in the column. Nor does it prevent values wider than the column display width from being displayed correctly. For example, a column specified as SMALLINT(3) has the usual SMALLINT range of -32768 to 32767, and values outside the range permitted by three digits are displayed in full using more than three digits.

这个显示长度并不会限制该字段的数字存储范围, 同时, 也不会阻止大于指定显示长度的数字写入该字段. 比如, SMALLINT(3) 的字段和 SMALLINT 的数字存储范围都是 -32768 to 32767, 如果存储的数字超过 3 个位数仍然是允许被存入 SMALLINT(3) 字段, 而且以其本来的位数显示.

When used in conjunction with the optional (nonstandard) attribute ZEROFILL, the default padding of spaces is replaced with zeros. For example, for a column declared as INT(4) ZEROFILL, a value of 5 is retrieved as 0005.

如果配合 ZEROFILL 属性, 将用 0 来补齐. 比如 INT(4) ZEROFILL 字段, 数字 5 会被存储为 0005.


Laravel 迁移文件语法的佐证

在写 Laravel 迁移文件的时候, 大家会发现, 迁移文件的语法中是没有整型长度的:

$table->integer('uniacid');

之所以没有长度, 是因为整型长度只是用于限定"显示长度"而已, 并不会改变存储范围, 而且这只是 MySQL 的额外特性, 并不是标准的 SQL 语法 (not ANSI SQL standards), 而 Laravel 只支持 ANSI SQL standards.


参考文章


文章历史

  • 2017/03/12 (第一次发布)
  • 2017/03/14 增加"高性能MySQL"书中关于整型长度的说明
  • 2017/03/19 发现之前的配图(如下图所示)是错误的. 我原来以为 tinyint(1) 是因为错误理解整型长度的意义导致的错误, 但是今天发现之所以有 tinyint(1)是因为如果在 MySQL中设置 boolean 类型, 实质存储的就是 tinyint(1)! 所以之前配图中的数据类型是没有错误的! 是我搞错了 :-)
  • 2017/03/23 修改"缘起"章节的描述, 因为 MySQL 存储的 int 默认是 int(11), 存储的 tinyint 默认是 tinyint(4), 存储的 boolean 型实际存储的是 tinyint(1). 所以之前自己依据数据库中存在的 tinyint(1) 而推断大家理解错"整型长度"是错误的!
  • 2017/06/13 润色

如果我的文章对你有用, 希望给些改进的建议, 或者打个"喜欢" _

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

推荐阅读更多精彩内容