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

221

Ich frage mich , was der Unterschied zwischen BigInt, MediumIntund Intsind ... wäre es offensichtlich scheinen , dass sie für größere Zahlen ermöglichen; Ich kann jedoch ein Int(20)oder ein machen BigInt(20)und das würde den Anschein erwecken, dass es nicht unbedingt um Größe geht.

Ein Einblick wäre großartig, nur ein bisschen neugierig. Ich benutze MySQL seit einer Weile und versuche, Geschäftsanforderungen bei der Auswahl von Typen anzuwenden, aber ich habe diesen Aspekt nie verstanden.

Parris
quelle

Antworten:

478

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

  • INT ist eine 4-Byte-Ganzzahl mit Vorzeichen.

  • BIGINT ist eine vorzeichenbehaftete Ganzzahl mit acht Byte.

Sie akzeptieren jeweils nicht mehr und nicht weniger Werte, als in ihrer jeweiligen Anzahl von Bytes gespeichert werden können. Das bedeutet 2 32 Werte in a INTund 2 64 Werte in a BIGINT.

Die 20 in INT(20)und BIGINT(20)bedeutet fast nichts. Dies ist ein Hinweis auf die Anzeigebreite. Es hat nichts mit Speicherung oder dem Wertebereich zu tun, den diese Spalte akzeptiert.

Praktisch betrifft es nur die ZEROFILLOption:

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

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

Es ist eine häufige Quelle der Verwirrung für MySQL-Benutzer, zu sehen INT(20)und anzunehmen, dass es sich um eine Größenbeschränkung handelt, ähnlich wie bei CHAR(20). Das ist nicht der Fall.

Bill Karwin
quelle
4
Wow, dieser Beitrag hat meine Verwirrung zu diesem Thema perfekt ausgeräumt. Scheint eine seltsame Wahl der Entwickler zu sein - wie ich vermutet hätte, war es Breite + Maximalwert oder Bits / etc.
Sh4d0wsPlyr
27
`es betrifft nur die ZEROFILL-Option:` jetzt endet meine Neugier
Umair
6
Ich wünschte wirklich, sie hätten die Syntax mit dem Display mit auf ZEROFILL anstelle von INT entworfen. Beispiel : bar INT ZEROFILL(20). Es wäre viel klarer gewesen. Diese Entscheidung wurde jedoch vor langer Zeit getroffen, und eine Änderung würde Millionen von Datenbankinstallationen beschädigen.
Bill Karwin
1
Ich bin damit einverstanden, dass dies sehr verwirrend ist. Ich hatte den Eindruck, dass die Anzahl die ganze Zeit die Grenze war. Ich machte mir sogar Sorgen, einige Zahlen kleiner zu machen, als ich wusste, dass die Daten in einem bestimmten Bereich liegen würden.
jDub9
2
@ jDub9, ja, und es ist noch verwirrender, dass NUMERIC / DECIMAL ein Präzisionsargument verwenden, das sich auf den Wertebereich und die Größe der Spalte auswirkt.
Bill Karwin
40

Die Zahl in Klammern in einer Typdeklaration ist die Anzeigebreite , die nicht mit dem Wertebereich zusammenhängt, der in einem Datentyp gespeichert werden kann. Nur weil Sie deklarieren können, Int(20)heißt das nicht, dass Sie Werte bis zu 10 ^ 20 darin speichern können:

[...] Diese optionale Anzeigebreite kann von Anwendungen verwendet werden, um ganzzahlige Werte anzuzeigen, deren Breite kleiner als die für die Spalte angegebene Breite ist, indem sie mit Leerzeichen nach links aufgefüllt werden. ...

Die Anzeigebreite schränkt weder den Wertebereich ein, der in der Spalte gespeichert werden kann, noch die Anzahl der Ziffern, die für Werte angezeigt werden, deren Breite die für die Spalte angegebene Breite überschreitet. Beispielsweise hat eine als SMALLINT (3) angegebene Spalte den üblichen SMALLINT-Bereich von -32768 bis 32767, und Werte außerhalb des durch drei Zeichen zulässigen Bereichs werden mit mehr als drei Zeichen angezeigt.

