DB Belajar DatabaseDoni Winarso
Referensi SQL ↗
Database · Bab 01

Pengantar Database

Database adalah kumpulan data yang terorganisir sehingga mudah diakses, dikelola, dan diperbarui. SQL (Structured Query Language) adalah bahasa standar untuk berkomunikasi dengan database relasional.

Apa itu Database?

Database (basis data) menyimpan informasi secara terstruktur. Contoh sehari-hari: daftar kontak di ponsel, riwayat transaksi bank, hingga katalog produk toko online — semuanya disimpan dalam database.

Tanpa database, data biasanya tersimpan di file teks atau spreadsheet yang sulit dikelola saat datanya banyak. Database memungkinkan pencarian cepat, penyimpanan konsisten, dan akses bersamaan oleh banyak pengguna.

Jenis-jenis Database

JenisDeskripsiContoh
Relasional (RDBMS)Data disimpan dalam tabel dengan baris dan kolomMySQL, PostgreSQL, Oracle
NoSQLData tersimpan sebagai dokumen, key-value, atau grafMongoDB, Redis, Cassandra
NewSQLSkalabilitas NoSQL dengan jaminan ACID relasionalCockroachDB, TiDB

Mengapa Belajar SQL?

Catatan: Contoh-contoh di modul ini menggunakan sintaks SQL standar yang kompatibel dengan MySQL dan sebagian besar RDBMS modern.
Database · Bab 02

RDBMS & Terminologi Dasar

RDBMS (Relational Database Management System) adalah perangkat lunak yang mengelola database relasional. Sebelum menulis SQL, penting memahami istilah-istilah dasarnya.

Konsep Tabel

Data diorganisir dalam tabel (juga disebut relasi). Setiap tabel punya nama unik dalam database.

id_mahasiswanamajurusanipk
1AndiInformatika3.75
2BudiSistem Informasi3.50
3CitraInformatika3.90

Istilah Penting

IstilahPenjelasan
TabelStruktur penyimpan data, terdiri atas baris dan kolom
Baris (Row / Record)Satu data lengkap dalam tabel
Kolom (Column / Field)Satu atribut dari sebuah tabel
Primary Key (PK)Kolom yang mengidentifikasi setiap baris secara unik
Foreign Key (FK)Kolom yang menghubungkan ke Primary Key tabel lain
IndexStruktur tambahan untuk mempercepat pencarian data
SchemaKumpulan definisi tabel, view, dan objek database lainnya
QueryPerintah SQL untuk mengambil atau memanipulasi data

Hubungan Antar Tabel

Kekuatan RDBMS ada pada relasi antar tabel. Ada tiga jenis relasi utama:

mahasiswaN—1jurusan mahasiswaM—Nmata_kuliah
Database · Bab 03

Tipe Data SQL

Setiap kolom dalam tabel harus punya tipe data. Tipe data menentukan jenis nilai yang boleh disimpan dan cara database mengelolanya secara internal.

Tipe Numerik

TipeUkuranKegunaan
TINYINT1 byteAngka kecil, boolean (0/1)
INT / INTEGER4 byteAngka bulat umum, ID
BIGINT8 byteAngka bulat sangat besar
DECIMAL(p,s)VariabelAngka presisi tetap (harga, IPK)
FLOAT / DOUBLE4/8 byteAngka desimal (presisi tidak tetap)

Tipe Teks

TipeMaks. PanjangKegunaan
CHAR(n)255 karakterTeks panjang tetap (kode pos, kode negara)
VARCHAR(n)65.535 karakterTeks panjang bervariasi (nama, email)
TEXT65.535 karakterTeks panjang (artikel, deskripsi)
LONGTEXT~4 GBTeks sangat panjang

Tipe Tanggal & Waktu

TipeFormatKegunaan
DATEYYYY-MM-DDTanggal saja
TIMEHH:MM:SSWaktu saja
DATETIMEYYYY-MM-DD HH:MM:SSTanggal dan waktu
TIMESTAMPYYYY-MM-DD HH:MM:SSOtomatis diperbarui oleh DB
Tips: Gunakan DECIMAL bukan FLOAT untuk nilai keuangan agar tidak kehilangan presisi akibat pembulatan floating-point.
Database · Bab 04

