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


221

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

Деяке розуміння було б приголомшливим, просто цікавим. Я деякий час використовую MySQL і намагаюся застосувати бізнес-потреби при виборі типів, але я ніколи не розумів цього аспекту.

Відповіді:


478

Дивіться http://dev.mysql.com/doc/refman/8.0/en/numeric-types.html

  • INT це чотирибайтове підписане ціле число.

  • BIGINT - це вісімбайтове підписане ціле число.

Вони приймають не більше і не менше значень, ніж можуть бути збережені у відповідній кількості байтів. Це означає 2 32 значення в INTі 2 64 значення в 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?
drmercer

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 -2147483648 ~ 2147483647

  2. int (X) з ключовим словом zerofill, поле дорівнює неподписаному діапазону int 0 ~ 4294967295, якщо довжина num менша ніж X, вона заповнить 0 зліва

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.