之前在论坛上看到一个有意思的问题,如果有一个字段的值超过bigint,会发生什么。
然后就看到有人喷,说0.1秒插入一个值,将bigint设置为无符号,插入到极限需要多久,根本不可能遇到如何如何 。
(接下来会做个测试)

好了,进入正文:
首先需要知道一个概念,如果在定义的时候,设置UNSIGNED可以将范围扩大一倍,该值意味着此字段无符号(即不包含负数)。

根据文档可知,数据类型有五种,分别为
TINYINT,SMALLINT,MEDIUMINT,INT(INTEGER),BIGINT。

其值的范围,同样查阅官方文档可知
TINYINT为 -128~127 无符号数则为127-(-128)=255(2^8-1),因为非负,所以从0开始即0~255,以此类推:
SMALLINT为 -32768~32767 无符号数则为0~65535(2^16-1)
MEDIUMINT为 -8388608~8388607 无符号数则为0~16777215(2^24-1)
INT为-2147483648~2147483647 无符号数则为0~4294967295(2^32-1)
BIGINT为-9223372036854775808~9223372036854775807 无符号数则为0~18446744073709551615(2^64-1)
当然光是INT就已经达到了20亿以上的数量级,十分够用。
下表来自MySQL 5.6官方手册

Type Storage Minimum Value Maximum Value
  (Bytes) (Signed/Unsigned) (Signed/Unsigned)
TINYINT 1 -128 127
    0 255
SMALLINT 2 -32768 32767
    0 65535
MEDIUMINT 3 -8388608 8388607
    0 16777215
INT 4 -2147483648 2147483647
    0 4294967295
BIGINT 8 -9223372036854775808 9223372036854775807
    0 18446744073709551615

其存储所需容量也可以看出,由小到大分别为
TINYINT              1字节
SMALLINT              2字节
M EDIUMINT              3字节
I NT                  4字节
B IGINT              8字节

当然上述数据类型及范围好像在sql server中也是适用的,同时也包括一些程序设计语言。

回到开始的话题,如果超过BIGINT的范围怎么办?
其实mysql的处理方法和超过 TINYINT 一样:
此处测试均为MySQL 5.6版本(社区版),存储引擎为默认的InnoDB。

  1. mysql> CREATE TABLE a (id TINYINT UNSIGNED PRIMARY KEY AUTO_INCREMENT);
  2. Query OK, 0 rows affected (0.25 sec)
  3. mysql> INSERT INTO a SELECT 255;
  4. Query OK, 1 row affected (0.04 sec)
  5. Records: 1 Duplicates: 0 Warnings: 0
  6. mysql> INSERT INTO a SELECT 256;
  7. ERROR 1264 (22003): Out of range value for column 'id' at row 1
  8. mysql> INSERT INTO a SELECT NULL;
  9. ERROR 1062 (23000): Duplicate entry '255' for key 'PRIMARY'
  10. mysql> SELECT * FROM a;
  11. +-----+
  12. | id |
  13. +-----+
  14. | 255 |
  15. +-----+
  16. 1 row in set (0.00 sec)

首先插入255上限值,然后我做了如下两个操作:
1、插入256,报错ERROR 1264,即超过ID列的上限值。
2、插入NULL,此处应该自增,报错ERROR 1062,即 由于主键约束,故无法重复存在。

其报错结果可以轻易看出,256是不能够被插入的(废话)
处理AUTO_INCREMENT约束时,即便遇到数值类型的上限值,仍然会尝试插入,此时插入的值是上限值,即255。

此处可以看出此处的 AUTO_INCREMENT = 255,而不是256(即便255已经存在)。
注,此处(ENGINE=InnoDB后面)的AUTO_INCREMENT为MySQL认为该表的下一个自增字段的值。

  1. mysql> SHOW CREATE TABLE a\G
  2. *************************** 1. row ***************************
  3. Table: a
  4. Create Table: CREATE TABLE `a` (
  5. `id` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,
  6. PRIMARY KEY (`id`)
  7. ) ENGINE=InnoDB AUTO_INCREMENT=255 DEFAULT CHARSET=latin1
  8. 1 row in set (0.00 sec)

