MySQL整数数据类型int

一、int类型说明

MySQL整数数据类型int

id      int(M)                             [UNSIGNED]   [ZEROFILL] 
字段名  字段类型(显示长度,创建表时不指定显示长度)  [无符号]     [前导填充]

unsigned
01:int (M)后面加上unsigned,就是无符号,只可插入正整数,其范围: 0~4294967295;
02:4字节就是32位,那么2的32次方减1就是4294967295;
03:因为加了unsigned,就是正整数,也就是无符号,所以范围是0~4294967295;
04:4294967295的长度是10;不指定长度,例如:int unsigned,显示长度就是int (10),但当
你插入的正整数的长度达不到长度10时,不会自动补充,1显示1; 4294967295显示
4294967295;

zerofill
01:int(M)后面加上zerofill参数,会把unsigned带上,也就是无符号,只可插入正整数,范
围是0~4294967295;
02:4字节就是32位,那么2的32次方减1就是4294967295;
03:因为会把unsigned带上,就是正整数,也就是无符号,所以范围是0~4294967295;
04:42949672955的长度是10,不指定长度时,例如:int zerofill,其显示长度就是10,
当你插入正整数长度达不到长度10时,会前导师0填充;1显示0000000001;
4294967295显示4294967295;

不加unsigned和zerofill
不在int后加上unsigned或zerofill,其默认是有符号,也就可插入正整数和负整数,且负整
数和正整数的最大数的长度是10;但是因为要显示符号("-"),所以显示长度11,虽然显示的长
度是11,但对于插入的正整数和负整数的长度达不到长度11时,不会自动前导零填充;

特别说明
01:在创建表的时候,一般不指定其长度,例如:int或int unsigned
02:插入的数据若超出范围,能否插入成功,这个得根据sql_mode中是否开启严格模式,即sql_mode
参数中是否包含STRICT_TRANS_TABLES变量;

二、实践环境准备

-- 数据库版本和默认的存储引擎
mysql> select @@version,@@default_storage_engine;
+------------+--------------------------+
| @@version  | @@default_storage_engine |
+------------+--------------------------+
| 5.7.28-log | InnoDB                   |
+------------+--------------------------+
1 row in set (0.00 sec)

-- 创建chenliang库
mysql> create database if not exists chenliang;
Query OK, 1 row affected (0.03 sec)

mysql> show databases like "chenliang";
+----------------------+
| Database (chenliang) |
+----------------------+
| chenliang            |
+----------------------+
1 row in set (0.03 sec)

-- 进入chenliang库
mysql> use chenliang;
Database changed

mysql> select database();
+------------+
| database() |
+------------+
| chenliang  |
+------------+
1 row in set (0.01 sec)

-- 查看事务是否自动提交
mysql> select @@global.autocommit;
+---------------------+
| @@global.autocommit |
+---------------------+
|                   1 |
+---------------------+
1 row in set (0.00 sec)

三、测试1【加unsigned参数】

SQL_MODE中开启了严格模式,即SQL_MODE参数中包含STRICT_TRANS_TABLES参数

-- 设置会话模式下sql_mode中包含strict_trans_tables变量
mysql> set session sql_mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION";
Query OK, 0 rows affected (0.00 sec)

mysql> select @@sql_mode\G
*************************** 1. row ***************************
@@sql_mode: STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
1 row in set (0.00 sec)

-- 创建test1测试表(这里指定了UNSIGNED,也就是无符号)
mysql> create table if not exists test1(
    -> id int unsigned
    -> );
Query OK, 0 rows affected (0.02 sec)

  -- PS
  -- 表test1的id字段加了unsigned参数,那么id字段的取值范围为0~4294967295
  -- 其显示长度是int(10),因为4294967295的长度是10

-- 查看test1表的表结构
mysql> desc test1;
+-------+------------------+------+-----+---------+-------+
| Field | Type             | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| id    | int(10) unsigned | YES  |     | NULL    |       |
+-------+------------------+------+-----+---------+-------+
1 row in set (0.01 sec)

-- 测试插入0~4294967295范围内的整数和不在该范围内的整数
mysql> insert into test1(id) values(-1);          # 插入数值-1,错误,不在范围内
ERROR 1264 (22003): Out of range value for column ‘id‘ at row 1

mysql> insert into test1(id) values(0);           # 插入数值0,正确,在范围内
Query OK, 1 row affected (0.00 sec)

mysql> insert into test1(id) values(4294967295);  # 插入数值4294967295,正确,在范围内
Query OK, 1 row affected (0.00 sec)

mysql> insert into test1(id) values(4294967296);  # 插入数值4294967296,错误,不在范围内
ERROR 1264 (22003): Out of range value for column ‘id‘ at row 1

mysql> select * from test1;
+------------+
| id         |
+------------+
|          0 |
| 4294967295 |
+------------+
2 rows in set (0.00 sec)

SQL_MODE末开启严格模式,即SQL_MODE参数中不包含STRICT_TRANS_TABLES参数

