我想知道BigInt,MediumInt和Int之间的区别是什么……似乎可以允许更大的数字;这似乎很明显。 但是,我可以制作一个Int(20)或一个BigInt(20),这似乎使它不一定与大小有关。
一些见识会很棒,只是有点好奇。 我使用MySQL已有一段时间,并在选择类型时尝试满足业务需求,但是我从不理解这一方面。
见http://dev.mysql.com/doc/refman/8.0/en/numeric-types.html
INT是一个四字节有符号整数。
BIGINT是一个八字节有符号整数。
它们各自接受的值不超过可以存储在其各自字节数中的值。这意味着INT中的232个值和BIGINT中的264个值。
Int(20)和BIGINT(20)中的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))是一个普遍的困惑。不是这种情况。
哇,这篇帖子很好地消除了我对此主题的困惑。似乎是开发人员的一个奇怪选择-正如我猜想的是宽度+最大值或位/等。
`它仅影响ZEROFILL选项:`现在我的好奇心结束了
我真的希望他们设计的语法是在ZEROFILL而不是INT上显示的。示例:bar INT ZEROFILL(20)。这本来应该清楚得多。但是这个决定是很久以前做出的,现在更改它会破坏数百万个数据库的安装。
我同意这非常令人困惑。我一直以为这个数字一直都是极限。当我知道数据会在一定范围内时,甚至担心要减小一些数字。
@ jDub9,是的,更令人困惑的是NUMERIC / DECIMAL带有一个精度参数,该参数确实会影响值的范围和列的大小。
类型声明中括号内的数字是显示宽度,该宽度与可以存储在数据类型中的值的范围无关。仅仅因为您可以声明Int(20)并不意味着您可以在其中存储最多10 ^ 20的值:
[...] 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. ...
The display width does not constrain the range of values that can be stored in the column, nor the number of digits that are displayed for values having a width exceeding that specified for the column. For example, a column specified as SMALLINT(3) has the usual SMALLINT range of -32768 to 32767, and values outside the range allowed by three characters are displayed using more than three characters.
有关每个MySQL数据类型中可以存储的最大值和最小值的列表,请参见此处。
你是说这里
引用:
The"BIGINT(20)" specification isn't a digit limit. It just means that when the data is displayed, if it uses less than 20 digits it will be left-padded with zeros. 2^64 is the hard limit for the BIGINT type, and has 20 digits itself, hence BIGINT(20) just means everything less than 10^20 will be left-padded with spaces on display.
2 ^ 64(无符号)实际上有21位数字。 BIGINT(20)是危险的。使用它的人似乎以2 ^ 64可以包含20个十进制数字的想法来证明其用法是正确的。如果是这样,为什么还要指定宽度限制?事实证明,那也不是正确的。需要21位数字才能正确显示2 ^ 64。
据我所知,只有一个小的区别是您尝试插入超出范围的值。
In examples I'll use 401421228216, which is 101110101110110100100011101100010111000 (length 39 characters)
如果系统具有Int(20),则意味着在内存中分配最少20位。但是,如果您插入的值大于2^20,则只有小于INT(32) -> 2147483647(对于UNSIGNED为2 * INT(32) -> 4294967295)时,该值才能成功存储。
例:
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(对于UNSIGNED,则为2 * BIGINT(64) -> 18446744073709551615)
例:
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)
让我们举一个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的num小于10将填充0,但是如果没有ZEROFILL则不会填充
其次,使用关键字ZEROFILL,int_10_with_zf成为无符号的int类型,如果插入减号,则会出现错误Out of range value for column.....。但是您可以在int_10处插入减号。另外,如果将4294967291插入int_10,也会得到错误Out of range value for column.....
结论:
不带关键字ZEROFILL的int(X)等于int范围-2147483648?2147483647
关键字ZEROFILL的int(X),该字段等于unsigned int范围0?4294967295,如果num的长度小于X,则它将在左侧填充0
我想补充一点,如果您存储的是一个非常大的数字,例如902054990011312,那么您可以很容易地看到Int(20)和BIGINT(20)的区别。建议将其存储在BIGINT中。