Типы в MySQL: BigInt (20) против Int (20)


221

Мне было интересно , что разница между BigInt, MediumIntи Intкоторые ... казалось бы , очевидно , что они позволили бы для больших чисел; Тем не менее, я могу сделать Int(20)или или, BigInt(20)и это может показаться, что это не обязательно о размере.

Некоторое понимание было бы потрясающим, просто любопытным. Некоторое время я использовал MySQL и пытался использовать бизнес-потребности при выборе типов, но я никогда не понимал этот аспект.

Ответы:


479

См. Http://dev.mysql.com/doc/refman/8.0/en/numeric-types.html.

  • INT является четырехбайтовым целым числом со знаком.

  • BIGINT является восьмибайтовым целым числом со знаком.

Каждый из них принимает не больше и не меньше значений, чем может быть сохранено в их соответствующем количестве байтов. Это означает, что 2 32 значения в a INTи 2 64 значения в a BIGINT.

20 в 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). Это было бы намного яснее. Но это решение было принято давным-давно, и его изменение сейчас сломало бы миллионы установок баз данных.
Билл Карвин

1
Я согласен, что это очень запутанно. Я был под впечатлением, что число было пределом все это время. Даже беспокоился о сокращении некоторых чисел, когда я знал, что данные будут в определенном диапазоне.
jDub9

2
@ jDub9, да, и еще более странно, что NUMERIC / DECIMAL принимают аргумент точности, который влияет на диапазон значений и размер столбца.
Билл Карвин

40

Число в скобках в объявлении типа - это ширина экрана , которая не связана с диапазоном значений, которые можно сохранить в типе данных. То, что вы можете объявить Int(20), не означает, что вы можете хранить в нем значения до 10 ^ 20:

[...] Эта необязательная ширина отображения может использоваться приложениями для отображения целочисленных значений, ширина которых меньше ширины, указанной для столбца, путем добавления их слева к пробелам. ...

Ширина отображения не ограничивает диапазон значений, которые могут быть сохранены в столбце, ни количество цифр, отображаемых для значений, ширина которых превышает указанную для столбца. Например, столбец, указанный как SMALLINT (3), имеет обычный диапазон SMALLINT от -32768 до 32767, а значения вне диапазона, разрешенного тремя символами, отображаются с использованием более трех символов.

Список максимальных и минимальных значений, которые могут быть сохранены в каждом типе данных MySQL, см. Здесь .


18

Цитата :

Спецификация «BIGINT (20)» не ограничена цифрами. Это просто означает, что когда отображаются данные, если они используют менее 20 цифр, они будут дополнены нулями слева. 2 ^ 64 - это жесткое ограничение для типа BIGINT, которое само по себе имеет 20 цифр, поэтому BIGINT (20) означает, что все, что меньше 10 ^ 20, будет заполнено слева пробелами.


3
2 ^ 64 (без знака) на самом деле имеет 21 цифру. BIGINT (20) опасно. Люди, которые используют его, кажется, оправдывают свое использование идеей, что 2 ^ 64 соответствует 20 десятичным цифрам. Если это так, зачем вообще указывать ограничение ширины? Оказывается, это тоже не правильно. Для правильного отображения 2 ^ 64 необходимо 21 цифра.
Хит Ханникатт

@HeathHunnicutt Если я не ошибаюсь, 2 ^ 64 = 18446744073709551616, который имеет 20 цифр. Что заставляет вас говорить, что у него есть 21?
барабанщик

3

Насколько я знаю, есть только одна небольшая разница, когда вы пытаетесь вставить значение, которое находится за пределами диапазона.

В примерах я буду использовать 401421228216, который 101110101110110100100011101100010111000(длина 39 символов)

  • Если у вас есть INT(20)для системы это означает выделить в памяти минимум 20 бит. Но если вы вставите значение больше чем 2^20, оно будет успешно сохранено, только если оно меньше INT(32) -> 2147483647(или 2 * INT(32) -> 4294967295для UNSIGNED)

Пример:

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) -> 18446744073709551615для UNSIGNED)

Пример:

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

Я хотел бы добавить еще одно замечание: если вы храните действительно большое число, например 902054990011312, тогда легко увидеть разницу INT(20)и BIGINT(20). Желательно хранить в BIGINT.


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 заполнит 0, но без zerofillнего не будет

  • Во-вторых, с ключевым словом zerofillint_10_with_zf становится типом int без знака, если вы вставите минус, вы получите ошибку Out of range value for column...... Но вы можете вставить минус в int_10. Также, если вы вставите 4294967291 в int_10, вы получите ошибкуOut of range value for column.....

Вывод:

  1. int (X) без ключевого слова zerofill, равно int range -2147483648 ~ 2147483647

  2. int (X) с ключевым словом zerofill, поле равно unsigned int range 0 ~ 4294967295, если длина num меньше X, он заполнит 0 слева

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.