Tipi in MySQL: BigInt (20) vs Int (20)


221

Mi chiedevo quale fosse la differenza tra BigInt, MediumInte Intsono ... sembrerebbe ovvio che consentirebbero numeri più grandi; tuttavia, posso fare un Int(20)o un BigInt(20)e ciò sembrerebbe che non si tratti necessariamente di dimensioni.

Alcune intuizioni sarebbero fantastiche, un po 'curiose. Uso MySQL da un po 'e cerco di applicare le esigenze aziendali nella scelta dei tipi, ma non ho mai capito questo aspetto.

Risposte:


478

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

  • INT è un numero intero con segno a quattro byte.

  • BIGINT è un numero intero con segno a otto byte.

Ognuno di essi accetta non più né meno valori di quanti possano essere memorizzati nel rispettivo numero di byte. Ciò significa che 2 32 valori in an INTe 2 64 valori in a BIGINT.

Il 20 in INT(20)e non BIGINT(20)significa quasi nulla. È un suggerimento per la larghezza del display. Non ha nulla a che fare con l'archiviazione, né l'intervallo di valori che la colonna accetterà.

In pratica, interessa solo l' ZEROFILLopzione:

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

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

È una fonte comune di confusione per gli utenti MySQL di vedere INT(20)e assumere che sia un limite di dimensioni, qualcosa di analogo a CHAR(20). Questo non è il caso.


4
Caspita, questo post ha chiarito perfettamente la mia confusione su questo argomento. Sembra una scelta strana da parte degli sviluppatori - come avrei immaginato fosse larghezza + valore massimo, o bit / ecc.
Sh4d0wsPlyr,

27
`interessa solo l'opzione ZEROFILL:` ora la mia curiosità finisce
Umair,

6
Vorrei davvero che avessero progettato la sintassi con il display con su ZEROFILL invece di INT. Esempio: bar INT ZEROFILL(20). Sarebbe stato molto più chiaro. Ma quella decisione è stata presa molto tempo fa, e cambiarla ora avrebbe rotto milioni di installazioni di database.
Bill Karwin,

1
Sono d'accordo che questo è molto confuso. Avevo l'impressione che il numero fosse il limite per tutto questo tempo. Persino preoccupato di ridurre alcuni numeri quando sapevo che i dati sarebbero stati entro un certo intervallo.
jDub9,

2
@ jDub9, sì, ed è ancora più confusa che NUMERICO / DECIMALE prendere un argomento di precisione che fa influenzare l'intervallo di valori e la dimensione della colonna.
Bill Karwin,

40

Il numero tra parentesi in una dichiarazione di tipo è la larghezza di visualizzazione , che non è correlata all'intervallo di valori che possono essere memorizzati in un tipo di dati. Solo perché puoi dichiarare Int(20)non significa che puoi memorizzare valori fino a 10 ^ 20 al suo interno:

[...] Questa larghezza di visualizzazione facoltativa può essere utilizzata dalle applicazioni per visualizzare valori interi con una larghezza inferiore alla larghezza specificata per la colonna riempiendoli a sinistra di spazi. ...

La larghezza di visualizzazione non limita l'intervallo di valori che è possibile memorizzare nella colonna, né il numero di cifre visualizzate per valori con una larghezza superiore a quella specificata per la colonna. Ad esempio, una colonna specificata come SMALLINT (3) ha il solito intervallo SMALLINT da -32768 a 32767 e i valori al di fuori dell'intervallo consentito da tre caratteri vengono visualizzati utilizzando più di tre caratteri.

Per un elenco dei valori massimo e minimo che possono essere memorizzati in ciascun tipo di dati MySQL, vedere qui .


18

Preventivo :

La specifica "BIGINT (20)" non è un limite di cifre. Significa solo che quando i dati vengono visualizzati, se utilizza meno di 20 cifre, saranno riempiti a sinistra con zeri. 2 ^ 64 è il limite rigido per il tipo BIGINT e ha 20 cifre in sé, quindi BIGINT (20) significa che tutto ciò che è inferiore a 10 ^ 20 sarà riempito a sinistra con spazi visualizzati.


3
2 ^ 64 (senza segno) ha in realtà 21 cifre. BIGINT (20) è pericoloso. Le persone che lo usano sembrano giustificare il loro uso sull'idea che 2 ^ 64 si adatta a 20 cifre decimali. In tal caso, perché specificare un limite di larghezza? A quanto pare, anche questo non è corretto. Sono necessarie 21 cifre per visualizzare correttamente 2 ^ 64.
Heath Hunnicutt,

@HeathHunnicutt A meno che non mi sbagli, 2 ^ 64 = 18446744073709551616, che ha 20 cifre. Cosa ti fa dire che ha 21?
drmercer,

3

Per quanto ne so, c'è solo una piccola differenza quando si sta tentando di inserire un valore fuori range.

In esempi userò 401421228216, che è 101110101110110100100011101100010111000(lunghezza 39 caratteri)

  • Se si dispone INT(20)di un sistema, questo significa allocare in memoria almeno 20 bit. Ma se inserirai un valore più grande di 2^20, verrà archiviato correttamente, solo se è inferiore a INT(32) -> 2147483647(o 2 * INT(32) -> 4294967295per UNSIGNED)

Esempio:

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 si dispone BIGINT(20)di un sistema, questo significa allocare in memoria almeno 20 bit. Ma se inserirai un valore maggiore di 2^20, verrà archiviato correttamente, se inferiore a BIGINT(64) -> 9223372036854775807(o 2 * BIGINT(64) -> 18446744073709551615per UNSIGNED)

Esempio:

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

Volevo aggiungere un altro punto è, se stai memorizzando un numero davvero grande come 902054990011312, allora si può facilmente vedere la differenza di INT(20)e BIGINT(20). Si consiglia di conservare in BIGINT.


1

Diamo un esempio per int (10) uno con la parola chiave zerofill, uno no, alla tabella piace che:

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

Inseriamo alcuni dati:

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

Poi

select * from tb_test_int_type; 

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

Possiamo vederlo

  • con la parola chiave zerofill, num inferiore a 10 riempirà 0, ma senza di zerofillessa non lo farà

  • In secondo luogo con la parola chiave zerofill, int_10_with_zf diventa un tipo int senza segno, se si inserisce un segno meno si otterrà un errore Out of range value for column...... Ma puoi inserire meno in int_10. Inoltre, se si inserisce 4294967291 in int_10, si otterrà un erroreOut of range value for column.....

Conclusione:

  1. int (X) senza parola chiave zerofill, è uguale all'intervallo int -2147483648 ~ 2147483647

  2. int (X) con parola chiave zerofill, il campo è uguale all'intervallo int senza segno 0 ~ 4294967295, se la lunghezza di num è inferiore a X riempirà 0 a sinistra

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.