-- 设置会话模式下sql_mode中不开启严格模式,即不包含strict_trans_tables变量
mysql> set session sql_mode="NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION";
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> select @@sql_mode\G
*************************** 1. row ***************************
@@sql_mode: NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
1 row in set (0.00 sec)

-- 创建test11表(这里指定了UNSIGNED,也就是无符号)
mysql> create table if not exists test11(
    -> id int unsigned
    -> );
Query OK, 0 rows affected (0.01 sec)

  -- PS
  -- 表test11的id字段加了unsigned参数,那么id字段的取值范围为0~4294967295
  -- 其显示长度是int(10),因为4294967295的长度是10

-- 查看test11表的表结构
mysql> desc test11;
+-------+------------------+------+-----+---------+-------+
| Field | Type             | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| id    | int(10) unsigned | YES  |     | NULL    |       |
+-------+------------------+------+-----+---------+-------+
1 row in set (0.00 sec)

-- 测试插入0~4294967295范围内的整数和不在该范围内的整数
mysql> insert into test11(id) values(-1);
Query OK, 1 row affected, 1 warning (0.00 sec)
  -- 不在范围内,但未报错(因为sql_mode中没有开启严格模式)
  -- 插入到表中的数据不是-1,而是0

mysql> insert into test11(id) values(0); 
Query OK, 1 row affected (0.00 sec)
  -- 在范围内,不报错,插入的数据是什么就是什么

mysql> insert into test11(id) values(4294967295);
Query OK, 1 row affected (0.00 sec)
  -- 在范围内,不报错,插入的数据是什么就是什么

mysql> insert into test11(id) values(4294967296);
Query OK, 1 row affected, 1 warning (0.00 sec)
  -- 不在范围内,但未报错(因为sql_mode中没有开启严格模式)
  -- 插入到表中的数据不是4294967296,而是4294967295

mysql> select * from test11;
+------------+
| id         |
+------------+
|          0 |
|          0 |
| 4294967295 |
| 4294967295 |
+------------+
4 rows in set (0.00 sec)

四、测试2【加zerofill参数】

SQL_MODE中开启了严格模式,即SQL_MODE参数中包含STRICT_TRANS_TABLES参数

-- 设置会话模式下sql_mode中包含strict_trans_tables变量
mysql> set session sql_mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION";
Query OK, 0 rows affected (0.00 sec)
mysql> select @@sql_mode\G
*************************** 1. row ***************************
@@sql_mode: STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
1 row in set (0.00 sec)

-- 创建test2表,(这里指定了zerofill,也就是前导零填充)
mysql> create table if not exists test2(
    -> id int zerofill
    -> );
Query OK, 0 rows affected (0.03 sec)

  -- PS
  -- id字段加了zerofill,会前导零填充,会把unsigned参数带上,那么范围为0~4294967295
  -- 显示长度是int(10),因为4294967295的长度是10

-- 查看test2表的表结构
mysql> desc test2;
+-------+---------------------------+------+-----+---------+-------+
| Field | Type                      | Null | Key | Default | Extra |
+-------+---------------------------+------+-----+---------+-------+
| id    | int(10) unsigned zerofill | YES  |     | NULL    |       |
+-------+---------------------------+------+-----+---------+-------+
1 row in set (0.03 sec)

-- 测试插入0~4294967295范围内的整数和不在该范围内的整数
mysql> insert into test2(id) values(-1);          # 插入数值-1,错误,不在范围内
ERROR 1264 (22003): Out of range value for column ‘id‘ at row 1
 
mysql> insert into test2(id) values(0);           # 插入数值0,正确,在范围内
Query OK, 1 row affected (0.00 sec)

mysql> insert into test2(id) values(4294967295);  # 插入数值4294967295,正确,在范围内
Query OK, 1 row affected (0.00 sec)

mysql> insert into test2(id) values(4294967296);  # 插入数值4294967296,错误,不在范围内
ERROR 1264 (22003): Out of range value for column ‘id‘ at row 1

mysql> select * from test2;
+------------+
| id         |
+------------+
| 0000000000 |
| 4294967295 |
+------------+
2 rows in set (0.00 sec)

SQL_MODE末开启严格模式,即SQL_MODE参数中不包含STRICT_TRANS_TABLES参数

-- 设置会话模式下sql_mode中不开启严格模式,即不包含strict_trans_tables变量
mysql> set session sql_mode="NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION";
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> select @@sql_mode\G
*************************** 1. row ***************************
@@sql_mode: NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
1 row in set (0.00 sec)

-- 创建test22表(这里指定了zerofill,也就是前导零填充)
mysql> create table if not exists test22(
    -> id int zerofill
    -> );
Query OK, 0 rows affected (0.00 sec)

  -- PS
  -- id字段加了zerofill,会前导零填充,会把unsigned参数带上,那么范围为0~4294967295
  -- 显示长度是int(10),因为4294967295的长度是10

-- 查看test22表的表结构
mysql> desc test22;
+-------+---------------------------+------+-----+---------+-------+
| Field | Type                      | Null | Key | Default | Extra |
+-------+---------------------------+------+-----+---------+-------+
| id    | int(10) unsigned zerofill | YES  |     | NULL    |       |
+-------+---------------------------+------+-----+---------+-------+
1 row in set (0.00 sec)

