Jenis dalam MySQL: BigInt (20) vs Int (20)

221

Saya bertanya-tanya apa perbedaan antara BigInt,, MediumIntdan Int... tampaknya jelas bahwa mereka akan memungkinkan untuk jumlah yang lebih besar; Namun, saya dapat membuat Int(20)atau atau BigInt(20)itu akan membuatnya tampak tidak selalu tentang ukuran.

Beberapa wawasan akan menjadi luar biasa, hanya semacam penasaran. Saya telah menggunakan MySQL untuk sementara waktu dan mencoba menerapkan kebutuhan bisnis ketika memilih jenis, tetapi saya tidak pernah mengerti aspek ini.

Parris
sumber

Jawaban:

478

Lihat http://dev.mysql.com/doc/refman/8.0/id/numeric-types.html

  • INT adalah integer bertanda empat byte.

  • BIGINT adalah integer bertanda delapan byte.

Mereka masing-masing menerima nilai tidak lebih dan tidak lebih sedikit daripada yang dapat disimpan dalam jumlah byte masing-masing. Itu berarti 2 32 nilai dalam suatu INTdan 2 64 nilai dalam a BIGINT.

20 in INT(20)dan BIGINT(20)hampir tidak berarti apa-apa. Ini adalah petunjuk untuk lebar layar. Ini tidak ada hubungannya dengan penyimpanan, atau rentang nilai yang akan diterima kolom.

Secara praktis, ini hanya memengaruhi ZEROFILLopsi:

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

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

Ini adalah sumber kebingungan umum bagi pengguna MySQL untuk melihat INT(20)dan menganggapnya sebagai batas ukuran, sesuatu yang analog dengan CHAR(20). Ini bukan kasusnya.

Bill Karwin
sumber
4
Wow, postingan ini membersihkan kebingungan saya tentang hal ini dengan sempurna. Sepertinya pilihan aneh oleh pengembang - seperti yang saya duga itu lebar + nilai maks, atau bit / etc.
Sh4d0wsPlyr
27
`itu hanya memengaruhi opsi ZEROFILL:` sekarang rasa ingin tahu saya berakhir
Umair
6
Saya benar-benar berharap bahwa mereka telah mendesain sintaks dengan tampilan pada ZEROFILL bukan INT. Contoh: bar INT ZEROFILL(20). Itu akan jauh lebih jelas. Tapi keputusan itu sudah dibuat sejak lama, dan mengubahnya sekarang akan merusak jutaan instalasi basis data.
Bill Karwin
1
Saya setuju ini sangat membingungkan. Saya mendapat kesan bahwa angka adalah batas selama ini. Bahkan khawatir membuat beberapa angka lebih kecil ketika saya tahu data akan berada dalam kisaran tertentu.
jDub9
2
@ jDub9, ya, dan bahkan lebih membingungkan bahwa NUMERIC / DECIMAL mengambil argumen presisi yang tidak memengaruhi rentang nilai dan ukuran kolom.
Bill Karwin
40

Angka dalam tanda kurung dalam deklarasi tipe adalah lebar tampilan , yang tidak terkait dengan rentang nilai yang dapat disimpan dalam tipe data. Hanya karena Anda dapat mendeklarasikan Int(20)tidak berarti Anda dapat menyimpan nilai hingga 10 ^ 20 di dalamnya:

[...] Lebar tampilan opsional ini dapat digunakan oleh aplikasi untuk menampilkan nilai integer yang memiliki lebar kurang dari lebar yang ditentukan untuk kolom dengan melapisi bagian kiri dengan spasi. ...

Lebar tampilan tidak membatasi rentang nilai yang dapat disimpan dalam kolom, atau jumlah digit yang ditampilkan untuk nilai yang memiliki lebar melebihi yang ditentukan untuk kolom.Misalnya, kolom yang ditentukan sebagai SMALLINT (3) memiliki rentang SMALLINT biasa -32768 hingga 32767, dan nilai di luar rentang yang diizinkan oleh tiga karakter ditampilkan menggunakan lebih dari tiga karakter.