DDL — Data Definition Language

DDL digunakan untuk mendefinisikan struktur database: membuat tabel, mengubah strukturnya, atau menghapusnya. Perintah utama: CREATE, ALTER, dan DROP.

CREATE DATABASE & TABLE

-- Buat database baru
CREATE DATABASE kampus;

-- Gunakan database tersebut
USE kampus;

-- Buat tabel mahasiswa
CREATE TABLE mahasiswa (
    id_mahasiswa INT          NOT NULL AUTO_INCREMENT,
    nim          VARCHAR(12)  NOT NULL UNIQUE,
    nama         VARCHAR(100) NOT NULL,
    jurusan      VARCHAR(80),
    ipk          DECIMAL(3,2) DEFAULT 0.00,
    tgl_masuk    DATE,
    created_at   TIMESTAMP    DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id_mahasiswa)
);

Constraint Penting

ConstraintFungsi
NOT NULLKolom tidak boleh kosong
UNIQUENilai harus unik di seluruh tabel
PRIMARY KEYNOT NULL + UNIQUE, identifikasi baris
FOREIGN KEYMerujuk Primary Key tabel lain
DEFAULTNilai otomatis jika tidak diisi
CHECKMemvalidasi nilai dengan kondisi tertentu

Contoh Tabel dengan Foreign Key

CREATE TABLE mata_kuliah (
    id_mk    INT         NOT NULL AUTO_INCREMENT,
    kode_mk  VARCHAR(10) NOT NULL UNIQUE,
    nama_mk  VARCHAR(100) NOT NULL,
    sks      TINYINT     NOT NULL DEFAULT 2,
    PRIMARY KEY (id_mk)
);

CREATE TABLE nilai (
    id_nilai     INT NOT NULL AUTO_INCREMENT,
    id_mahasiswa INT NOT NULL,
    id_mk        INT NOT NULL,
    nilai_akhir  DECIMAL(5,2),
    PRIMARY KEY (id_nilai),
    FOREIGN KEY (id_mahasiswa) REFERENCES mahasiswa(id_mahasiswa) ON DELETE CASCADE,
    FOREIGN KEY (id_mk)        REFERENCES mata_kuliah(id_mk)      ON DELETE RESTRICT
);

ALTER TABLE

-- Tambah kolom baru
ALTER TABLE mahasiswa ADD COLUMN email VARCHAR(120) AFTER nama;

-- Ubah tipe kolom
ALTER TABLE mahasiswa MODIFY COLUMN ipk DECIMAL(4,2);

-- Ubah nama kolom
ALTER TABLE mahasiswa RENAME COLUMN jurusan TO program_studi;

-- Hapus kolom
ALTER TABLE mahasiswa DROP COLUMN tgl_masuk;

DROP TABLE & DATABASE

-- Hapus tabel (data ikut terhapus)
DROP TABLE IF EXISTS nilai;

-- Hapus database (semua tabel ikut terhapus)
DROP DATABASE IF EXISTS kampus;
Hati-hati: DROP menghapus data secara permanen. Selalu cadangkan data penting sebelum menjalankan perintah ini.
Database · Bab 05

DML — Data Manipulation Language

DML digunakan untuk memanipulasi data di dalam tabel: memasukkan, memperbarui, dan menghapus baris. Perintah utama: INSERT, UPDATE, dan DELETE.

INSERT — Menambah Data

-- Sisipkan satu baris
INSERT INTO mahasiswa (nim, nama, program_studi, ipk)
VALUES ('2021001', 'Andi Pratama', 'Informatika', 3.75);

-- Sisipkan banyak baris sekaligus
INSERT INTO mahasiswa (nim, nama, program_studi, ipk) VALUES
  ('2021002', 'Budi Santoso',  'Sistem Informasi', 3.50),
  ('2021003', 'Citra Dewi',    'Informatika',       3.90),
  ('2021004', 'Deni Firmansyah','Manajemen',        3.20);

