Angka bulat adalah data yang paling sering kita simpan: jumlah stok, nomor telepon, harga dalam rupiah utuh, hingga penghitung kunjungan. MySQL menyediakan lima ukuran tipe integer yang berbeda supaya kita tidak memakai gudang raksasa untuk menyimpan satu kotak korek api. Pada Chapter ini kita akan memetakan kelima ukuran tersebut, mencoba menyimpan nilai yang melebihi batasnya, membongkar mitos INT(11) yang masih beredar di banyak tutorial lama, dan mengenal atribut UNSIGNED untuk kolom yang tidak pernah bernilai negatif.
Lima Ukuran INTEGER #
Kelima tipe integer dibedakan oleh jumlah byte penyimpanan — dan jumlah byte tersebut menentukan rentang nilai yang bisa ditampung. Semakin besar byte, semakin luas rentangnya, dan semakin banyak ruang yang dipakai per baris. Tabel berikut merangkum rentang lengkap versi MySQL 8.4:
| Tipe | Byte | Rentang SIGNED | Rentang UNSIGNED |
|---|---|---|---|
TINYINT | 1 | -128 s.d. 127 | 0 s.d. 255 |
SMALLINT | 2 | -32.768 s.d. 32.767 | 0 s.d. 65.535 |
MEDIUMINT | 3 | -8.388.608 s.d. 8.388.607 | 0 s.d. 16.777.215 |
INT | 4 | -2.147.483.648 s.d. 2.147.483.647 | 0 s.d. 4.294.967.295 |
BIGINT | 8 | sekitar -9,22 × 10¹⁸ s.d. 9,22 × 10¹⁸ | 0 s.d. 18.446.744.073.709.551.615 |
Aturan praktisnya sederhana: pilih tipe terkecil yang masih menampung nilai terbesar yang masuk akal untuk kolom tersebut. Kolom stok_rak TINYINT cukup untuk rak yang maksimal memuat ratusan barang, sedangkan kolom harga properti atau jumlah populasi dunia sudah layak memakai BIGINT. Kesalahan klasik pemula adalah memakai INT untuk semua kolom angka — sah-sah saja, tetapi tabel berjuta-juta baris akan membayar mahal ruang dan memori ekstra yang sebenarnya tidak diperlukan.
Membuat Tabel Latihan #
Kita mulai dengan menyiapkan database latihan khusus section ini, lalu membuat tabel barang yang memakai lima ukuran integer sekaligus:
DROP DATABASE IF EXISTS belajar_tipe;
CREATE DATABASE belajar_tipe;
USE belajar_tipe;Output yang Dihasilkan:
Query OK, 0 rows affected, 1 warning (0.00 sec)
Query OK, 1 row affected (0.00 sec)
Database changedBaris pertama berasal dari DROP DATABASE IF EXISTS yang tidak menemukan database lama — perintah diabaikan dengan aman dan hanya mencatat satu warning informatif. CREATE DATABASE kemudian membuat belajar_tipe baru, dan USE mengaktifkannya untuk sesi kita (ditandai respons Database changed). Pola tiga baris ini akan kita ulang di setiap chapter section Tipe Data supaya latihan selalu dimulai dari keadaan bersih.
CREATE TABLE barang (
id SMALLINT UNSIGNED,
nama VARCHAR(50),
stok_rak TINYINT UNSIGNED,
stok_gudang MEDIUMINT UNSIGNED,
harga_satuan INT UNSIGNED,
total_nilai BIGINT UNSIGNED
);Output yang Dihasilkan:
Query OK, 0 rows affected (0.00 sec)Mari kita bedah definisi tabel di atas baris per baris:
- Baris 1 (
CREATE TABLE barang (): Membuat tabel baru bernamabarang; tanda kurung buka mengawali daftar enam definisi kolom. - Baris 2 (
id SMALLINT UNSIGNED): Kolom identitas barang memakaiSMALLINT UNSIGNED— maksimal 65.535 nomor barang, cukup untuk toko latihan kita. - Baris 3 (
nama VARCHAR(50)): Nama barang bertipe string variabel; tipe string akan dibedah tuntas pada chapter STRING. - Baris 4 (
stok_rak TINYINT UNSIGNED): Stok di rak memakai tipe terkecil — maksimal 255 unit per barang. - Baris 5 (
stok_gudang MEDIUMINT UNSIGNED): Stok gudang bisa jutaan unit sehingga naik satu kelas keMEDIUMINT. - Baris 6 (
harga_satuan INT UNSIGNED): Harga satuan dalam rupiah utuh memakaiINT UNSIGNEDhingga 4,29 miliar. - Baris 7 (
total_nilai BIGINT UNSIGNED): Total nilai persediaan (harga × jumlah) bisa melampaui 4,29 miliar, maka dipakaiBIGINT.
Sekarang kita isi tiga baris data dan membacanya kembali:
INSERT INTO barang (id, nama, stok_rak, stok_gudang, harga_satuan, total_nilai)
VALUES
(1, 'Pensil Kayu', 12, 500, 2500, 1280000),
(2, 'Buku Tulis 38', 8, 1200, 4500, 5400000),
(3, 'Penghapus', 25, 3000, 1500, 4500000);
SELECT id, nama, stok_rak, stok_gudang, harga_satuan, total_nilai
FROM barang
ORDER BY id;Output yang Dihasilkan:
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
+------+---------------+----------+-------------+--------------+-------------+
| id | nama | stok_rak | stok_gudang | harga_satuan | total_nilai |
+------+---------------+----------+-------------+--------------+-------------+
| 1 | Pensil Kayu | 12 | 500 | 2500 | 1280000 |
| 2 | Buku Tulis 38 | 8 | 1200 | 4500 | 5400000 |
| 3 | Penghapus | 25 | 3000 | 1500 | 4500000 |
+------+---------------+----------+-------------+--------------+-------------+
3 rows in set (0.00 sec)Tiga baris tersimpan dan ditampilkan kembali persis seperti nilainya — angka bulat tidak mengalami pembulatan maupun konversi bentuk. Klausa ORDER BY id kita pakai supaya urutan tampilan selalu sama meskipun MySQL kelak menyimpan barisnya dengan urutan fisik yang berbeda.
Batas Rentang dan Strict Mode #
Apa yang terjadi jika kita memaksa menyimpan nilai di luar rentang? Mari kita coba memasukkan stok rak sebesar 300 ke kolom TINYINT UNSIGNED yang batas maksimalnya 255:
-- @error
INSERT INTO barang (id, nama, stok_rak) VALUES (4, 'Rautan', 300);Output yang Dihasilkan:
Query OK, 0 rows affected (0.00 sec)
ERROR 1264 (22003): Out of range value for column 'stok_rak' at row 1
ByeServer menolak statement tersebut dengan galat Out of range value for column 'stok_rak' at row 1 dan seluruh baris tidak tersimpan — angka 300 tidak dipangkas menjadi 255 secara diam-diam. Perlakuan ini berasal dari strict mode (STRICT_TRANS_TABLES) yang aktif secara bawaan di MySQL 8.4: nilai yang tidak muat dianggap kesalahan data, bukan sesuatu yang boleh ditebak server. Pada mode longgar yang dipakai versi-versi lama, MySQL justru memangkas nilai ke batas terdekat dan hanya mengeluarkan peringatan — perilaku yang sering menyembunyikan bug aplikasi. Karena strict mode adalah standar modern, kita menulis kode dengan asumsi out-of-range selalu gagal keras.
INT(11) dan Display Width yang Usang #
Banyak tutorial lama menulis INT(11) atau TINYINT(4) seolah angka di dalam kurung membatasi jumlah digit. Itu adalah display width — lebar tampilan untuk alat klien lawas — dan sama sekali tidak membatasi rentang nilai: kolom INT(11) tetap bisa menyimpan 2 miliar. MySQL sudah menandai fitur ini deprecated sejak versi 8.0.17, dan di MySQL 8.4 lebar tampilan diabaikan serta dihilangkan dari metadata tabel. Kita bisa membuktikannya langsung:
CREATE TABLE lebar_usang (nomor INT(11), kode TINYINT(4));
SHOW WARNINGS;
DESC lebar_usang;Output yang Dihasilkan:
Query OK, 0 rows affected, 2 warnings (0.00 sec)
+---------+------+------------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+------------------------------------------------------------------------------+
| Warning | 1681 | Integer display width is deprecated and will be removed in a future release. |
| Warning | 1681 | Integer display width is deprecated and will be removed in a future release. |
+---------+------+------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| nomor | int | YES | | NULL | |
| kode | tinyint | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)Kita mendeklarasikan INT(11) dan TINYINT(4), dan hasilnya membuktikan dua hal sekaligus: kolom Type pada DESC hanya menampilkan int dan tinyint, serta SHOW WARNINGS mencatat peringatan bahwa lebar tampilan integer sudah usang. MySQL 8.4 membuang angka lebar tampilan begitu tabel dibuat dan menandai penulisannya sebagai praktik terlarang di masa depan. Kesimpulan praktisnya: tulis INT, bukan INT(11); angka di kurung itu tidak punya efek apa pun pada data yang disimpan. Satu-satunya pengecualian sejarah adalah TINYINT(1) yang lazim dipakai sebagai konvensi kolom boolean — hal itu kita bahas pada chapter BOOLEAN dan Nilai Logika.
INT UNSIGNED untuk Nilai Non-Negatif #
Atribut UNSIGNED membuang sisi negatif dari rentang dan melipatgandakan batas atasnya. Tabel barang kita sejak awal memakai UNSIGNED pada semua kolom angka karena stok, harga, dan penghitung tidak pernah bernilai negatif. Untuk melihat seberapa jauh batasnya naik, kita simpan nilai maksimal INT UNSIGNED pada tabel penghitung kunjungan:
CREATE TABLE pengunjung (hari DATE, jumlah INT UNSIGNED);
INSERT INTO pengunjung VALUES ('2026-01-15', 4294967295);
SELECT hari, jumlah, jumlah + 1 AS batas_terlampaui FROM pengunjung;Output yang Dihasilkan:
Query OK, 0 rows affected (0.00 sec)
Query OK, 1 row affected (0.00 sec)
+------------+------------+------------------+
| hari | jumlah | batas_terlampaui |
+------------+------------+------------------+
| 2026-01-15 | 4294967295 | 4294967296 |
+------------+------------+------------------+
1 row in set (0.00 sec)Baris dengan nilai 4294967295 tersimpan tanpa masalah — angka tersebut justru menyebabkan galat Out of range bila kolomnya memakai INT biasa. Perhatikan juga kolom batas_terlampaui: ekspresi jumlah + 1 melebihi 4,29 miliar sehingga hasilnya meluas ke tipe BIGINT dan tetap dihitung. Sebaliknya, nilai negatif kini terlarang:
-- @error
INSERT INTO pengunjung VALUES ('2026-01-16', -1);Output yang Dihasilkan:
Query OK, 0 rows affected (0.00 sec)
ERROR 1264 (22003): Out of range value for column 'jumlah' at row 1
ByeKolom INT UNSIGNED menolak -1 dengan galat out-of-range yang sama seperti kasus TINYINT kita sebelumnya. Sisi negatif rentang telah “dipindahtangankan” untuk memperluas sisi positif — pertukaran yang menguntungkan selama datanya memang tidak mungkin negatif. Konsekuensi lain dari pertukaran ini — termasuk jebakan pengurangan pada kolom UNSIGNED — akan kita bedah tuntas pada chapter SIGNED dan UNSIGNED.
Terakhir, kita bereskan database latihan sebelum pindah topik:
DROP DATABASE belajar_tipe;Output yang Dihasilkan:
Query OK, 3 rows affected (0.00 sec)Referensi #
- Integer Types (Exact Value) — MySQL 8.4 Reference Manual
- Numeric Data Types — MySQL 8.4 Reference Manual
- Data Types — MySQL 8.4 Reference Manual
Integer menuntaskan angka bulat, tetapi harga 4.500,50 rupiah masih menyisakan pecahan yang menuntut ketelitian. Chapter berikutnya memperkenalkan DECIMAL untuk angka pecahan yang persis dan membedah mengapa FLOAT/DOUBLE bisa membuat perhitungan uang melenceng.