Normalisasi: Merapikan Desain Tabel agar Data Tidak Kembar
Memahami masalah data berulang (anomali), aturan 1NF, 2NF, 3NF dengan contoh nyata, lalu mempraktikkan memecah tabel dengan INSERT ... SELECT DISTINCT.
Masalah: tabel yang "semuanya jadi satu"
Perhatikan tabel mahasiswa_lama milik sebuah kampus:
| id | nama | jurusan | angkatan |
|---|---|---|---|
| 1 | Alya Putri | Informatika | 2022 |
| 3 | Cindy Maharani | Informatika | 2023 |
| 6 | Farhan Malik | Informatika | 2021 |
| 2 | Bagus Setiawan | Sistem Informasi | 2022 |
Nama jurusan ditulis berulang di setiap baris. Ini menimbulkan tiga masalah klasik yang disebut anomali:
- Anomali ubah: jurusan berganti nama menjadi "Teknik Informatika"? Kamu harus mengubah ratusan baris. Satu terlewat = data tidak konsisten.
- Anomali tambah: mau mencatat jurusan baru yang belum punya mahasiswa? Tidak bisa, karena jurusan hanya hidup di dalam baris mahasiswa.
- Anomali hapus: menghapus satu-satunya mahasiswa jurusan Manajemen ikut melenyapkan fakta bahwa jurusan itu ada.
Plus salah ketik: "Informatika", "informatika", "Informatik" dihitung sebagai tiga jurusan berbeda. Obatnya adalah normalisasi: memecah data ke tabel-tabel yang masing-masing mengurus satu hal.
Tiga bentuk normal yang wajib kamu tahu
| Bentuk | Aturan singkat | Contoh pelanggaran |
|---|---|---|
| 1NF | Setiap sel berisi satu nilai saja (tidak ada daftar dalam satu sel), dan tidak ada kolom berulang | Kolom hobi berisi "renang, catur, musik" atau kolom telp1, telp2, telp3 |
| 2NF | Memenuhi 1NF, dan setiap kolom bergantung pada seluruh kunci utama (relevan bila kuncinya gabungan) | Tabel (pesanan_id, produk_id, nama_produk): nama_produk hanya bergantung pada produk_id |
| 3NF | Memenuhi 2NF, dan kolom biasa tidak bergantung pada kolom biasa lain | Tabel pelanggan menyimpan kota dan kode_pos dan provinsi; provinsi ditentukan oleh kota |
Pegangan mudah (dari Bill Kent): "Setiap kolom harus bergantung pada kunci, seluruh kunci, dan tidak ada selain kunci, sumpah demi Tuhan." Kalau satu kolom lebih "mengenal" kolom lain daripada kunci utamanya, pisahkan ke tabel sendiri.
Resep memecah tabel dengan SQL
Kita ubah jurusan (teks berulang) menjadi tabel tersendiri, dan mahasiswa hanya menyimpan nomor-nya:
-- 1) tabel baru untuk jurusan
CREATE TABLE jurusan (
id INT AUTO_INCREMENT PRIMARY KEY,
nama VARCHAR(50) NOT NULL UNIQUE
);
-- 2) isi dari data yang sudah ada: tiap jurusan cukup sekali
INSERT INTO jurusan (nama)
SELECT DISTINCT jurusan FROM mahasiswa_lama ORDER BY jurusan;
-- 3) mahasiswa menyimpan nomor jurusan
ALTER TABLE mahasiswa_lama ADD COLUMN jurusan_id INT;
UPDATE mahasiswa_lama
SET jurusan_id = (SELECT id FROM jurusan WHERE jurusan.nama = mahasiswa_lama.jurusan);
-- 4) kolom teks lama tidak diperlukan lagi
ALTER TABLE mahasiswa_lama DROP COLUMN jurusan;
Perhatikan INSERT INTO ... SELECT ...: memasukkan hasil sebuah query langsung ke tabel lain. Ini jurus andalan untuk memindahkan dan merapikan data.
Setelah ini, untuk menampilkan nama jurusan kamu cukup JOIN (bab 24). Ganti nama jurusan? Ubah satu baris di tabel jurusan dan semua mahasiswa otomatis ikut.
Di MySQL asli, langkah akhir yang disarankan adalah menambahkan relasi: ALTER TABLE mahasiswa_lama ADD FOREIGN KEY (jurusan_id) REFERENCES jurusan(id);. Simulator latihan belum mendukung penambahan FK lewat ALTER, jadi bagian itu cukup kamu pahami.
Apakah selalu harus dinormalisasi sempurna?
Untuk sistem transaksi (toko, sekolah, bank), tujuan 3NF adalah standar yang bagus. Tapi ada kalanya sengaja melanggarnya (denormalisasi) demi kecepatan, misalnya menyimpan total pesanan langsung di tabel pesanan, atau data laporan/analitik yang dibaca jutaan kali. Syaratnya: lakukan dengan sadar, bukan karena belum tahu aturannya.