Aplikasi nyata sering menambah baris lewat form yang tidak melengkapi semua kolom: barang baru tercatat sebelum stoknya dihitung, dan anggota baru terdaftar tanpa status yang dipilih. Tanpa nilai bawaan, tiap INSERT seperti itu harus menyebut semua kolom secara eksplisit — atau gagal dengan galat 1364 seperti yang kita lihat pada chapter NOT NULL. Klausa DEFAULT mengisi kekosongan itu: saat INSERT tidak mengirim nilai untuk sebuah kolom, server memakai nilai bawaan yang sudah kita tetapkan di definisi tabel. Pada chapter ini kita akan memasang default literal seperti 'aktif' dan 0, memanggilnya lewat kata kunci DEFAULT, lalu mengenal default khusus CURRENT_TIMESTAMP yang mengisi waktu pencatatan secara otomatis.

Menetapkan DEFAULT Literal #

Kita siapkan tabel barang untuk gudang toko alat tulis. Barang baru di sistem ini selalu berstatus aktif, stoknya dihitung dari nol, dan diskonnya belum ada:

sql
CREATE DATABASE belajar_default;
USE belajar_default;

Output yang Dihasilkan:

text
Query OK, 1 row affected (0.00 sec)

Database changed
sql
CREATE TABLE barang (
  id INT PRIMARY KEY,
  nama VARCHAR(100) NOT NULL,
  status VARCHAR(20) NOT NULL DEFAULT 'aktif',
  stok INT NOT NULL DEFAULT 0,
  diskon DECIMAL(5,2) DEFAULT 0.00,
  catatan VARCHAR(255) DEFAULT NULL
);

Output yang Dihasilkan:

text
Query OK, 0 rows affected (0.00 sec)

Mari kita bedah baris-baris yang memuat nilai bawaan:

  1. Baris 4 (status VARCHAR(20) NOT NULL DEFAULT 'aktif'): Kolom wajib terisi dengan nilai bawaan 'aktif'. Kombinasi NOT NULL DEFAULT adalah pola umum untuk kolom status — selalu terisi, tetapi pemanggil INSERT boleh tidak menyebutnya.
  2. Baris 5 (stok INT NOT NULL DEFAULT 0): Default angka bulat 0 — barang baru masuk sebelum dihitung fisiknya, jadi stok dimulai dari nol.
  3. Baris 6 (diskon DECIMAL(5,2) DEFAULT 0.00): Default boleh dipasang pada kolom opsional juga; tanpa NOT NULL, kolom ini tetap bisa dikirim NULL secara eksplisit.
  4. Baris 7 (catatan VARCHAR(255) DEFAULT NULL): Penulisan eksplisit bahwa nilai bawaannya NULL. Ini juga perilaku bawaan semua kolom opsional, jadi klausa ini murni pernyataan ulang untuk kejelasan.

Struktur nilai bawaan bisa kita periksa lewat DESC — kolom Default menampilkan nilai bawaan tiap kolom:

sql
DESC barang;

Output yang Dihasilkan:

text
+---------+--------------+------+-----+---------+-------+
| Field   | Type         | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| id      | int          | NO   | PRI | NULL    |       |
| nama    | varchar(100) | NO   |     | NULL    |       |
| status  | varchar(20)  | NO   |     | aktif   |       |
| stok    | int          | NO   |     | 0       |       |
| diskon  | decimal(5,2) | YES  |     | 0.00    |       |
| catatan | varchar(255) | YES  |     | NULL    |       |
+---------+--------------+------+-----+---------+-------+
6 rows in set (0.00 sec)

Perhatikan kolom id dan nama: nilai Default-nya NULL bukan berarti bawaannya string kosong, melainkan bahwa tidak ada nilai bawaan — persis alasan galat 1364 muncul saat kolom wajib semacam itu tidak dikirim.

INSERT Tanpa Nilai Terisi Otomatis #

Sekarang kita tambahkan barang baru hanya dengan data intinya — id dan nama:

sql
INSERT INTO barang (id, nama) VALUES (1, 'Buku Tulis 58');

SELECT id, nama, status, stok, diskon, catatan FROM barang ORDER BY id;

Output yang Dihasilkan:

text
Query OK, 1 row affected (0.00 sec)

+----+---------------+--------+------+--------+---------+
| id | nama          | status | stok | diskon | catatan |
+----+---------------+--------+------+--------+---------+
|  1 | Buku Tulis 58 | aktif  |    0 |   0.00 | NULL    |
+----+---------------+--------+------+--------+---------+
1 row in set (0.00 sec)

Baris tersimpan lengkap: status terisi 'aktif', stok terisi 0, diskon terisi 0.00, dan catatan terisi NULL — semuanya diambil dari nilai bawaan karena INSERT tidak mengirimkannya. Inilah pasangan sempurna untuk kolom NOT NULL dari chapter sebelumnya: wajib terisi di database, tetap mudah diisi dari aplikasi.

