Contoh Normalisasi Database 1NF, 2NF, 3NF: Studi Kasus Kwitansi Rumah Sakit
Diperbarui Oktober 2026. Catatan kuliah basis data dari April 2013 ini saya tulis ulang dengan contoh tabel yang lengkap, supaya setiap tahap normalisasi bisa diikuti tanpa harus menebak isi gambar.

Foto: rawpixel (CC0)
Normalisasi adalah teknik merancang tabel basis data dengan cara memecah tabel yang datanya berulang (redundan) menjadi beberapa tabel yang lebih kecil dan saling berelasi. Tujuannya supaya data tidak dobel, gampang diubah, dan tidak menimbulkan anomali saat ditambah, diubah, atau dihapus.
Normalisasi biasanya dipakai bersama ERD (Entity Relationship Diagram). ERD membantu melihat gambaran besar, sedangkan normalisasi memeriksa apakah tiap tabel sudah "sehat".
Tahapan normalisasi
- Unnormalized (UNF) — data mentah apa adanya dari dokumen, masih ada kelompok data yang berulang.
- Bentuk Normal Pertama (1NF) — setiap kolom berisi satu nilai (atomik), tidak ada kelompok berulang.
- Bentuk Normal Kedua (2NF) — sudah 1NF dan setiap kolom bukan kunci bergantung pada seluruh kunci primer (tidak ada ketergantungan parsial).
- Bentuk Normal Ketiga (3NF) — sudah 2NF dan tidak ada kolom bukan kunci yang bergantung pada kolom bukan kunci lain (tidak ada ketergantungan transitif).
Untuk kebanyakan kasus kuliah dan aplikasi sederhana, sampai 3NF sudah cukup.
Studi kasus: kwitansi pembayaran rumah sakit
Misalkan kita punya kwitansi seperti ini (data fiktif):
| No. Kwitansi | K-0471 | Tanggal | 06-10-2012 |
|---|---|---|---|
| No. RM | RM-1044 | Nama Pasien | Ahmad Fauzi |
| Klinik | Umum | Dokter | D019 – dr. Dian |
| Kode | Tindakan | Jumlah | Tarif | Subtotal |
|---|---|---|---|---|
| T01 | Pemeriksaan klinik umum | 1 | 25.000 | 25.000 |
| T07 | Farmasi rawat jalan | 1 | 15.900 | 15.900 |
| T09 | Administrasi | 1 | 3.850 | 3.850 |
| Total | 44.750 | |||
1. Unnormalized (UNF)
Semua isi kwitansi dimasukkan ke satu tabel. Satu kwitansi punya banyak tindakan, sehingga kolom tindakan "menumpuk" dalam satu baris:
| NoKwitansi | Tanggal | NoRM | NamaPasien | Klinik | KodeDokter | NamaDokter | Tindakan (Kode, Nama, Jml, Tarif) |
|---|---|---|---|---|---|---|---|
| K-0471 | 06-10-2012 | RM-1044 | Ahmad Fauzi | Umum | D019 | dr. Dian | T01 Pemeriksaan 1×25.000; T07 Farmasi 1×15.900; T09 Administrasi 1×3.850 |
Masalahnya: kolom tindakan berisi banyak nilai sekaligus, jadi sulit dicari atau dihitung.
2. Bentuk Normal Pertama (1NF)
Pecah kelompok berulang menjadi baris tersendiri, sehingga setiap sel hanya berisi satu nilai:
| NoKwitansi | Tanggal | NoRM | NamaPasien | Klinik | KodeDokter | NamaDokter | KodeTindakan | NamaTindakan | Tarif | Jumlah |
|---|---|---|---|---|---|---|---|---|---|---|
| K-0471 | 06-10-2012 | RM-1044 | Ahmad Fauzi | Umum | D019 | dr. Dian | T01 | Pemeriksaan klinik umum | 25.000 | 1 |
| K-0471 | 06-10-2012 | RM-1044 | Ahmad Fauzi | Umum | D019 | dr. Dian | T07 | Farmasi rawat jalan | 15.900 | 1 |
| K-0471 | 06-10-2012 | RM-1044 | Ahmad Fauzi | Umum | D019 | dr. Dian | T09 | Administrasi | 3.850 | 1 |
Kunci primernya sekarang gabungan (NoKwitansi, KodeTindakan). Tabel sudah 1NF, tetapi data pasien dan dokter ditulis berulang-ulang.
3. Bentuk Normal Kedua (2NF)
Cari kolom yang hanya bergantung pada sebagian kunci:
- Tanggal, NoRM, NamaPasien, Klinik, KodeDokter, NamaDokter cukup ditentukan oleh NoKwitansi saja.
- NamaTindakan dan Tarif cukup ditentukan oleh KodeTindakan saja.
- Jumlah baru bergantung pada keduanya (NoKwitansi + KodeTindakan).
Maka tabel dipecah menjadi tiga:
- Kwitansi (NoKwitansi, Tanggal, NoRM, NamaPasien, Klinik, KodeDokter, NamaDokter)
- Tindakan (KodeTindakan, NamaTindakan, Tarif)
- DetailKwitansi (NoKwitansi, KodeTindakan, Jumlah)
4. Bentuk Normal Ketiga (3NF)
Di tabel Kwitansi masih ada ketergantungan transitif: NamaPasien ditentukan oleh NoRM, dan NamaDokter ditentukan oleh KodeDokter, bukan langsung oleh NoKwitansi. Jika nama dokter berubah, kita harus mengubah banyak baris kwitansi. Pisahkan:
- Pasien (NoRM, NamaPasien)
- Dokter (KodeDokter, NamaDokter, Klinik)
- Kwitansi (NoKwitansi, Tanggal, NoRM*, KodeDokter*)
- Tindakan (KodeTindakan, NamaTindakan, Tarif)
- DetailKwitansi (NoKwitansi*, KodeTindakan*, Jumlah)
Garis bawah = kunci primer, tanda * = kunci tamu (foreign key). Total pembayaran tidak perlu disimpan karena bisa dihitung dari Jumlah × Tarif.
Catatan praktis: di sistem sungguhan, tarif saat transaksi biasanya juga disimpan di DetailKwitansi (misalnya kolom TarifSaatItu). Alasannya, tarif di tabel Tindakan bisa naik, sedangkan kwitansi lama harus tetap menampilkan harga lama.
Menguji hasil normalisasi
Cara paling mudah memastikan rancangan sudah benar adalah langsung mencobanya di DBMS (MySQL, PostgreSQL, atau SQLite). Buat tabel-tabelnya, isi data contoh, lalu coba susun kembali kwitansi dengan query JOIN:
SELECT k.NoKwitansi, k.Tanggal, p.NamaPasien, d.NamaDokter,
t.NamaTindakan, dk.Jumlah, t.Tarif, dk.Jumlah * t.Tarif AS Subtotal
FROM Kwitansi k
JOIN Pasien p ON p.NoRM = k.NoRM
JOIN Dokter d ON d.KodeDokter = k.KodeDokter
JOIN DetailKwitansi dk ON dk.NoKwitansi = k.NoKwitansi
JOIN Tindakan t ON t.KodeTindakan = dk.KodeTindakan
WHERE k.NoKwitansi = 'K-0471';
Kalau kwitansi bisa disusun ulang dengan lengkap tanpa ada data yang hilang atau dobel, berarti pemecahan tabelnya berhasil.
Ringkasan
- 1NF: hilangkan kelompok berulang, satu sel satu nilai.
- 2NF: hilangkan ketergantungan pada sebagian kunci gabungan.
- 3NF: hilangkan ketergantungan antar kolom bukan kunci.
Lihat juga catatan saya tentang ER Diagram database perpustakaan. Semoga bermanfaat, dan kalau ada yang keliru silakan koreksi di komentar.