UPDATE — Memperbarui Data

-- Perbarui satu baris (berdasarkan PK)
UPDATE mahasiswa
SET ipk = 3.80
WHERE id_mahasiswa = 1;

-- Perbarui banyak baris sekaligus
UPDATE mahasiswa
SET program_studi = 'Teknik Informatika'
WHERE program_studi = 'Informatika';
Penting: Selalu sertakan klausa WHERE saat menggunakan UPDATE dan DELETE. Tanpa WHERE, seluruh baris di tabel akan terpengaruh.

DELETE — Menghapus Data

-- Hapus satu baris
DELETE FROM mahasiswa WHERE id_mahasiswa = 4;

-- Hapus semua baris dengan kondisi
DELETE FROM mahasiswa WHERE ipk < 2.00;

-- Kosongkan seluruh tabel (lebih cepat dari DELETE tanpa WHERE)
TRUNCATE TABLE mahasiswa;

DELETE vs TRUNCATE

AspekDELETETRUNCATE
Kondisi WHEREBisaTidak bisa
KecepatanLebih lambat (per baris)Lebih cepat (langsung reset)
Reset AUTO_INCREMENTTidakYa
Bisa di-rollbackYa (jika dalam transaksi)Tidak di semua RDBMS
Database · Bab 06

SELECT & Klausa Dasar

SELECT adalah perintah paling sering digunakan dalam SQL. Perintah ini mengambil data dari satu atau lebih tabel sesuai kondisi yang kita tentukan.

Sintaks Dasar

-- Ambil semua kolom
SELECT * FROM mahasiswa;

-- Ambil kolom tertentu saja
SELECT nim, nama, ipk FROM mahasiswa;

-- Beri alias kolom
SELECT nama AS "Nama Mahasiswa", ipk AS "Nilai IPK"
FROM mahasiswa;

Klausa WHERE

-- Mahasiswa dengan IPK di atas 3.5
SELECT * FROM mahasiswa WHERE ipk > 3.5;

-- Mahasiswa dari Informatika dengan IPK >= 3.7
SELECT nama, ipk
FROM mahasiswa
WHERE program_studi = 'Informatika'
  AND ipk >= 3.7;

ORDER BY — Pengurutan

-- Urutkan dari IPK tertinggi ke terendah
SELECT nama, ipk
FROM mahasiswa
ORDER BY ipk DESC;

-- Urutkan berdasarkan program studi (A-Z) lalu IPK (terbesar dulu)
SELECT nama, program_studi, ipk
FROM mahasiswa
ORDER BY program_studi ASC, ipk DESC;

LIMIT & OFFSET — Paginasi

-- Ambil 5 baris pertama
SELECT * FROM mahasiswa LIMIT 5;

-- Halaman 2 (5 baris, lewati 5 baris pertama)
SELECT * FROM mahasiswa LIMIT 5 OFFSET 5;

DISTINCT — Nilai Unik

-- Tampilkan daftar program studi yang ada (tanpa duplikat)
SELECT DISTINCT program_studi FROM mahasiswa;
FROM→WHERE→GROUP BY→HAVING→SELECT→ORDER BY→LIMIT

Urutan di atas adalah urutan eksekusi logis SQL, bukan urutan penulisan. Paham urutan ini membantu memahami mengapa alias dari SELECT belum bisa dipakai di WHERE.

Database · Bab 07

Operator & Kondisi

SQL menyediakan berbagai operator untuk menyaring dan membandingkan data di klausa WHERE.

Operator Perbandingan

OperatorArti
=Sama dengan
<> atau !=Tidak sama dengan
> < >= <=Lebih besar / lebih kecil
BETWEEN a AND bNilai antara a dan b (inklusif)
IN (a, b, c)Nilai ada dalam daftar
NOT IN (...)Nilai tidak dalam daftar
IS NULLNilai kosong (NULL)
IS NOT NULLNilai tidak kosong
LIKE 'pola%'Pencarian pola teks