Kata Kunci DEFAULT di VALUES #

Nilai bawaan juga bisa dipanggil secara eksplisit dari daftar VALUES lewat kata kunci DEFAULT. Statement berikut memakainya untuk dua kolom sekaligus, lalu membandingkannya dengan baris yang mengirim nilai manual:

sql
INSERT INTO barang (id, nama, status, stok) VALUES
  (2, 'Pensil Kayu 2B', DEFAULT, DEFAULT),
  (3, 'Spidol Whiteboard', 'nonaktif', 24);

SELECT id, nama, status, stok FROM barang ORDER BY id;

Output yang Dihasilkan:

text
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

+----+-------------------+----------+------+
| id | nama              | status   | stok |
+----+-------------------+----------+------+
|  1 | Buku Tulis 58     | aktif    |    0 |
|  2 | Pensil Kayu 2B    | aktif    |    0 |
|  3 | Spidol Whiteboard | nonaktif |   24 |
+----+-------------------+----------+------+
3 rows in set (0.00 sec)

Baris kedua memperoleh 'aktif' dan 0 dari nilai bawaan, sedangkan baris ketiga mengirim nilainya sendiri: 'nonaktif' dan 24. Kata kunci DEFAULT berguna saat form aplikasi mengirim nilai kosong yang ingin kita gugurkan ke nilai bawaan, alih-alih menyimpan string kosong.

DEFAULT CURRENT_TIMESTAMP #

Kebutuhan umum berikutnya adalah mencatat waktu pembuatan baris. MySQL menyediakan CURRENT_TIMESTAMP sebagai nilai bawaan khusus untuk kolom bertipe TIMESTAMP — server mengisinya dengan waktu saat statement INSERT dijalankan:

sql
-- @check
CREATE TABLE pengunjung (
  id INT PRIMARY KEY,
  nama VARCHAR(100) NOT NULL,
  mendaftar TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

INSERT INTO pengunjung (id, nama) VALUES
  (1, 'Budi'),
  (2, 'Siti');

SELECT id, nama, mendaftar FROM pengunjung ORDER BY id;

Output yang Dihasilkan:

text
Query OK, 0 rows affected (0.01 sec)

Query OK, 2 rows affected (0.01 sec)

+----+------+---------------------+
| id | nama | mendaftar           |
+----+------+---------------------+
|  1 | Budi | 2026-02-14 09:41:07 |
|  2 | Siti | 2026-02-14 09:41:07 |
+----+------+---------------------+
2 rows in set (0.00 sec)

Kedua baris mendapat nilai mendaftar tanpa pernah kita kirim — tugas kolom TIMESTAMP DEFAULT CURRENT_TIMESTAMP memang demikian. Nilai waktu pada contoh di atas tentu berbeda dengan hasil di komputer kita masing-masing, karena CURRENT_TIMESTAMP mengambil jam server pada saat INSERT dijalankan; itulah alasan blok ini tidak dibandingkan secara otomatis oleh pengujian. Nilainya juga tidak bisa diandalkan sebagai data latihan yang tetap — untuk tanggal contoh yang pasti, kita selalu menulis literal seperti '2026-01-15'.

DEFAULT pada Kolom NOT NULL dan NULL Eksplisit #

Dua pertanyaan terakhir kerap muncul: bolehkah kolom NOT NULL punya default, dan apa bedanya DEFAULT NULL? Keduanya sudah terjawab di tabel kita — status membuktikan kolom NOT NULL boleh punya default ('aktif'), dan catatan membuktikan default boleh bernilai NULL pada kolom opsional. Ringkasnya:

KombinasiPerilaku saat tidak dikirim
NOT NULL DEFAULT xterisi x — pola paling aman untuk kolom wajib
DEFAULT x (opsional)terisi x; pengirim masih boleh mengirim NULL
DEFAULT NULLterisi NULL (sama seperti opsional tanpa default)
NOT NULL tanpa defaultditolak dengan galat 1364

Satu batasan penting: nilai default harus berupa konstanta — angka, string, atau tanggal literal — kecuali pengecualian fungsi waktu seperti CURRENT_TIMESTAMP di atas. Ekspresi hitung seperti DEFAULT harga * 2 tidak valid pada definisi kolom biasa.

Referensi #

Barang baru kini tercatat lengkap walau form hanya mengirim nama. Nilai bawaan status dan stok bekerja karena nilainya pasti dan tetap — tapi bagaimana dengan identitas id yang idealnya terisi angka berurutan tanpa kita menghitungnya? Tugas itu diambil alih oleh AUTO_INCREMENT pada chapter berikutnya. Sebelum itu, kita bereskan database latihan:

sql
DROP DATABASE IF EXISTS belajar_default;

Output yang Dihasilkan:

text
Query OK, 2 rows affected (0.00 sec)

Dua tabel — barang dan pengunjung — ikut terbuang.