MySQL Türleri: BigInt (20) vs Int (20)


221

Ben aradaki fark ne merak ediyorum BigInt, MediumIntve Int... onlar daha büyük sayılar için izin verecek açıktır görünüyor edilir; ancak, bir Int(20)veya a yapabilirim BigInt(20)ve bu mutlaka boyutla ilgili değildir.

Biraz içgörü harika olurdu, sadece biraz meraklı olurdu. Ben kullanıyorum MySQL bir süre ve türleri seçerken iş ihtiyaçlarını uygulamak için çalışıyor, ama bu yönünü hiç anlayamadım.

Yanıtlar:


479

Bkz. Http://dev.mysql.com/doc/refman/8.0/en/numeric-types.html

  • INT dört bayt imzalı bir tam sayıdır.

  • BIGINT sekiz bayt imzalı bir tam sayıdır.

Her biri, ilgili bayt sayısına kaydedilebilecek değerden daha fazla ve daha az değer kabul etmez. Bu, hareket araçları 2 32 bir değerleri INTve 2 64 bir değerleri BIGINT.

20 inç INT(20)ve BIGINT(20)neredeyse hiçbir şey ifade etmiyor. Ekran genişliği için bir ipucu. Depolama ile veya sütunun kabul edeceği değer aralığı ile ilgisi yoktur.

Pratik olarak, sadece ZEROFILLseçeneği etkiler :

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

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

MySQL kullanıcılarının INT(20)bir boyut sınırı, buna benzer bir şey görmesi ve varsayması yaygın bir karışıklık kaynağıdır CHAR(20). Olay bu değil.


4
Vay be, bu yazı bu konudaki karışıklığımı mükemmel bir şekilde temizledi. Geliştiriciler tarafından garip bir seçim gibi görünüyor - tahmin ediyorum ki genişlik + maksimum değer veya bit / vb.
Sh4d0wsPlyr

27
`` sadece ZEROFILL seçeneğini etkiliyor: `` şimdi merakım bitiyor
Umair

6
Ben gerçekten INT yerine ZEROFILL ile ekran ile sözdizimini tasarlamış olmalarını dilerdim. Örnek: bar INT ZEROFILL(20). Çok daha açık olurdu. Ancak bu karar uzun zaman önce alınmıştı ve şimdi değiştirilmesi milyonlarca veritabanı kurulumunu bozacaktır.
Bill Karwin

1
Bunun çok kafa karıştırıcı olduğuna katılıyorum. Bu sayının bu süre boyunca sınır olduğu izlenimi altındaydım. Verilerin belirli bir aralıkta olacağını bildiğimde bazı sayıları küçültmekten bile endişeleniyorum.
jDub9

2
jDub9 @, evet, ve daha da SAYISAL / ONDALIK hassas argüman almasını karıştıran yapar değer aralığını ve sütunun boyutunu etkiler.
Bill Karwin

40

Tür bildirimindeki parantez içindeki sayı, veri türünde saklanabilecek değer aralığı ile ilgisi olmayan görüntüleme genişliğidir . Beyan edebilmeniz Int(20), içinde 10 ^ 20'ye kadar değerleri saklayabileceğiniz anlamına gelmez:

[...] Bu isteğe bağlı ekran genişliği, uygulamalar tarafından sütun için belirtilen genişlikten daha düşük bir genişliğe sahip tamsayı değerlerini boşluklarla sollayarak doldurarak görüntülemek için kullanılabilir. ...

Görüntüleme genişliği, sütunda depolanabilecek değer aralığını veya sütun için belirtilen genişliği aşan değerler için görüntülenen basamak sayısını kısıtlamaz. Örneğin, SMALLINT (3) olarak belirtilen bir sütunda normal SMALLINT aralığı -32768 ile 32767 arasındadır ve üç karakter tarafından izin verilen aralığın dışındaki değerler üçten fazla karakter kullanılarak görüntülenir.

Her bir MySQL veri tipinde saklanabilecek maksimum ve minimum değerlerin listesi için buraya bakın .


18

Alıntı :

"BIGINT (20)" özelliği bir rakam sınırı değildir. Bu sadece veriler görüntülendiğinde, 20 basamaktan az kullanırsa, sıfırlarla solda bırakılacağı anlamına gelir. 2 ^ 64, BIGINT tipi için sabit sınırdır ve 20 basamağa sahiptir, bu nedenle BIGINT (20), 10 ^ 20'den küçük her şeyin ekranda boşluklarla solda kalacağı anlamına gelir.


3
2 ^ 64 (imzasız) aslında 21 basamaklıdır. BIGINT (20) tehlikelidir. Bunu kullanan kişiler, 20 ondalık basamağa 2 ^ 64 sığdığı fikrindeki kullanımlarını haklı çıkarıyor görünmektedir. Durum buysa, neden bir genişlik sınırı belirtmelisiniz? Sonuç olarak, bu da doğru değil. 2 ^ 64'ü düzgün görüntülemek için 21 basamak gerekir.
Heath Hunnicutt

@HeathHunnicutt Yanılmıyorsam, 20 basamaklı 2 ^ 64 = 18446744073709551616. Sana 21 tane olduđunu söyleten nedir?
drmercer

3

Bildiğim kadarıyla, aralığın dışında bir değer eklemeye çalıştığınızda sadece küçük bir fark var.

Örneklerde kullanacağım 401421228216, 101110101110110100100011101100010111000(uzunluk 39 karakter)

  • INT(20)Sisteminiz varsa, bu, bellekte en az 20 bit ayırmak anlamına gelir. Eğer daha o büyük değer ekleyeceğimiz Ama eğer 2^20, o daha az olduğu sürece, başarılı saklanacaktır INT(32) -> 2147483647(veya 2 * INT(32) -> 4294967295için UNSIGNED)

Misal:

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)
  • BIGINT(20)Sisteminiz varsa, bu, bellekte en az 20 bit ayırmak anlamına gelir. Ama değerini ekleyeceğimiz eğer bundan daha büyük 2^20olursa o kadar az olursa, o başarıyla saklanacaktır BIGINT(64) -> 9223372036854775807(veya 2 * BIGINT(64) -> 18446744073709551615için UNSIGNED)

Misal:

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

Bir nokta daha eklemek istedim, eğer 902054990011312 gibi gerçekten çok büyük bir sayı saklıyorsanız, INT(20)ve farkı kolayca görebilirsiniz BIGINT(20). İçinde saklanması tavsiye edilir BIGINT.


1

Sıfır (doldur) anahtar kelimeli int (10) için bir örnek verelim, biri değil, tablo şöyle:

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

Biraz veri ekleyelim:

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

Sonra

select * from tb_test_int_type; 

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

Görebiliyoruz

  • anahtar kelime ile zerofill10'dan küçük num 0 doldurur, ancak zerofillolmazsa

  • İkincisi zerofill, int_10_with_zf anahtar sözcüğüyle imzasız int türüne dönüşür, eksi eklerseniz hata alırsınız Out of range value for column...... Ancak int_10 öğesine eksi ekleyebilirsiniz. Ayrıca int_10'a 4294967291 eklerseniz hata alırsınızOut of range value for column.....

Sonuç:

  1. int (X) anahtar kelime olmadan zerofill, int aralığına eşit -2147483648 ~ 2147483647

  2. int (X) anahtar kelimesiyle zerofill, alan işaretsiz int aralığına eşittir 0 ~ 4294967295, num'un uzunluğu X'den küçükse 0 sola doldurur

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.