Contoh Penggunaan

-- BETWEEN
SELECT * FROM mahasiswa WHERE ipk BETWEEN 3.00 AND 3.75;

-- IN
SELECT * FROM mahasiswa
WHERE program_studi IN ('Informatika', 'Sistem Informasi');

-- LIKE (% = nol atau lebih karakter, _ = tepat satu karakter)
SELECT * FROM mahasiswa WHERE nama LIKE 'A%';      -- nama awalan A
SELECT * FROM mahasiswa WHERE nim  LIKE '2021___'; -- NIM 7 digit awalan 2021

-- IS NULL
SELECT * FROM mahasiswa WHERE email IS NULL;

-- Kombinasi AND / OR / NOT
SELECT * FROM mahasiswa
WHERE (program_studi = 'Informatika' OR program_studi = 'Sistem Informasi')
  AND ipk >= 3.5
  AND email IS NOT NULL;
Tips: Gunakan tanda kurung () saat menggabungkan AND dan OR untuk memastikan urutan evaluasi sesuai yang diinginkan.
Database · Bab 08

Fungsi Agregat

Fungsi agregat merangkum banyak baris menjadi satu nilai. Digunakan untuk menghitung jumlah, rata-rata, nilai maksimum, minimum, dan total.

Fungsi Utama

FungsiKegunaan
COUNT(*)Hitung jumlah baris
COUNT(kolom)Hitung baris yang nilainya bukan NULL
SUM(kolom)Jumlah total nilai numerik
AVG(kolom)Rata-rata nilai numerik
MAX(kolom)Nilai terbesar
MIN(kolom)Nilai terkecil

Contoh Query

-- Jumlah total mahasiswa
SELECT COUNT(*) AS total_mahasiswa FROM mahasiswa;

-- Rata-rata IPK seluruh mahasiswa
SELECT AVG(ipk) AS rata_ipk FROM mahasiswa;

-- IPK tertinggi dan terendah
SELECT MAX(ipk) AS ipk_max, MIN(ipk) AS ipk_min FROM mahasiswa;

-- Jumlah nilai mata kuliah per mahasiswa
SELECT id_mahasiswa, COUNT(id_mk) AS jml_mk, AVG(nilai_akhir) AS rata_nilai
FROM nilai
GROUP BY id_mahasiswa;

Fungsi String & Tanggal Umum

-- String
SELECT UPPER(nama), LOWER(email), LENGTH(nama) FROM mahasiswa;
SELECT CONCAT(nama, ' - ', program_studi) AS info FROM mahasiswa;

-- Tanggal
SELECT NOW(), CURDATE(), YEAR(tgl_masuk), DATEDIFF(NOW(), tgl_masuk) AS hari_kuliah
FROM mahasiswa;
Database · Bab 09

GROUP BY & HAVING

GROUP BY mengelompokkan baris berdasarkan satu atau lebih kolom sehingga fungsi agregat dapat diterapkan per kelompok. HAVING menyaring hasil pengelompokan tersebut.

GROUP BY

-- Jumlah mahasiswa per program studi
SELECT program_studi, COUNT(*) AS jumlah_mahasiswa
FROM mahasiswa
GROUP BY program_studi;

-- Rata-rata IPK per program studi
SELECT program_studi,
       COUNT(*)    AS jumlah,
       AVG(ipk)    AS rata_ipk,
       MAX(ipk)    AS ipk_terbaik
FROM mahasiswa
GROUP BY program_studi
ORDER BY rata_ipk DESC;

HAVING — Filter Hasil Agregat

WHERE menyaring baris sebelum dikelompokkan. HAVING menyaring hasil kelompok setelah agregat dihitung.

-- Program studi dengan rata-rata IPK di atas 3.5
SELECT program_studi, AVG(ipk) AS rata_ipk
FROM mahasiswa
GROUP BY program_studi
HAVING AVG(ipk) > 3.5;