-- 测试插入0~4294967295范围内的整数和不在该范围内的整数
mysql> insert into test22(id) values(-1);
Query OK, 1 row affected, 1 warning (0.00 sec)
  -- 不在范围内,但未报错(因为sql_mode中未开启严格模式)
  -- 插入到表中的数据不是-1,而是0,但因为加了zerofill参数,所以会前导零填充

mysql> insert into test22(id) values(0);
Query OK, 1 row affected (0.00 sec)
  -- 在范围内,不报错,插入的数据是多少就是多少

mysql> insert into test22(id) values(4294967295);
Query OK, 1 row affected (0.01 sec)
  -- 在范围内,不报错,插入的数据是多少就是多少

mysql> insert into test22(id) values(4294967296);
Query OK, 1 row affected, 1 warning (0.00 sec)
  -- 不在范围内,但未报错(因为sql_mode中未开启严格模式)
  -- 插入到表中的数据不是4294967296,而是4294967295,因为有zerofill参数,所以会前导零填充

mysql> select * from test22;
+------------+
| id         |
+------------+
| 0000000000 |
| 0000000000 |
| 4294967295 |
| 4294967295 |
+------------+
4 rows in set (0.00 sec)

五、测试3【不加unsigned和zerofill参数】

SQL_MODE中开启了严格模式,即SQL_MODE参数中包含STRICT_TRANS_TABLES参数

-- 设置会话模式下sql_mode中包含strict_trans_tables变量
mysql> set session sql_mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION";
Query OK, 0 rows affected (0.00 sec)

mysql> select @@sql_mode\G
*************************** 1. row ***************************
@@sql_mode: STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
1 row in set (0.00 sec)

-- 创建test3表(不加unsigned和zerofill)
mysql> create table if not exists test3(
    -> id int
    -> );
Query OK, 0 rows affected (0.02 sec)

  -- PS
  -- id字段没加unsigned和zerofill参数,那么id字段的范围为-2147483648~2147483647
  -- 最大数的长度是10,因为要显示符号("-"),所以其最终的显示长度是int(11)

-- 查看test3表的表结构
mysql> desc test3;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)1 row in set (0.01 sec)

-- 测试插入-2147483648~2147483647的整数和不在该范围内的整数
mysql> insert into test3(id) values(-2147483649);  # 错误,不在范围内
ERROR 1264 (22003): Out of range value for column ‘id‘ at row 1

mysql> insert into test3(id) values(-2147483648);  # 正确,在范围内
Query OK, 1 row affected (0.00 sec)

mysql> insert into test3(id) values(2147483647);   # 正确,在范围内
Query OK, 1 row affected (0.00 sec)

mysql> insert into test3(id) values(2147483648);  # 错误,不在范围内
ERROR 1264 (22003): Out of range value for column ‘id‘ at row 1

mysql> select * from test3;
+-------------+
| id          |
+-------------+
| -2147483648 |
|  2147483647 |
+-------------+
2 rows in set (0.00 sec)

SQL_MODE末开启严格模式,即SQL_MODE参数中不包含STRICT_TRANS_TABLES参数

-- 设置会话模式下sql_mode中不开启严格模式,即不包含strict_trans_tables变量
mysql> set session sql_mode="NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION";
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> select @@sql_mode\G
*************************** 1. row ***************************
@@sql_mode: NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
1 row in set (0.00 sec)

-- 创建test33表(不加unsigned和zerofill)
mysql> create table if not exists test33(
    -> id int
    -> );
Query OK, 0 rows affected (0.01 sec)

  -- PS
  -- id字段没加unsigned和zerofill参数,那么id字段的范围为-2147483648~2147483647
  -- 最大数的长度是10,因为要显示符号("-"),所以其最终的显示长度是int(11)

-- 查看test33表的表结构
mysql> desc test33;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)

-- 测试插入-2147483648~2147483647的整数和不在该范围内的整数
mysql> insert into test33(id) values(-2147483649); 
Query OK, 1 row affected, 1 warning (0.00 sec)
  -- 不在范围内,但未报错(因为sql_mode中没有开启严格模式)
  -- 插入到表中的数据不是-2147483649,而是-2147483648;

mysql> insert into test33(id) values(-2147483648); 
Query OK, 1 row affected (0.00 sec)
  -- 在范围内,不会报错,插入的数据是什么就是什么

mysql> insert into test33(id) values(2147483647);
Query OK, 1 row affected (0.00 sec)
  -- 在范围内,不会报错,插入的数据是什么就是什么

mysql> insert into test33(id) values(2147483648); 
Query OK, 1 row affected, 1 warning (0.02 sec)
  -- 不在范围内,但未报错(因为sql_mode中没有开启严格模式)
  -- 插入到表中的数据不是2147483648,而是2147483647;

mysql> select * from test33;
+-------------+
| id          |
+-------------+
| -2147483648 |
| -2147483648 |
|  2147483647 |
|  2147483647 |
+-------------+
4 rows in set (0.00 sec)

相关推荐