当然既然开始了,还是要做一下BIGINT的实验。

  1. mysql> CREATE TABLE b (id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT);
  2. Query OK, 0 rows affected (0.26 sec)
  3. mysql> INSERT INTO b SELECT 18446744073709551615;
  4. Query OK, 1 row affected (0.05 sec)
  5. Records: 1 Duplicates: 0 Warnings: 0
  6. mysql> INSERT INTO b SELECT 18446744073709551616;
  7. ERROR 1264 (22003): Out of range value for column 'id' at row 1
  8. mysql> INSERT INTO b SELECT NULL;
  9. ERROR 1467 (HY000): Failed to read auto-increment value from storage engine
  10. mysql> SHOW CREATE TABLE b\G
  11. *************************** 1. row ***************************
  12. Table: b
  13. Create Table: CREATE TABLE `b` (
  14. `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  15. PRIMARY KEY (`id`)
  16. ) ENGINE=InnoDB AUTO_INCREMENT=18446744073709551615 DEFAULT CHARSET=latin1
  17. 1 row in set (0.00 sec)

同样插入BIGINT UGSIGNED的上限值,然后继续做如下两个操作:
1、插入18446744073709551616,报错ERROR 1264,即超过ID列的上限值。(与实验1的报错结果一致)
2、插入NULL,此处报错与之前不同,为ERROR 1467。
ERROR 1467官方解释为:

Error: 1467 SQLSTATE: HY000 (ER_AUTOINC_READ_FAILED)

Message: Failed to read auto-increment value from storage engine

字面意思为“从存储引擎读取自增字段失败”。

搜了一下google,好像还真有人在实际运用中遇到这种问题,有个小哥提出了如下的方法:

After some searching i found the answer and it solved my problem.
run this sql query it will fix the problem

ALTER TABLE `YOUR_TABLE` AUTO_INCREMENT = 1
我也做了如下操作,但是…… 发现并未生效。

  1. mysql> ALTER TABLE b AUTO_INCREMENT = 1;
  2. Query OK, 0 rows affected (0.04 sec)
  3. Records: 0 Duplicates: 0 Warnings: 0
  4. mysql> INSERT INTO b SELECT NULL;
  5. ERROR 1467 (HY000): Failed to read auto-increment value from storage engine
  6. mysql> SHOW CREATE TABLE b\G
  7. *************************** 1. row ***************************
  8. Table: b
  9. Create Table: CREATE TABLE `b` (
  10. `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  11. PRIMARY KEY (`id`)
  12. ) ENGINE=InnoDB AUTO_INCREMENT=18446744073709551615 DEFAULT CHARSET=latin1
  13. 1 row in set (0.00 sec)

额外两个tips:
【1】由于TIMESTAMP用的其实是INT来存储,故从1970年1月1日开始往后顺延2147483647s,约24855天,即68年(到2038年)。
关于TIMESTAMP,官方给出的范围是:
 '1970-01-01 00:00:01.000000' UTC to '2038-01-19 03:14:07.999999' UTC.

【2】
MySQL提供了一个叫SERIAL的”类型“
实际上是unsigned NOT NULL AUTO_INCREMENT UNIQUE的别名:

  1. mysql> CREATE TABLE test(a SERIAL);
  2. Query OK, 0 rows affected (0.41 sec)
  3. mysql> show create table test\G
  4. *************************** 1. row ***************************
  5. Table: test
  6. Create Table: CREATE TABLE `test` (
  7. `a` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  8. UNIQUE KEY `a` (`a`)
  9. ) ENGINE=InnoDB DEFAULT CHARSET=latin1
  10. 1 row in set (0.00 sec)

关于整型数据类型宽度int(11)的解释可参考
http://blog.itpub.net/29773961/viewspace-1804920/

作者公众号(持续更新)

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29773961/viewspace-1803302/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/29773961/viewspace-1803302/