-- Program studi dengan lebih dari 10 mahasiswa aktif
SELECT program_studi, COUNT(*) AS jml
FROM mahasiswa
WHERE status = 'aktif'     -- WHERE dulu (saring baris)
GROUP BY program_studi
HAVING COUNT(*) > 10;      -- HAVING kemudian (saring kelompok)
Perbedaan kunci: WHERE → sebelum GROUP BY, tidak bisa pakai fungsi agregat. HAVING → setelah GROUP BY, bisa pakai fungsi agregat.
Database · Bab 10

JOIN

JOIN menggabungkan baris dari dua tabel atau lebih berdasarkan kolom yang berelasi. Ini adalah salah satu fitur terpenting dalam database relasional.

Jenis-jenis JOIN

JenisHasil
INNER JOINHanya baris yang memiliki pasangan di kedua tabel
LEFT JOINSemua baris tabel kiri + baris pasangan dari kanan (NULL jika tidak ada)
RIGHT JOINSemua baris tabel kanan + baris pasangan dari kiri (NULL jika tidak ada)
FULL OUTER JOINSemua baris dari kedua tabel (tidak semua RDBMS mendukung)
CROSS JOINPerkalian kartesian semua baris

INNER JOIN

-- Tampilkan nama mahasiswa beserta nilai mata kuliahnya
SELECT m.nama, mk.nama_mk, n.nilai_akhir
FROM nilai n
INNER JOIN mahasiswa   m  ON n.id_mahasiswa = m.id_mahasiswa
INNER JOIN mata_kuliah mk ON n.id_mk        = mk.id_mk
ORDER BY m.nama;

LEFT JOIN

-- Semua mahasiswa, tampilkan nilai jika ada (NULL jika belum ada nilai)
SELECT m.nama, mk.nama_mk, n.nilai_akhir
FROM mahasiswa m
LEFT JOIN nilai        n  ON m.id_mahasiswa = n.id_mahasiswa
LEFT JOIN mata_kuliah mk  ON n.id_mk        = mk.id_mk;

-- Mahasiswa yang BELUM memiliki nilai sama sekali
SELECT m.nama
FROM mahasiswa m
LEFT JOIN nilai n ON m.id_mahasiswa = n.id_mahasiswa
WHERE n.id_nilai IS NULL;

Self JOIN

-- Contoh: tabel karyawan dengan kolom id_manager (FK ke diri sendiri)
SELECT k.nama AS karyawan, m.nama AS manager
FROM karyawan k
LEFT JOIN karyawan m ON k.id_manager = m.id_karyawan;
Tips performa: Pastikan kolom yang digunakan untuk JOIN (terutama FK) sudah diindeks agar query berjalan cepat.
Database · Bab 11

Subquery

Subquery (query bersarang) adalah query di dalam query lain. Hasilnya digunakan sebagai sumber data, kondisi, atau nilai dalam query luar.

Subquery di WHERE

-- Mahasiswa dengan IPK di atas rata-rata
SELECT nama, ipk
FROM mahasiswa
WHERE ipk > (SELECT AVG(ipk) FROM mahasiswa);

-- Mahasiswa yang memiliki nilai di mata kuliah 'Basis Data'
SELECT nama FROM mahasiswa
WHERE id_mahasiswa IN (
    SELECT n.id_mahasiswa
    FROM nilai n
    INNER JOIN mata_kuliah mk ON n.id_mk = mk.id_mk
    WHERE mk.nama_mk = 'Basis Data'
);

Subquery di FROM (Derived Table)

-- Rata-rata IPK per program studi, lalu ambil yang di atas 3.6
SELECT prodi, rata_ipk
FROM (
    SELECT program_studi AS prodi, AVG(ipk) AS rata_ipk
    FROM mahasiswa
    GROUP BY program_studi
) AS ringkasan
WHERE rata_ipk > 3.6;

Subquery dengan EXISTS

-- Mahasiswa yang sudah pernah mengambil setidaknya satu mata kuliah
SELECT nama FROM mahasiswa m
WHERE EXISTS (
    SELECT 1 FROM nilai n WHERE n.id_mahasiswa = m.id_mahasiswa
);