Untuk daftar nilai maksimum dan minimum yang dapat disimpan di setiap tipe data MySQL, lihat di sini .

John Feminella
sumber
18

Kutipan :

Spesifikasi "BIGINT (20)" bukan batas angka. Ini hanya berarti bahwa ketika data ditampilkan, jika menggunakan kurang dari 20 digit, data akan dibiarkan kosong. 2 ^ 64 adalah batas keras untuk jenis BIGINT, dan memiliki 20 digit itu sendiri, maka BIGINT (20) berarti semuanya kurang dari 10 ^ 20 akan dibiarkan penuh dengan spasi pada layar.

OMG Ponies
sumber
3
2 ^ 64 (tidak ditandatangani) sebenarnya memiliki 21 digit. BIGINT (20) berbahaya. Orang-orang yang menggunakannya tampaknya membenarkan penggunaannya pada gagasan bahwa 2 ^ 64 cocok dalam 20 angka desimal. Jika itu masalahnya, mengapa menentukan batas lebar sama sekali? Ternyata, itu juga tidak benar. Diperlukan 21 digit untuk menampilkan 2 ^ 64 dengan benar.
Heath Hunnicutt
@HeathHunnicutt Kecuali saya salah, 2 ^ 64 = 18446744073709551616, yang memiliki 20 digit. Apa yang membuat Anda mengatakan memiliki 21?
drmercer
3

Sejauh yang saya tahu, hanya ada satu perbedaan kecil ketika Anda mencoba memasukkan nilai yang di luar jangkauan.

Dalam contoh saya akan menggunakan 401421228216, yaitu 101110101110110100100011101100010111000(panjang 39 karakter)

  • Jika Anda memiliki INT(20)sistem ini berarti mengalokasikan dalam memori minimum 20 bit. Tetapi jika Anda akan memasukkan nilai yang lebih besar dari 2^20itu, itu akan berhasil disimpan, hanya jika kurang dari INT(32) -> 2147483647(atau 2 * INT(32) -> 4294967295untuk UNSIGNED)

Contoh:

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)
  • Jika Anda memiliki BIGINT(20)sistem ini berarti mengalokasikan dalam memori minimum 20 bit. Tetapi jika Anda akan memasukkan nilai yang lebih besar dari 2^20itu, itu akan berhasil disimpan, jika kurang dari BIGINT(64) -> 9223372036854775807(atau 2 * BIGINT(64) -> 18446744073709551615untuk UNSIGNED)

Contoh:

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

Saya ingin menambahkan satu hal lagi yaitu, jika Anda menyimpan jumlah yang sangat besar seperti 902054990011312 maka orang dapat dengan mudah melihat perbedaan INT(20)dan BIGINT(20). Dianjurkan untuk menyimpan di BIGINT.

Debasis Sabat
sumber
1

Mari kita beri contoh untuk int (10) satu dengan kata kunci zerofill, satu tidak, tabel suka itu:

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

Mari kita masukkan beberapa data:

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

Kemudian

select * from tb_test_int_type; 

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

Kita bisa melihatnya

  • dengan kata kunci zerofill, num kurang dari 10 akan mengisi 0, tetapi tanpa zerofillitu tidak akan

  • Kedua dengan kata kunci zerofill, int_10_with_zf menjadi tipe int yang tidak ditandatangani, jika Anda memasukkan minus, Anda akan mendapatkan kesalahan Out of range value for column...... Tapi Anda bisa memasukkan minus ke int_10. Juga jika Anda memasukkan 4294967291 ke int_10 Anda akan mendapatkan kesalahanOut of range value for column.....

Kesimpulan:

  1. int (X) tanpa kata kunci zerofill, sama dengan rentang int -2147483648 ~ 2147483647

  2. int (X) dengan kata kunci zerofill, bidangnya sama dengan rentang int tak bertanda 0 ~ 4294967295, jika panjang num kurang dari X akan mengisi 0 ke kiri

Jayhello
sumber