MySQL 五种整型数据类型的范围与区别 tinyint smallint mediumint int bigint相关推荐

  1. MYSQL中TINYINT SMALLINT MEDIUMINT INT BIGINT的区分

    在MYSQL当中整形数据的存储有四种,分别是TINYINT SMALLINT MEDIUMINT INT BIGINT,它们的区分如下: 类型 存储大小(字节) 最小有符号数 最小无符号数 最大有符号 ...

  2. 【mysql】关于mysql中int(M)类型的具体含义以及tinyint/smallint/mediumint/int/bigint的区别是什么?

    之前定义数据库类型一直不理解int(M)的具体含义,M决定的是什么?不同M的值的区别是什么?tinyint / smallint / mediumint / int / bigint这些类型又有什么不 ...

  3. MySQL数据类型详解:tinyint,smallint,mediumint,int,bigint的区别

    前言 每种编程语言都有自己所定义的数据类型,mysql也不例外,平时我们在创建表时,需要根据业务要求,结合存储.索引.字段临界值等条件来为字段定制不一样的类型.下面我们一起学习下mysql的几种常用的 ...

  4. mysql tinyint int mediumint 用哪个好_MYSQL 字段类型之TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT...

    1. tinyint: 只能存储-128到127大小的数字, 不在乎后面的定义,如tinyint(9). 需1字节存储空间. 当加有UNSIGNED后,数字可以从0增加到255大小. dba@loca ...

  5. mysql修改字段类型为smallint_MYSQL 字段类型之TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT

    1. tinyint: 只能存储-128到127大小的数字, 不在乎后面的定义,如tinyint(9). 需1字节存储空间. 当加有UNSIGNED后,数字可以从0增加到255大小. dba@loca ...

  6. c语言的数据类型有什么 long int,C语言的三种整型数据类型:INT SHORT INT和LONG INT...

    int数据类型的位数为16位,short int数据类型的位数也是16位.而long int的位数为32位,可用来存储比较大的整数. short int和long int可以缩写为short和long ...

  7. C语言的三种整型数据类型:int、short int和long int

    int数据类型的位数为16位,short int数据类型的位数也是16位.而long int的位数为32位,可用来存储比较大的整数. short int 和 long int可以缩写为short 和 ...

  8. c语言的数据类型有什么 long int,C语言的三种整型数据类型:int、short_int和long_int...

    int数据类型的位数为16位,short int数据类型的位数也是16位.而long int的位数为32位,可用来存储比较大的整数. short int 和 long int可以缩写为short 和 ...

  9. ABAP里几种整型数据类型的范围和转换

最新文章

  1. Java编程笔试时输入问题:如何输入固定长度、不定长度的一维数组?如何输入固定长度、不定长度的二维数组?
  2. Java 集合系列10: HashMap深入解析(1)
  3. 【已解决】Could not find resource jdbc.properties
  4. 件工程项目开发最全文档模板_一文带你了解微信小程序社区和小程序开发
  5. using用法是什么?
  6. Ubuntu 系统目录结构
  7. chisel(安装)
  8. REHL 6 安装指南
  9. 没有调用save或update方法,却有sql语句执行
  10. “刚毕业1年,做Python能挣多少?”网友:吹的不多...
  11. java宿舍信息管理系统_Java宿舍管理系统
  12. Sublime text3 Version 3... 3207 激活码许可证(2019-07-19亲测有效)
  13. Leetcode 1153 字符串转化
  14. 视频服务器是什么?要如何搭建?
  15. Java中IO流的分类和BIO,NIO,AIO的区别
  16. 关于华为云的域名认证问题
  17. 自动化测试遇到的难点_1.5 自动化测试普遍存在的问题
  18. 用python 实现发射爱心
  19. 如何将抓取下来的unicode字符串转换为中文
  20. chiinv函数java_Excel 使用CHIINV函数和GAMMA.DIST函数绘制卡方分布

热门文章

  1. 服务器IO高,系统卡死
  2. 天原笔记(4)大气环流
  3. 高级软件架构师实战培训阶二
  4. 确界原理证明实数完备性定理
  5. Intel e1000 网卡
  6. 90+深度学习开源数据集整理|包括目标检测、工业缺陷、图像分割等多个方向
  7. 极客日报:华为诉争“鸿蒙HongMeng”商标再被驳回;比尔盖茨夫妇正式离婚;iOS 15“查找”新功能,关机也能用
  8. 来自网页的消息服务器不能创建对象,mation服务器不能创建对象
  9. TTFB响应时快时慢问题解决
  10. 电脑强制关机导致本地mysql无法启动_本地mysql因为电脑突然重启造成了mysql无法启动...