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

221

Me preguntaba cuál es la diferencia entre BigInt, MediumInty Intson ... parecería obvio que permitirían números más grandes; Sin embargo, puedo hacer una Int(20)o una BigInt(20)y eso parecería que no se trata necesariamente del tamaño.

Alguna idea sería increíble, solo un poco curiosa. He estado usando MySQL durante un tiempo e intenté aplicar las necesidades comerciales al elegir tipos, pero nunca entendí este aspecto.

Parris
fuente

Respuestas:

479

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

  • INT es un entero con signo de cuatro bytes.

  • BIGINT es un entero con signo de ocho bytes.

Cada uno de ellos no acepta más ni menos valores de los que se pueden almacenar en su respectivo número de bytes. Eso significa 2 32 valores en an INTy 2 64 valores en a BIGINT.

El 20 en INT(20)y no BIGINT(20)significa casi nada. Es una pista para el ancho de la pantalla. No tiene nada que ver con el almacenamiento, ni el rango de valores que aceptará la columna.

Prácticamente, afecta solo la ZEROFILLopción:

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

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

Es una fuente común de confusión para los usuarios de MySQL ver INT(20)y asumir que es un límite de tamaño, algo análogo a esto CHAR(20). Este no es el caso.

Bill Karwin
fuente
44
Wow, esta publicación aclaró mi confusión sobre este tema perfectamente. Parece una elección extraña por parte de los desarrolladores, como habría supuesto que era ancho + valor máximo, o bits / etc.
Sh4d0wsPlyr
27
`afecta solo a la opción ZEROFILL:` ahora mi curiosidad termina
Umair
66
Realmente desearía que hubieran diseñado la sintaxis con la pantalla con ZEROFILL en lugar de INT. Ejemplo: bar INT ZEROFILL(20). Hubiera sido mucho más claro. Pero esa decisión se tomó hace mucho tiempo, y cambiarla ahora rompería millones de instalaciones de bases de datos.
Bill Karwin
1
Estoy de acuerdo en que esto es muy confuso. Tenía la impresión de que ese número era el límite todo este tiempo. Incluso me preocupaba reducir algunos números cuando sabía que los datos estarían dentro de cierto rango.
jDub9
2
@ jDub9, sí, y es aún más confuso que NUMÉRICO / DECIMAL toma un argumento de precisión que hace afectar el rango de valores y el tamaño de la columna.
Bill Karwin el
40

El número entre paréntesis en una declaración de tipo es el ancho de visualización , que no está relacionado con el rango de valores que se pueden almacenar en un tipo de datos. El hecho de que pueda declarar Int(20)no significa que pueda almacenar valores de hasta 10 ^ 20 en él:

[...] Este ancho de visualización opcional puede ser utilizado por aplicaciones para mostrar valores enteros que tengan un ancho menor que el ancho especificado para la columna al rellenarlos con espacios a la izquierda. ...

El ancho de visualización no restringe el rango de valores que se pueden almacenar en la columna, ni el número de dígitos que se muestran para los valores que tienen un ancho superior al especificado para la columna. Por ejemplo, una columna especificada como SMALLINT (3) tiene el rango SMALLINT habitual de -32768 a 32767, y los valores fuera del rango permitido por tres caracteres se muestran con más de tres caracteres.

Para obtener una lista de los valores máximos y mínimos que se pueden almacenar en cada tipo de datos MySQL, consulte aquí .

John Feminella
fuente
18

Cita :

La especificación "BIGINT (20)" no es un límite de dígitos. Simplemente significa que cuando se muestran los datos, si usa menos de 20 dígitos, se rellena con ceros a la izquierda. 2 ^ 64 es el límite estricto para el tipo BIGINT, y tiene 20 dígitos, por lo tanto BIGINT (20) solo significa que todo menos de 10 ^ 20 se rellenará con espacios en la pantalla.

Ponis OMG
fuente
3
2 ^ 64 (sin signo) en realidad tiene 21 dígitos. BIGINT (20) es peligroso. Las personas que lo usan parecen justificar su uso con la idea de que 2 ^ 64 cabe en 20 dígitos decimales. Si ese es el caso, ¿por qué especificar un límite de ancho? Resulta que eso tampoco es correcto. Se necesitan 21 dígitos para mostrar correctamente 2 ^ 64.
Heath Hunnicutt
@HeathHunnicutt A menos que me equivoque, 2 ^ 64 = 18446744073709551616, que tiene 20 dígitos. ¿Qué te hace decir que tiene 21?
Drmercer
3

Hasta donde sé, solo hay una pequeña diferencia cuando intentas insertar un valor que está fuera de rango.

En los ejemplos que usaré 401421228216, que es 101110101110110100100011101100010111000(longitud 39 caracteres)

  • Si tiene INT(20)para el sistema, esto significa asignar en la memoria un mínimo de 20 bits. Pero si inserta un valor mayor que 2^20, se almacenará con éxito, solo si es menor que INT(32) -> 2147483647(o 2 * INT(32) -> 4294967295para UNSIGNED)

Ejemplo:

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 tiene BIGINT(20)para el sistema, esto significa asignar en la memoria un mínimo de 20 bits. Pero si inserta un valor mayor que 2^20, se almacenará con éxito, si es menor que BIGINT(64) -> 9223372036854775807(o 2 * BIGINT(64) -> 18446744073709551615para UNSIGNED)

Ejemplo:

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
fuente
1

Quería agregar un punto más: si está almacenando un número realmente grande como 902054990011312, entonces se puede ver fácilmente la diferencia de INT(20)y BIGINT(20). Es recomendable almacenar en BIGINT.

Debasis Sabat
fuente
1

Pongamos un ejemplo para int (10) uno con la palabra clave zerofill, uno no, a la tabla le gusta eso:

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

Insertemos algunos datos:

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

Luego

select * from tb_test_int_type; 

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

Podemos ver eso

  • con la palabra clave zerofill, num menos de 10 llenará 0, pero sin zerofillella no

  • En segundo lugar, con la palabra clave zerofill, int_10_with_zf se convierte en el tipo int sin signo, si inserta un signo menos, obtendrá un error Out of range value for column...... Pero puede insertar menos a int_10. Además, si inserta 4294967291 en int_10 obtendrá un errorOut of range value for column.....

Conclusión:

  1. int (X) sin palabra clave zerofill, es igual al rango int -2147483648 ~ 2147483647

  2. int (X) con la palabra clave zerofill, el campo es igual al rango int sin signo 0 ~ 4294967295, si la longitud de num es menor que X, llenará 0 a la izquierda

Jayhello
fuente