-- Mahasiswa yang BELUM pernah mengambil mata kuliah apa pun
SELECT nama FROM mahasiswa m
WHERE NOT EXISTS (
    SELECT 1 FROM nilai n WHERE n.id_mahasiswa = m.id_mahasiswa
);
Subquery vs JOIN: Untuk banyak kasus, JOIN lebih cepat dari subquery karena optimizer database lebih efisien menanganinya. Gunakan subquery saat logikanya lebih mudah dipahami atau saat EXISTS lebih sesuai.
Database · Bab 12

INDEX

Index mempercepat pencarian data dengan membuat struktur pencarian tambahan, mirip daftar isi buku. Tanpa index, database harus memindai seluruh tabel (full table scan).

Membuat Index

-- Index sederhana pada satu kolom
CREATE INDEX idx_nama ON mahasiswa(nama);

-- Index unik (nilai tidak boleh duplikat)
CREATE UNIQUE INDEX idx_nim ON mahasiswa(nim);

-- Index komposit (dua kolom sekaligus)
CREATE INDEX idx_prodi_ipk ON mahasiswa(program_studi, ipk);

-- Tampilkan semua index pada tabel
SHOW INDEX FROM mahasiswa;

Menghapus Index

DROP INDEX idx_nama ON mahasiswa;

Kapan Menggunakan Index?

Gunakan IndexHindari Index
Kolom yang sering dipakai di WHERETabel sangat kecil (kurang dari ratusan baris)
Kolom Foreign KeyKolom yang sangat sering di-UPDATE/INSERT
Kolom yang sering di ORDER BY atau JOINKolom dengan sedikit nilai unik (mis. jenis kelamin)
Tradeoff: Index mempercepat pembacaan (SELECT) tetapi memperlambat penulisan (INSERT, UPDATE, DELETE) karena index juga perlu diperbarui. Jangan membuat index sembarangan.
Database · Bab 13

VIEW

View adalah query yang disimpan sebagai objek virtual di database. View terlihat seperti tabel biasa saat di-query, tetapi datanya tidak disimpan secara fisik — dihasilkan dinamis setiap kali diakses.

Membuat View

-- View ringkasan akademik mahasiswa
CREATE VIEW v_akademik AS
SELECT
    m.nim,
    m.nama,
    m.program_studi,
    m.ipk,
    COUNT(n.id_mk)       AS total_mk_diambil,
    AVG(n.nilai_akhir)   AS rata_nilai
FROM mahasiswa m
LEFT JOIN nilai n ON m.id_mahasiswa = n.id_mahasiswa
GROUP BY m.id_mahasiswa, m.nim, m.nama, m.program_studi, m.ipk;

Menggunakan View

-- Query view seperti tabel biasa
SELECT * FROM v_akademik WHERE ipk >= 3.5 ORDER BY ipk DESC;

-- Gabungkan view dengan tabel lain
SELECT v.nama, v.rata_nilai, mk.nama_mk
FROM v_akademik v
JOIN nilai n   ON n.id_mahasiswa = (SELECT id_mahasiswa FROM mahasiswa WHERE nim = v.nim)
JOIN mata_kuliah mk ON n.id_mk = mk.id_mk;

Memodifikasi & Menghapus View

-- Perbarui definisi view
CREATE OR REPLACE VIEW v_akademik AS
SELECT m.nim, m.nama, m.program_studi, m.ipk
FROM mahasiswa m;

-- Hapus view
DROP VIEW IF EXISTS v_akademik;

Manfaat View

Database · Bab 14

Transaksi & ACID

Transaksi adalah sekelompok operasi SQL yang dieksekusi sebagai satu unit. Jika salah satu operasi gagal, semua operasi dalam kelompok tersebut dibatalkan.

Perintah Transaksi

-- Mulai transaksi
START TRANSACTION;

-- Operasi 1: kurangi saldo pengirim
UPDATE rekening SET saldo = saldo - 1000000 WHERE id_rekening = 101;

