Database atau basis data adalah kumpulan data yang terorganisir dan tersimpan secara sistematis dalam komputer. Database relasional menggunakan tabel-tabel yang saling berhubungan untuk menyimpan dan mengelola data.
Tanpa normalisasi yang baik, database dapat mengalami masalah seperti:
Normalisasi adalah proses mengorganisir data dalam database untuk mengurangi redundansi dan meningkatkan integritas data. Normalisasi dilakukan dengan memecah tabel besar menjadi tabel-tabel yang lebih kecil dan mendefinisikan relasi di antara mereka.
Suatu tabel dikatakan dalam 1NF jika:
Contoh Pelanggaran 1NF:
| ID_Siswa | Nama | Hobi |
|---|---|---|
| 1 | Budi | Sepak bola, Musik |
| 2 | Ani | Membaca, Menulis, Renang |
Setelah 1NF:
| ID_Siswa | Nama | Hobi |
|---|---|---|
| 1 | Budi | Sepak bola |
| 1 | Budi | Musik |
| 2 | Ani | Membaca |
| 2 | Ani | Menulis |
| 2 | Ani | Renang |
Suatu tabel dikatakan dalam 2NF jika:
Contoh Pelanggaran 2NF:
| ID_Siswa | ID_Mata_Kuliah | Nama_Siswa | Nilai | Nama_Mata_Kuliah |
|---|---|---|---|---|
| 1 | 101 | Budi | A | Database |
| 1 | 102 | Budi | B | Pemrograman Web |
| 2 | 101 | Ani | A | Database |
Masalah: Nama_Siswa hanya bergantung pada ID_Siswa, dan Nama_Mata_Kuliah hanya bergantung pada ID_Mata_Kuliah.
Setelah 2NF:
Tabel Siswa: | ID_Siswa | Nama_Siswa | |———-|————| | 1 | Budi | | 2 | Ani |
Tabel Mata_Kuliah: | ID_Mata_Kuliah | Nama_Mata_Kuliah | |—————-|——————| | 101 | Database | | 102 | Pemrograman Web |
Tabel Nilai: | ID_Siswa | ID_Mata_Kuliah | Nilai | |———-|—————-|——-| | 1 | 101 | A | | 1 | 102 | B | | 2 | 101 | A |
Suatu tabel dikatakan dalam 3NF jika:
Contoh Pelanggaran 3NF:
| ID_Siswa | Nama | Kota | Kode_Pos | Provinsi |
|---|---|---|---|---|
| 1 | Budi | Jakarta | 12345 | DKI |
| 2 | Ani | Bandung | 40111 | Jawa Barat |
Masalah: Provinsi bergantung pada Kota, bukan pada ID_Siswa.
Setelah 3NF:
Tabel Siswa: | ID_Siswa | Nama | Kode_Pos | |———-|———–|———-| | 1 | Budi | 12345 | | 2 | Ani | 40111 |
Tabel Kota: | Kode_Pos | Kota | Provinsi | |———-|————-|————| | 12345 | Jakarta | DKI | | 40111 | Bandung | Jawa Barat |
Suatu tabel dikatakan dalam BCNF jika:
BCNF adalah versi yang lebih ketat dari 3NF dan menangani anomali khusus yang jarang terjadi.
Mari kita lihat contoh lengkap proses normalisasi dari tabel yang tidak ternormalisasi hingga 3NF.
Tabel Pemesanan: | ID_Pesanan | Tanggal | Nama_Customer | Telp_Customer | Alamat_Customer | Produk | Harga_Produk | Jumlah | Total | |————|————|—————|—————|—————–|———————-|——————-|————-|———| | 1 | 2026-03-01 | John Doe | 081234567890 | Jl. Merdeka 1 | Mouse, Keyboard | 50000, 150000 | 2, 1 | 250000 | | 2 | 2026-03-02 | Jane Smith | 081298765432 | Jl. Sudirman 5 | Monitor | 1000000 | 1 | 1000000 |
Pisahkan nilai yang tidak atomik:
| ID_Pesanan | Tanggal | Nama_Customer | Telp_Customer | Alamat_Customer | Produk | Harga_Produk | Jumlah | Subtotal |
|---|---|---|---|---|---|---|---|---|
| 1 | 2026-03-01 | John Doe | 081234567890 | Jl. Merdeka 1 | Mouse | 50000 | 2 | 100000 |
| 1 | 2026-03-01 | John Doe | 081234567890 | Jl. Merdeka 1 | Keyboard | 150000 | 1 | 150000 |
| 2 | 2026-03-02 | Jane Smith | 081298765432 | Jl. Sudirman 5 | Monitor | 1000000 | 1 | 1000000 |
Pisahkan data yang bergantung partial:
Tabel Pesanan: | ID_Pesanan | Tanggal | ID_Customer | |————|————|————-| | 1 | 2026-03-01 | 1 | | 2 | 2026-03-02 | 2 |
Tabel Customer: | ID_Customer | Nama_Customer | Telp_Customer | Alamat_Customer | |————-|—————|—————|—————–| | 1 | John Doe | 081234567890 | Jl. Merdeka 1 | | 2 | Jane Smith | 081298765432 | Jl. Sudirman 5 |
Tabel Produk: | ID_Produk | Nama_Produk | Harga | |———–|————-|————-| | 1 | Mouse | 50000 | | 2 | Keyboard | 150000 | | 3 | Monitor | 1000000 |
Tabel Detail_Pesanan: | ID_Pesanan | ID_Produk | Jumlah | Subtotal | |————|———–|——–|———-| | 1 | 1 | 2 | 100000 | | 1 | 2 | 1 | 150000 | | 2 | 3 | 1 | 1000000 |
Dalam kasus ini, tabel sudah memenuhi 3NF karena tidak ada transitive dependency. Subtotal sebenarnya dapat dihitung (Jumlah × Harga), jadi bisa dihapus untuk menghindari redundansi:
Tabel Detail_Pesanan (Final): | ID_Pesanan | ID_Produk | Jumlah | |————|———–|——–| | 1 | 1 | 2 | | 1 | 2 | 1 | | 2 | 3 | 1 |
Relasi adalah hubungan antara tabel dalam database. Ada tiga jenis relasi utama:
Satu record dalam tabel A berhubungan dengan tepat satu record dalam tabel B.
Contoh: Satu siswa memiliki satu KTP.
Tabel Siswa: | ID_Siswa | Nama | Email | |———-|———–|——————-| | 1 | Budi | budi@email.com | | 2 | Ani | ani@email.com |
Tabel KTP: | ID_KTP | ID_Siswa | Nomor_KTP | Alamat_KTP | |——–|———-|—————-|—————| | 1 | 1 | 3201010101010001| Jl. Merdeka 1| | 2 | 2 | 3202020202020002| Jl. Sudirman 5|
Diagram:
Siswa (1) ←→ (1) KTP
Satu record dalam tabel A dapat berhubungan dengan banyak record dalam tabel B, tetapi satu record dalam tabel B hanya berhubungan dengan satu record dalam tabel A.
Contoh: Satu dosen dapat mengajar banyak mata kuliah, tetapi satu mata kuliah hanya diajar oleh satu dosen.
Tabel Dosen: | ID_Dosen | Nama_Dosen | Email | |———-|—————-|——————–| | 1 | Dr. Ahmad | ahmad@univ.ac.id | | 2 | Dr. Siti | siti@univ.ac.id |
Tabel Mata_Kuliah: | ID_Mata_Kuliah | Nama_Mata_Kuliah | ID_Dosen | SKS | |—————-|——————|———-|—–| | 101 | Database | 1 | 3 | | 102 | Pemrograman Web | 1 | 3 | | 103 | Jaringan | 2 | 3 |
Diagram:
Dosen (1) ←→ (N) Mata_Kuliah
Banyak record dalam tabel A dapat berhubungan dengan banyak record dalam tabel B, dan sebaliknya.
Contoh: Banyak siswa dapat mengambil banyak mata kuliah, dan satu mata kuliah dapat diambil oleh banyak siswa.
Implementasi: Relasi M:N membutuhkan junction table (tabel penghubung).
Tabel Siswa: | ID_Siswa | Nama | NIM | |———-|———–|———–| | 1 | Budi | 20230001 | | 2 | Ani | 20230002 | | 3 | Dedi | 20230003 |
Tabel Mata_Kuliah: | ID_Mata_Kuliah | Nama_Mata_Kuliah | SKS | |—————-|——————|—–| | 101 | Database | 3 | | 102 | Pemrograman Web | 3 | | 103 | Jaringan | 3 |
Tabel Siswa_Mata_Kuliah (Junction Table): | ID_Siswa | ID_Mata_Kuliah | Nilai | Semester | |———-|—————-|——-|———-| | 1 | 101 | A | 3 | | 1 | 102 | B | 3 | | 2 | 101 | A | 3 | | 2 | 103 | B | 3 | | 3 | 102 | A | 3 |
Diagram:
Siswa (M) ←→ Siswa_Mata_Kuliah ←→ (N) Mata_Kuliah
Berikut contoh implementasi schema database untuk sistem akademik:
-- Tabel Mahasiswa
CREATE TABLE Mahasiswa (
id_mahasiswa INT PRIMARY KEY AUTO_INCREMENT,
nim VARCHAR(10) UNIQUE NOT NULL,
nama VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE,
tanggal_lahir DATE,
alamat TEXT,
id_jurusan INT,
FOREIGN KEY (id_jurusan) REFERENCES Jurusan(id_jurusan)
);
-- Tabel Jurusan (One-to-Many dengan Mahasiswa)
CREATE TABLE Jurusan (
id_jurusan INT PRIMARY KEY AUTO_INCREMENT,
kode_jurusan VARCHAR(10) UNIQUE NOT NULL,
nama_jurusan VARCHAR(100) NOT NULL,
fakultas VARCHAR(100)
);
-- Tabel Dosen
CREATE TABLE Dosen (
id_dosen INT PRIMARY KEY AUTO_INCREMENT,
nip VARCHAR(20) UNIQUE NOT NULL,
nama VARCHAR(100) NOT NULL,
email VARCHAR(100) UNIQUE,
spesialisasi VARCHAR(100)
);
-- Tabel Mata_Kuliah
CREATE TABLE Mata_Kuliah (
id_mata_kuliah INT PRIMARY KEY AUTO_INCREMENT,
kode_mk VARCHAR(10) UNIQUE NOT NULL,
nama_mk VARCHAR(100) NOT NULL,
sks INT NOT NULL,
id_dosen INT,
FOREIGN KEY (id_dosen) REFERENCES Dosen(id_dosen)
);
-- Tabel Pengambilan_MK (Junction Table untuk Many-to-Many)
CREATE TABLE Pengambilan_MK (
id_pengambilan INT PRIMARY KEY AUTO_INCREMENT,
id_mahasiswa INT,
id_mata_kuliah INT,
semester INT,
tahun_ajaran VARCHAR(10),
nilai_angka DECIMAL(5,2),
nilai_huruf CHAR(2),
FOREIGN KEY (id_mahasiswa) REFERENCES Mahasiswa(id_mahasiswa),
FOREIGN KEY (id_mata_kuliah) REFERENCES Mata_Kuliah(id_mata_kuliah),
UNIQUE KEY unique_pengambilan (id_mahasiswa, id_mata_kuliah, semester, tahun_ajaran)
);
1. Menampilkan semua mahasiswa dengan jurusannya:
SELECT
m.nim,
m.nama,
m.email,
j.nama_jurusan,
j.fakultas
FROM Mahasiswa m
JOIN Jurusan j ON m.id_jurusan = j.id_jurusan
ORDER BY m.nama;
2. Menampilkan mata kuliah yang diambil oleh seorang mahasiswa:
SELECT
m.nama AS nama_mahasiswa,
mk.kode_mk,
mk.nama_mk,
mk.sks,
p.nilai_huruf,
d.nama AS nama_dosen
FROM Pengambilan_MK p
JOIN Mahasiswa m ON p.id_mahasiswa = m.id_mahasiswa
JOIN Mata_Kuliah mk ON p.id_mata_kuliah = mk.id_mata_kuliah
JOIN Dosen d ON mk.id_dosen = d.id_dosen
WHERE m.nim = '20230001'
ORDER BY mk.nama_mk;
3. Menghitung IPK mahasiswa:
SELECT
m.nim,
m.nama,
AVG(
CASE p.nilai_huruf
WHEN 'A' THEN 4.0
WHEN 'AB' THEN 3.5
WHEN 'B' THEN 3.0
WHEN 'BC' THEN 2.5
WHEN 'C' THEN 2.0
WHEN 'D' THEN 1.0
WHEN 'E' THEN 0.0
ELSE 0
END
) AS IPK
FROM Mahasiswa m
JOIN Pengambilan_MK p ON m.id_mahasiswa = p.id_mahasiswa
GROUP BY m.id_mahasiswa, m.nim, m.nama
ORDER BY IPK DESC;
4. Menampilkan mata kuliah dengan jumlah mahasiswanya:
SELECT
mk.kode_mk,
mk.nama_mk,
d.nama AS dosen_pengampu,
COUNT(p.id_mahasiswa) AS jumlah_mahasiswa
FROM Mata_Kuliah mk
LEFT JOIN Pengambilan_MK p ON mk.id_mata_kuliah = p.id_mata_kuliah
JOIN Dosen d ON mk.id_dosen = d.id_dosen
GROUP BY mk.id_mata_kuliah, mk.kode_mk, mk.nama_mk, d.nama
ORDER BY jumlah_mahasiswa DESC;
Berikut adalah representasi visual dari relasi antar tabel:
┌─────────────┐ ┌──────────────┐
│ Jurusan │ │ Dosen │
├─────────────┤ ├──────────────┤
│ id_jurusan │ │ id_dosen │
│ kode_jurusan│ │ nip │
│ nama_jurusan│ │ nama │
│ fakultas │ │ email │
└──────┬──────┘ │ spesialisasi │
│ └──────┬───────┘
│ 1:N │ 1:N
│ │
┌──────┴──────┐ ┌──────┴──────────┐
│ Mahasiswa │ │ Mata_Kuliah │
├─────────────┤ ├─────────────────┤
│id_mahasiswa │ │ id_mata_kuliah │
│ nim │ │ kode_mk │
│ nama │ │ nama_mk │
│ email │ │ sks │
│tanggal_lahir│ │ id_dosen (FK) │
│ alamat │ └────────┬────────┘
│id_jurusan(FK)│ │
└──────┬──────┘ │
│ │
│ M:N │
│ │
└────────┬───────────────┘
│
┌───────┴──────────┐
│ Pengambilan_MK │
├──────────────────┤
│ id_pengambilan │
│ id_mahasiswa (FK)│
│id_mata_kuliah(FK)│
│ semester │
│ tahun_ajaran │
│ nilai_angka │
│ nilai_huruf │
└──────────────────┘
Meskipun normalisasi penting, terkadang denormalisasi diperlukan untuk performa. Pertimbangkan:
Selalu gunakan foreign key constraint untuk memastikan referential integrity:
FOREIGN KEY (id_column) REFERENCES parent_table(id_column)
ON DELETE CASCADE
ON UPDATE CASCADE
Buat index pada kolom yang sering digunakan untuk:
CREATE INDEX idx_mahasiswa_nim ON Mahasiswa(nim);
CREATE INDEX idx_mata_kuliah_kode ON Mata_Kuliah(kode_mk);
Gunakan naming convention yang konsisten:
id_nama_tabel atau hanya idid_nama_tabel_referensitabel1_tabel2 atau nama yang deskriptifPerhatikan tabel berikut:
| ID_Pegawai | Nama | Departemen | Lokasi_Dept | Gaji | Proyek |
|---|---|---|---|---|---|
| 1 | Ahmad | IT | Gedung A | 8000000 | Website, Mobile App |
| 2 | Budi | HR | Gedung B | 6000000 | Recruitment |
| 3 | Citra | IT | Gedung A | 8500000 | Mobile App |
Pertanyaan:
Buatlah schema database untuk sistem perpustakaan dengan requirement:
Tentukan:
Normalisasi database adalah teknik fundamental dalam desain database yang bertujuan untuk:
Poin-poin Penting:
Dengan memahami normalisasi dan relasi, Anda dapat mendesain database yang efisien, scalable, dan mudah dimaintain.
Dibuat pada: 31 Maret 2026
Tags: #database #normalisasi #relasi #SQL #tutorial #basis-data