Tipos no MySQL: BigInt (20) vs Int (20)

Eu queria saber qual é a diferença entre BigInt , MediumInt e Int … parece óbvio que eles permitiriam números maiores; no entanto, eu posso fazer um Int(20) ou um BigInt(20) e isso faria parecer que não é necessariamente sobre o tamanho.

Alguma ideia seria incrível, apenas curiosa. Eu tenho usado o MySQL por um tempo e tentando aplicar as necessidades de negócios ao escolher tipos, mas nunca entendi esse aspecto.

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

  • INT é um inteiro assinado de quatro bytes.

  • BIGINT é um inteiro assinado de oito bytes.

Cada um deles não aceita mais nem menos valores que podem ser armazenados em seus respectivos números de bytes. Isso significa 2 32 valores em um INT e 2 64 valores em um BIGINT .

O 20 em INT(20) e BIGINT(20) significa quase nada. É uma dica para a largura da canvas. Não tem nada a ver com armazenamento nem com o intervalo de valores que a coluna aceitará.

Praticamente, afeta apenas a opção ZEROFILL :

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

É uma fonte comum de confusão para os usuários do MySQL ver INT(20) e assumir que é um limite de tamanho, algo análogo a CHAR(20) . Este não é o caso.

O número entre parênteses em uma declaração de tipo é a largura de exibição , que não está relacionada ao intervalo de valores que podem ser armazenados em um tipo de dados. Só porque você pode declarar Int(20) não significa que você pode armazenar valores de até 10 ^ 20 nele:

[…] Essa largura de exibição opcional pode ser usada por aplicativos para exibir valores inteiros com largura menor que a largura especificada para a coluna preenchendo-os com espaços. …

A largura de exibição não restringe o intervalo de valores que podem ser armazenados na coluna nem o número de dígitos exibidos para valores com largura superior à especificada para a coluna. Por exemplo, uma coluna especificada como SMALLINT (3) tem o intervalo SMALLINT usual de -32768 a 32767 e valores fora do intervalo permitido por três caracteres são exibidos usando mais de três caracteres.

Para uma lista dos valores máximo e mínimo que podem ser armazenados em cada tipo de dados MySQL, veja aqui .

Citação :

A especificação “BIGINT (20)” não é um limite de dígitos. Significa apenas que quando os dados são exibidos, se ele usa menos de 20 dígitos, ele será preenchido com zeros. 2 ^ 64 é o limite rígido para o tipo BIGINT, e tem 20 dígitos em si, portanto, BIGINT (20) significa apenas que tudo menos que 10 ^ 20 será preenchido com espaços à esquerda.

Tanto quanto eu sei, há apenas uma pequena diferença é quando você está tentando inserir valor que está fora do intervalo.

Nos exemplos, usarei 401421228216 , que é 101110101110110100100011101100010111000 (comprimento 39 caracteres)

  • Se você tiver INT(20) para o sistema, isso significa alocar na memory, no mínimo, 20 bits. Mas se você inserir valor maior que 2^20 , ele será armazenado com sucesso, somente se for menor que INT(32) -> 2147483647 (ou 2 * INT(32) -> 4294967295 para UNSIGNED )

Exemplo:

 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) 
  • Se você tiver BIGINT(20) para o sistema, isso significa alocar na memory, no mínimo, 20 bits. Mas se você inserir valor maior que 2^20 , ele será armazenado com sucesso, se for menor que BIGINT(64) -> 9223372036854775807 (ou 2 * BIGINT(64) -> 18446744073709551615 para UNSIGNED )

Exemplo:

 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) 

Eu queria adicionar mais um ponto é, se você está armazenando um número muito grande como 902054990011312, então pode-se ver facilmente a diferença de INT(20) e BIGINT(20) . É aconselhável armazenar em BIGINT .

Vamos dar um exemplo para int (10) um com zerofill keyword, um não, a tabela gosta disso:

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

Vamos inserir alguns dados:

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

Então

 select * from tb_test_int_type; # int_10, int_10_with_zf, unit '123456', '0000123456', '3147483647' '123456', '4294967291', '3147483647' 

Nós podemos ver isso

  • com a palavra-chave zerofill , num menor que 10 preencherá 0, mas sem zerofill não

  • Em segundo lugar, com a palavra-chave zerofill , int_10_with_zf torna-se unsigned int type, se você inserir um menos, você receberá um erro Out of range value for column..... Mas você pode inserir menos para int_10. Além disso, se você inserir 4294967291 em int_10, receberá um erro Out of range value for column.....

Conclusão:

  1. int (X) sem a palavra-chave zerofill , é igual a int intervalo -2147483648 ~ 2147483647

  2. int (X) com a palavra-chave zerofill , o campo é igual a unsigned int range 0 ~ 4294967295, se o comprimento do num é menor que X ele irá preencher 0 à esquerda