-- Operasi 2: tambah saldo penerima
UPDATE rekening SET saldo = saldo + 1000000 WHERE id_rekening = 202;

-- Jika semua berhasil, simpan permanen
COMMIT;

-- Jika terjadi kesalahan, batalkan semua perubahan
ROLLBACK;

SAVEPOINT

START TRANSACTION;

INSERT INTO log_transfer (keterangan) VALUES ('Transfer dimulai');
SAVEPOINT sp1;

UPDATE rekening SET saldo = saldo - 500000 WHERE id_rekening = 101;
SAVEPOINT sp2;

-- Jika langkah ini gagal, kembali ke sp1 saja
UPDATE rekening SET saldo = saldo + 500000 WHERE id_rekening = 202;

-- Kembali ke savepoint tertentu (tidak rollback seluruh transaksi)
ROLLBACK TO sp1;

COMMIT;

Prinsip ACID

PrinsipPenjelasan
AtomicitySemua operasi berhasil, atau semuanya dibatalkan — tidak ada yang "setengah jadi".
ConsistencySetiap transaksi membawa database dari satu state valid ke state valid lainnya.
IsolationTransaksi yang berjalan bersamaan tidak saling mengganggu.
DurabilitySetelah COMMIT, perubahan tersimpan permanen meskipun sistem mati mendadak.
Contoh nyata: Transfer uang antar rekening harus ACID — tidak boleh saldo sudah berkurang di pengirim tetapi belum bertambah di penerima karena sistem crash.
Database · Bab 15

Normalisasi Database

Normalisasi adalah proses mengorganisasi tabel dan kolom agar mengurangi redundansi data dan meningkatkan integritas. Ada beberapa tingkatan normal form (NF).

Anomali yang Dihindari

1NF — First Normal Form

Setiap sel harus berisi nilai tunggal (atomik). Tidak boleh ada kolom yang berisi daftar nilai atau grup yang berulang.

-- Salah (tidak 1NF): kolom mata_kuliah berisi banyak nilai
mahasiswa(id, nama, mata_kuliah)
  1, Andi, "Basis Data, Pemrograman, Jaringan"

-- Benar (1NF): satu baris satu nilai
mahasiswa_mk(id_mahasiswa, id_mk)
  1, 101
  1, 102
  1, 103

2NF — Second Normal Form

Harus memenuhi 1NF, dan semua kolom non-kunci harus bergantung penuh pada seluruh Primary Key (tidak boleh hanya bergantung pada sebagian PK komposit).

-- Tabel nilai (PK komposit: id_mahasiswa + id_mk)
-- Tidak 2NF jika ada kolom yang hanya bergantung pada id_mahasiswa saja:
nilai(id_mahasiswa, id_mk, nilai_akhir, nama_mahasiswa) -- nama_mahasiswa hanya tergantung id_mahasiswa

-- Solusi: pisahkan
mahasiswa(id_mahasiswa, nama_mahasiswa, ...)
nilai(id_mahasiswa, id_mk, nilai_akhir)

3NF — Third Normal Form

Harus memenuhi 2NF, dan tidak boleh ada dependensi transitif (kolom non-kunci bergantung pada kolom non-kunci lain).

-- Tidak 3NF:
mahasiswa(id_mahasiswa, nama, id_prodi, nama_prodi)
-- nama_prodi bergantung pada id_prodi, bukan langsung pada id_mahasiswa

-- Solusi (3NF):
mahasiswa(id_mahasiswa, nama, id_prodi)
program_studi(id_prodi, nama_prodi, ...)

Ringkasan Normal Form

NFSyarat
1NFNilai atomik, tidak ada grup berulang
2NF1NF + tidak ada partial dependency pada PK komposit
3NF2NF + tidak ada transitive dependency
BCNFVersi 3NF yang lebih ketat untuk kasus edge case
Praktis: Untuk sebagian besar proyek, normalisasi sampai 3NF sudah cukup. Denormalisasi (sengaja melanggar normal form) kadang dilakukan untuk meningkatkan performa query berat di sistem analitik.