MySQL中的类型:BigInt(20)与Int(20)


221

我想知道什么之间的区别BigIntMediumInt以及Int在...这似乎很明显,他们将允许更大的数字; 但是,我可以使一个Int(20)或一个BigInt(20)看起来似乎不一定与大小有关。

一些见识会很棒,只是有点好奇。我使用MySQL已有一段时间,并在选择类型时尝试满足业务需求,但是我从不理解这一方面。

Answers:


478

http://dev.mysql.com/doc/refman/8.0/en/numeric-types.html

  • INT 是一个四字节有符号整数。

  • BIGINT 是一个八字节有符号整数。

它们各自接受的值不超过可以存储在其各自字节数中的值。表示中的2 32个INT和中的2 64个BIGINT

20 in INT(20)BIGINT(20)几乎没有任何意义。这是显示宽度的提示。它与存储无关,也与列将接受的值的范围无关。

实际上,它仅影响以下ZEROFILL选项:

CREATE TABLE foo ( bar INT(20) ZEROFILL );
INSERT INTO foo (bar) VALUES (1234);
SELECT bar from foo;

+----------------------+
| bar                  |
+----------------------+
| 00000000000000001234 |
+----------------------+

对于MySQL用户而言,看到INT(20)并假设它是一个大小限制(类似于)是一个常见的困惑源CHAR(20)。不是这种情况。


4
哇,这篇文章很好地消除了我对此主题的困惑。似乎是开发人员的一个奇怪选择-正如我猜想的是宽度+最大值或位/等。
Sh4d0wsPlyr

27
`它仅影响ZEROFILL选项:`现在我的好奇心结束了
Umair

6
我真的希望他们设计的语法是在ZEROFILL而不是INT上显示的。范例:bar INT ZEROFILL(20)。这本来应该清楚得多。但是这个决定是很久以前做出的,现在更改它会破坏数百万个数据库的安装。
Bill Karwin '16

1
我同意这是非常令人困惑的。我一直以为这个数字一直都是极限。当我知道数据会在一定范围内时,甚至担心要减小一些数字。
jDub9

2
@ jDub9,是的,更令人困惑的是NUMERIC / DECIMAL带有一个影响值范围和列大小的精度参数。
比尔·卡温

40

类型声明中括号内的数字是display width,它与可以存储在数据类型中的值的范围无关。仅仅因为您可以声明Int(20)并不意味着您可以在其中存储最多10 ^ 20的值:

[...]应用程序可以使用此可选显示宽度来显示整数值,该整数值的宽度小于为列指定的宽度,方法是用空格左键填充它们。...

显示宽度不限制可以存储在该列中的值的范围,也不限制宽度超出该列指定值的值所显示的位数。例如,指定为SMALLINT(3)的列通常具有-32768到32767的SMALLINT范围,并且使用三个以上的字符来显示三个字符所允许的范围之外的值。

有关每个MySQL数据类型中可以存储的最大值和最小值的列表,请参见此处


18

引用

“ BIGINT(20)”规范不是数字限制。它仅表示在显示数据时,如果使用的数字少于20位,则将在其后填充零。2 ^ 64是BIGINT类型的硬限制,它本身具有20位数字,因此BIGINT(20)意味着小于10 ^ 20的所有内容都将在显示时保留空格。


3
2 ^ 64(无符号)实际上有21位数字。BIGINT(20)是危险的。使用它的人似乎以2 ^ 64可以容纳20个十进制数字的想法来证明自己的用法是正确的。如果是这样,为什么还要指定宽度限制?事实证明,这也不正确。需要21位数字才能正确显示2 ^ 64。
Heath Hunnicutt

@HeathHunnicutt除非我输错了,否则2 ^ 64 = 18446744073709551616,它具有20位数字。是什么让你说它有21个?
drmercer

3

据我所知,只有一个小的区别是您尝试插入超出范围的值。

在实施例I将使用401421228216,这是101110101110110100100011101100010111000(长度39个字符)

  • 如果您有INT(20)系统,则意味着在内存中至少分配20位。但是,如果您插入的值大于2^20,则该值将被成功存储,只有小于INT(32) -> 2147483647(或2 * INT(32) -> 4294967295UNSIGNED

例:

mysql> describe `test`;
+-------+------------------+------+-----+---------+-------+
| Field | Type             | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+-------+
| id    | int(20) unsigned | YES  |     | NULL    |       |
+-------+------------------+------+-----+---------+-------+
1 row in set (0,00 sec)

mysql> INSERT INTO `test` (`id`) VALUES (401421228216);
ERROR 1264 (22003): Out of range value for column 'id' at row 1

mysql> SET sql_mode = '';
Query OK, 0 rows affected, 1 warning (0,00 sec)

mysql> INSERT INTO `test` (`id`) VALUES (401421228216);
Query OK, 1 row affected, 1 warning (0,06 sec)

mysql> SELECT * FROM `test`;
+------------+
| id         |
+------------+
| 4294967295 |
+------------+
1 row in set (0,00 sec)
  • 如果您有BIGINT(20)系统,则意味着在内存中至少分配20位。但是,如果你插入值比我的大2^20,它将被成功存储,如果是小于BIGINT(64) -> 9223372036854775807(或2 * BIGINT(64) -> 18446744073709551615UNSIGNED

例:

mysql> describe `test`;
+-------+---------------------+------+-----+---------+-------+
| Field | Type                | Null | Key | Default | Extra |
+-------+---------------------+------+-----+---------+-------+
| id    | bigint(20) unsigned | YES  |     | NULL    |       |
+-------+---------------------+------+-----+---------+-------+
1 row in set (0,00 sec)

mysql> INSERT INTO `test` (`id`) VALUES (401421228216);
Query OK, 1 row affected (0,04 sec)

mysql> SELECT * FROM `test`;
+--------------+
| id           |
+--------------+
| 401421228216 |
+--------------+
1 row in set (0,00 sec)


1

让我们举一个int(10)的例子,其中一个带有zerofill关键字,一个不是,该表如下所示:

create table tb_test_int_type(
    int_10 int(10),
    int_10_with_zf int(10) zerofill,
    unit int unsigned
);

让我们插入一些数据:

insert into tb_test_int_type(int_10, int_10_with_zf, unit)
values (123456, 123456,3147483647), (123456, 4294967291,3147483647) 
;

然后

select * from tb_test_int_type; 

# int_10, int_10_with_zf, unit
'123456', '0000123456', '3147483647'
'123456', '4294967291', '3147483647'

我们可以看到

  • 关键字zerofill,小于10的num将填充0,但如果没有zerofill,则不会填充0

  • 其次,使用关键字zerofillint_10_with_zf成为无符号的int类型,如果插入减号,则会得到error Out of range value for column.....。但是您可以在int_10处插入减号。另外,如果将4294967291插入int_10,也会收到错误消息Out of range value for column.....

结论:

  1. 不带关键字的int(X)zerofill等于int范围-2147483648〜2147483647

  2. int(X)with keyword zerofill,该字段等于unsigned int范围0〜4294967295,如果num的长度小于X,它将在左侧填充0

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.