Eine Liste der Maximal- und Minimalwerte, die in jedem MySQL-Datentyp gespeichert werden können, finden Sie hier .

John Feminella
quelle
18

Zitat :

Die Spezifikation "BIGINT (20)" ist keine Ziffernbeschränkung. Es bedeutet nur, dass bei der Anzeige der Daten, wenn sie weniger als 20 Stellen verwenden, diese mit Nullen links aufgefüllt werden. 2 ^ 64 ist die harte Grenze für den BIGINT-Typ und hat selbst 20 Ziffern. Daher bedeutet BIGINT (20) nur, dass alles, was weniger als 10 ^ 20 ist, mit angezeigten Leerzeichen links aufgefüllt wird.

OMG Ponys
quelle
3
2 ^ 64 (ohne Vorzeichen) hat tatsächlich 21 Ziffern. BIGINT (20) ist gefährlich. Leute, die es benutzen, scheinen ihre Verwendung mit der Idee zu rechtfertigen, dass 2 ^ 64 in 20 Dezimalstellen passt. Wenn dies der Fall ist, warum überhaupt eine Breitenbeschränkung angeben? Wie sich herausstellt, ist das auch nicht richtig. 21 Ziffern werden benötigt, um 2 ^ 64 richtig anzuzeigen.
Heath Hunnicutt
@HeathHunnicutt Wenn ich mich nicht irre, 2 ^ 64 = 18446744073709551616, die 20 Ziffern hat. Was lässt Sie sagen, dass es 21 hat?
Drmercer
3

Soweit ich weiß, gibt es nur einen kleinen Unterschied, wenn Sie versuchen, einen Wert einzufügen, der außerhalb des Bereichs liegt.

In Beispielen werde ich verwenden 401421228216, die ist 101110101110110100100011101100010111000(Länge 39 Zeichen)

  • Wenn Sie INT(20)für das System haben, bedeutet dies, mindestens 20 Bit im Speicher zuzuweisen. Wenn Sie jedoch einen Wert einfügen, der größer als ist 2^20, wird er nur dann erfolgreich gespeichert, wenn er kleiner als INT(32) -> 2147483647(oder 2 * INT(32) -> 4294967295für UNSIGNED) ist.

Beispiel:

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)
  • Wenn Sie BIGINT(20)für das System haben, bedeutet dies, mindestens 20 Bit im Speicher zuzuweisen. Wenn Sie jedoch einen Wert einfügen, der größer als ist 2^20, wird er erfolgreich gespeichert, wenn er kleiner als BIGINT(64) -> 9223372036854775807(oder 2 * BIGINT(64) -> 18446744073709551615für UNSIGNED) ist.

Beispiel:

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

Ich wollte noch einen Punkt hinzufügen: Wenn Sie eine wirklich große Zahl wie 902054990011312 speichern, kann man den Unterschied von INT(20)und leicht erkennen BIGINT(20). Es ist ratsam, in zu speichern BIGINT.

Debasis Sabat
quelle
1

Geben wir ein Beispiel für int (10) eins mit dem Schlüsselwort zerofill, eins nicht, die Tabelle sieht so aus:

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

Fügen wir einige Daten ein:

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

Dann

select * from tb_test_int_type; 

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

Wir können das sehen

  • Mit dem Schlüsselwort zerofillwird num kleiner als 10 0 füllen, ohne zerofilljedoch nicht

  • Zweitens mit Schlüsselwort zerofill int_10_with_zf der Int-Typ ohne Vorzeichen. Wenn Sie ein Minus einfügen, wird eine Fehlermeldung angezeigt Out of range value for column...... Sie können jedoch ein Minus in int_10 einfügen. Auch wenn Sie 4294967291 in int_10 einfügen, wird eine Fehlermeldung angezeigtOut of range value for column.....

Fazit:

  1. int (X) ohne Schlüsselwort zerofill entspricht dem int-Bereich -2147483648 ~ 2147483647

  2. int (X) mit dem Schlüsselwort zerofill, das Feld entspricht dem vorzeichenlosen int-Bereich 0 ~ 4294967295, wenn die Länge von num kleiner als X ist, wird 0 links gefüllt

Jayhello
quelle