Types dans MySQL: BigInt (20) vs Int (20)

221

Je me demandais quelle est la différence entre BigInt, MediumIntet Intsont ... il semblerait évident qu'ils permettraient un plus grand nombre; cependant, je peux faire un Int(20)ou un BigInt(20)et cela donnerait l'impression qu'il ne s'agit pas nécessairement de taille.

Un aperçu serait génial, juste curieux. J'utilise MySQL depuis un certain temps et j'essaie d'appliquer les besoins de l'entreprise lors du choix des types, mais je n'ai jamais compris cet aspect.

Parris
la source

Réponses:

479

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

  • INT est un entier signé de quatre octets.

  • BIGINT est un entier signé de huit octets.

Ils n'acceptent chacun ni plus ni moins de valeurs que celles qui peuvent être stockées dans leur nombre d'octets respectif. Cela signifie 2 32 valeurs dans an INTet 2 64 valeurs dans a BIGINT.

Le 20 INT(20)et BIGINT(20)signifie presque rien. C'est un indice de largeur d'affichage. Cela n'a rien à voir avec le stockage, ni la plage de valeurs acceptée par cette colonne.

En pratique, cela n'affecte que l' ZEROFILLoption:

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

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

C'est une source courante de confusion pour les utilisateurs de MySQL pour voir INT(20)et supposer que c'est une limite de taille, quelque chose d'analogue à CHAR(20). Ce n'est pas le cas.

Bill Karwin
la source
4
Wow, ce poste a parfaitement dissipé ma confusion à ce sujet. Cela semble être un choix étrange de la part des développeurs - comme je l'aurais deviné, c'était la largeur + la valeur maximale, ou les bits / etc.
Sh4d0wsPlyr
27
`cela n'affecte que l'option ZEROFILL:` maintenant ma curiosité se termine
Umair
6
Je souhaite vraiment qu'ils aient conçu la syntaxe avec l'affichage avec sur ZEROFILL au lieu de INT. Exemple: bar INT ZEROFILL(20). Cela aurait été beaucoup plus clair. Mais cette décision a été prise il y a longtemps, et la changer maintenant briserait des millions d'installations de bases de données.
Bill Karwin
1
Je suis d'accord, c'est très déroutant. J'avais l'impression que le nombre était la limite tout ce temps. Même inquiet de réduire certains nombres quand je savais que les données seraient dans une certaine plage.
jDub9
2
@ jDub9, oui, et il est encore plus déroutant que NUMERIC / DECIMAL d'argument de précision qui n'affecte la plage de valeurs et la taille de la colonne.
Bill Karwin
40

Le nombre entre parenthèses dans une déclaration de type est la largeur d'affichage , qui n'est pas liée à la plage de valeurs qui peut être stockée dans un type de données. Ce Int(20)n'est pas parce que vous pouvez déclarer que vous pouvez y stocker jusqu'à 10 ^ 20:

[...] Cette largeur d'affichage facultative peut être utilisée par les applications pour afficher des valeurs entières ayant une largeur inférieure à la largeur spécifiée pour la colonne en les remplissant à gauche avec des espaces. ...

La largeur d'affichage ne limite pas la plage de valeurs pouvant être stockées dans la colonne, ni le nombre de chiffres affichés pour les valeurs dont la largeur dépasse celle spécifiée pour la colonne. Par exemple, une colonne spécifiée comme SMALLINT (3) a la plage SMALLINT habituelle de -32768 à 32767 et les valeurs en dehors de la plage autorisée par trois caractères sont affichées en utilisant plus de trois caractères.

Pour une liste des valeurs maximales et minimales qui peuvent être stockées dans chaque type de données MySQL, voir ici .

John Feminella
la source
18

Citation :

La spécification "BIGINT (20)" n'est pas une limite de chiffres. Cela signifie simplement que lorsque les données sont affichées, si elles utilisent moins de 20 chiffres, elles seront remplies de zéros à gauche. 2 ^ 64 est la limite stricte pour le type BIGINT, et a lui-même 20 chiffres, donc BIGINT (20) signifie simplement que tout ce qui est inférieur à 10 ^ 20 sera rempli à gauche avec des espaces affichés.

Poneys OMG
la source
3
2 ^ 64 (non signé) comporte en fait 21 chiffres. BIGINT (20) est dangereux. Les personnes qui l'utilisent semblent justifier leur utilisation sur l'idée que 2 ^ 64 tient sur 20 chiffres décimaux. Si tel est le cas, pourquoi spécifier une limite de largeur? En fin de compte, ce n'est pas non plus correct. 21 chiffres sont nécessaires pour afficher correctement 2 ^ 64.
Heath Hunnicutt
@HeathHunnicutt Sauf erreur, 2 ^ 64 = 18446744073709551616, qui comporte 20 chiffres. Qu'est-ce qui vous fait dire qu'il en a 21?
drmercer
3

Pour autant que je sache, il n'y a qu'une petite différence lorsque vous essayez d'insérer une valeur hors de portée.

Dans les exemples que j'utiliserai 401421228216, c'est-à-dire 101110101110110100100011101100010111000(longueur 39 caractères)

  • Si vous avez INT(20)pour le système, cela signifie allouer au moins 20 bits en mémoire. Mais si vous insérez une valeur plus grande que 2^20, elle sera stockée avec succès, uniquement si elle est inférieure à INT(32) -> 2147483647(ou 2 * INT(32) -> 4294967295pour UNSIGNED)

Exemple:

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)
  • Si vous avez BIGINT(20)pour le système, cela signifie allouer au moins 20 bits en mémoire. Mais si vous insérez une valeur plus grande que 2^20, elle sera stockée avec succès, si elle est inférieure à BIGINT(64) -> 9223372036854775807(ou 2 * BIGINT(64) -> 18446744073709551615pour UNSIGNED)

Exemple:

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)
Sergey Podgornyy
la source
1

Je voulais ajouter un point supplémentaire: si vous stockez un très grand nombre comme 902054990011312, vous pouvez facilement voir la différence entre INT(20)et BIGINT(20). Il est conseillé de ranger BIGINT.

Debasis Sabat
la source
1

Donnons un exemple pour int (10) un avec le mot-clé zerofill, un pas, le tableau aime ça:

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

Insérons quelques données:

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

ensuite

select * from tb_test_int_type; 

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

On peut voir ça

  • avec un mot clé zerofill, un nombre inférieur à 10 remplira 0, mais sans zerofilllui

  • Deuxièmement, avec le mot clé zerofill, int_10_with_zf devient un type int non signé, si vous insérez un moins, vous obtiendrez une erreur Out of range value for column...... Mais vous pouvez insérer moins à int_10. De plus, si vous insérez 4294967291 dans int_10, vous obtiendrez une erreurOut of range value for column.....

Conclusion:

  1. int (X) sans mot clé zerofill, est égal à la plage int -2147483648 ~ 2147483647

  2. int (X) avec le mot zerofill- clé , le champ est égal à la plage int non signée 0 ~ 4294967295, si la longueur de num est inférieure à X, il remplira 0 à gauche

Jayhello
la source