📊 Data Modelling
🎓 Pertemuan
Pertemuan 6: Normalisasi Data (1NF – 3NF)

MODUL PERTEMUAN 6

NORMALISASI DATA (1NF – 3NF)


A. INFORMASI UMUM MATA KULIAH

ItemKeterangan
Mata KuliahData Modelling
Kode MKSSD1019
Bobot3 SKS (Praktikum)
Semester4 (Empat)
Program StudiSains Data
FakultasEkonomi dan Bisnis Islam
UniversitasUIN K.H. Abdurrahman Wahid Pekalongan
Dosen PengampuMohammad Reza Maulana, M.Kom

B. INFORMASI PERTEMUAN

B.1 Sub-CPMK Pertemuan 6

Sub-CPMK 4.1: Mahasiswa mampu menyusun dan memvalidasi model data logikal yang bebas dari redundansi dan anomali, dengan menerapkan teknik normalisasi secara sistematis dari bentuk tidak normal hingga Third Normal Form (3NF).

B.2 Tujuan Pembelajaran (Learning Objectives)

Setelah mengikuti pertemuan ini, mahasiswa akan mampu:

  1. Menjelaskan tiga jenis anomali data (insertion, update, deletion) dan dampaknya terhadap integritas database (C2 – Memahami)
  2. Mengidentifikasi functional dependency (FD) dari sebuah relasi berdasarkan semantik bisnis (C3 – Mengaplikasikan)
  3. Membedakan jenis-jenis ketergantungan: full FD, partial dependency, dan transitive dependency (C2 – Memahami)
  4. Menerapkan normalisasi 1NF, 2NF, dan 3NF secara step-by-step pada tabel yang diberikan (C3 – Mengaplikasikan)
  5. Menganalisis sebuah tabel untuk menentukan apakah sudah memenuhi syarat bentuk normal tertentu (C4 – Menganalisis)
  6. Merancang skema relasional yang ternormalisasi hingga 3NF dari narasi bisnis yang diberikan (C4 – Menganalisis)

B.3 Kompetensi yang Dikembangkan

DomainKompetensi
KognitifMemahami anomali dan FD (C2), Menerapkan normalisasi (C3), Menganalisis tabel (C4)
AfektifMengembangkan ketelitian dalam memeriksa dependensi; menghargai pentingnya desain database yang bersih
PsikomotorikMendokumentasikan langkah normalisasi secara runtut; menulis skema hasil normalisasi dalam notasi formal

B.4 Indikator Pencapaian

Setelah mengikuti pertemuan ini, mahasiswa diharapkan mampu:

  1. Mencontohkan ketiga jenis anomali dari satu tabel yang sama secara konkret
  2. Menuliskan semua functional dependency yang ada dalam sebuah relasi
  3. Memverifikasi apakah sebuah relasi memenuhi 1NF, 2NF, atau 3NF
  4. Mendekomposisi tabel yang tidak normal menjadi tabel-tabel yang memenuhi 3NF
  5. Membuktikan bahwa dekomposisi yang dilakukan tidak kehilangan informasi (lossless decomposition)

B.5 Alokasi Waktu

NoKegiatanDurasiKeterangan
1Pembukaan & Review Tugas Mapping Pertemuan 510 menitHighlight pola umum dari tugas mahasiswa
2Aktivitas Pemantik: "Database Bermasalah"10 menitEksplorasi spreadsheet data yang kotor
3Materi 1: Anomali Data — Tiga Penyakit Database20 menitCeramah + demonstrasi konkret
4Materi 2: Functional Dependency — Bahasa Normalisasi20 menitCeramah + latihan identifikasi FD
5Break10 menit–
6Materi 3: First Normal Form (1NF)15 menitCeramah + latihan
7Materi 4: Second Normal Form (2NF)20 menitCeramah + latihan bertahap
8Materi 5: Third Normal Form (3NF)20 menitCeramah + latihan bertahap
9Praktikum Terbimbing: Normalisasi End-to-End20 menitLatihan individual/berpasangan
10Review & Diskusi Hasil Praktikum10 menitPembahasan bersama, tanya jawab
11Evaluasi, Briefing Tugas & Penutup10 menitKuis, penjelasan tugas normalisasi, refleksi
Total165 menit(termasuk fleksibilitas 5 menit)

C. MATERI PEMBELAJARAN

C.1 Aktivitas Pemantik – "Database Bermasalah"

Instruksi (10 menit): Dosen menampilkan tabel berikut di layar. Tabel ini adalah rekaman data yang disimpan oleh sebuah toko buku dalam satu spreadsheet Excel. Mahasiswa diminta mengamati dan menjawab pertanyaan.

Tabel: TRANSAKSI_TOKO_BUKU

no_fakturtgl_fakturid_pembelinama_pembelikota_pembelikode_bukujudul_bukunama_penulishargaqtysubtotal
F0012025-01-10C001Andi WijayaSemarangB101Belajar PythonRudi Hartono850002170000
F0012025-01-10C001Andi WijayaSemarangB205Data ScienceMaya Sari1200001120000
F0022025-01-11C002Budi SantosoPekalonganB101Belajar PythonRudi Hartono85000185000
F0032025-01-12C001Andi WijayaJakartaB310Machine LearningDewi Lestari1500003450000
F0042025-01-15C003Citra DewiSemarangB205Data ScienceMaya Sari950002190000

Pertanyaan Pemantik:

  1. Temukan inkonsistensi! Perhatikan data C001 - Andi Wijaya. Ada apa yang janggal di baris F001 dibanding F003?

  2. Bayangkan skenario ini: Harga buku B205 "Data Science" naik dari 120.000 menjadi 130.000. Berapa baris yang harus diubah? Apa risikonya?

  3. Bayangkan skenario lain: Faktur F004 ternyata dibatalkan dan harus dihapus. Apa informasi lain yang ikut hilang?

  4. Bisakah kita memasukkan data buku baru (kode_buku: B400, judul: "SQL Dasar", harga: 75.000) sebelum ada pembeli yang membeli buku tersebut?

Rangkuman Dosen: "Keempat masalah yang baru kalian temukan ini adalah bukti nyata mengapa normalisasi penting. Ini bukan sekadar teori — ini adalah penyakit nyata yang menyebabkan data tidak dapat dipercaya. Hari ini kita akan belajar teknik untuk menyembuhkannya secara sistematis."


C.2 Materi 1: Anomali Data — Tiga Penyakit Database

Anomali data adalah masalah yang timbul saat kita melakukan operasi manipulasi data (insert, update, delete) pada tabel yang tidak dirancang dengan baik. Ada tiga jenis anomali utama, dan ketiganya muncul akibat satu penyebab yang sama: redundansi data (data yang sama disimpan di lebih dari satu tempat).

C.2.1 Update Anomaly (Anomali Pembaruan)

Terjadi ketika memperbarui satu fakta membutuhkan pembaruan di banyak baris. Jika tidak semua baris diperbarui, timbul inkonsistensi.

CONTOH — Tabel PESANAN_DETAIL (tidak ternormalisasi):

| pesanan_id | pelanggan_id | nama_pelanggan | kota_pelanggan | produk_id | nama_produk    | harga  |
|------------|--------------|----------------|----------------|-----------|----------------|--------|
| P001       | C001         | Andi Wijaya    | Semarang       | PRD01     | Batik Motif A  | 150000 |
| P001       | C001         | Andi Wijaya    | Semarang       | PRD02     | Batik Motif B  | 200000 |
| P002       | C001         | Andi Wijaya    | Semarang       | PRD03     | Batik Motif C  | 175000 |
| P003       | C002         | Budi Santoso   | Pekalongan     | PRD01     | Batik Motif A  | 150000 |

SKENARIO: Andi Wijaya pindah dari Semarang ke Yogyakarta.

MASALAH:
  Harus update 3 baris (semua baris yang berisi C001).
  Jika admin hanya update 2 baris dari 3:
  → Baris pertama: kota = "Yogyakarta"  ← diperbarui
  → Baris kedua:  kota = "Yogyakarta"  ← diperbarui
  → Baris ketiga: kota = "Semarang"    ← LUPA! Inkonsistensi!

DAMPAK: Laporan yang berbeda menghasilkan data berbeda untuk pelanggan yang sama.

C.2.2 Insertion Anomaly (Anomali Penyisipan)

Terjadi ketika kita tidak bisa menyimpan data tentang satu entitas tanpa harus menyimpan data entitas lain secara bersamaan.

CONTOH — Tabel MENGAJAR (tidak ternormalisasi):

| dosen_id | nama_dosen   | kode_mk | nama_mk         | ruangan | semester |
|----------|--------------|---------|-----------------|---------|----------|
| D001     | Prof. Ahmad  | MK101   | Matematika Dasar| R201    | Ganjil   |
| D001     | Prof. Ahmad  | MK102   | Kalkulus        | R305    | Ganjil   |
| D002     | Dr. Budi     | MK201   | Statistika      | R102    | Ganjil   |

SKENARIO: Seorang dosen baru (D003, Dr. Citra) bergabung, tetapi belum mengampu
mata kuliah apapun semester ini.

MASALAH:
  Tidak bisa insert data D003 karena:
  → kode_mk adalah bagian dari PK (tidak boleh NULL atau kosong)
  → Tidak ada MK yang diajarkan → tidak ada baris yang bisa dibuat
  
  Akibatnya, data dosen baru tidak tersimpan padahal sudah ada di sistem HR!

SKENARIO LAIN: Kita ingin mendaftarkan MK baru (MK301, Aljabar Linear)
sebelum ada dosen yang ditugaskan:
  → Tidak bisa! Karena dosen_id juga bagian dari PK.

C.2.3 Deletion Anomaly (Anomali Penghapusan)

Terjadi ketika menghapus satu data secara tidak sengaja menghapus data lain yang seharusnya dipertahankan.

CONTOH — Tabel MENGAJAR (sama seperti di atas):

| dosen_id | nama_dosen   | kode_mk | nama_mk         | ruangan | semester |
|----------|--------------|---------|-----------------|---------|----------|
| D001     | Prof. Ahmad  | MK101   | Matematika Dasar| R201    | Ganjil   |
| D001     | Prof. Ahmad  | MK102   | Kalkulus        | R305    | Ganjil   |
| D002     | Dr. Budi     | MK201   | Statistika      | R102    | Ganjil   |

SKENARIO: Dr. Budi (D002) mengundurkan diri. Kita hapus semua baris terkait D002.

MASALAH:
  Saat menghapus baris D002:
  → Data mata kuliah MK201 (Statistika) ikut hilang!
  → Informasi bahwa MK201 pernah ada di sistem terhapus.
  
  Jika ada mahasiswa yang sudah mengambil MK201, referensi mereka menjadi rusak.
  Jika ingin menugaskan dosen lain untuk MK201, tidak ada data MK yang tersisa.

AKAR MASALAH KETIGANYA:
  Semua anomali berasal dari satu masalah yang sama:
  REDUNDANSI — informasi yang sama (nama dosen, nama MK) disimpan di banyak baris.
  Normalisasi adalah teknik untuk menghilangkan redundansi ini secara sistematis.

C.3 Materi 2: Functional Dependency — Bahasa Normalisasi

Sebelum bisa melakukan normalisasi, kita harus memahami functional dependency (FD) — konsep yang menjadi "bahasa" untuk mendeskripsikan hubungan antar atribut dalam sebuah relasi.

C.3.1 Definisi Functional Dependency

Definisi Formal: Dalam relasi R, atribut B functionally dependent pada atribut A (ditulis A → B) jika dan hanya jika: untuk setiap nilai A yang sama, pasti ada nilai B yang sama.

Cara membaca: "A menentukan B" atau "B bergantung pada A" atau "Jika A sama, maka B pasti sama."

NOTASI: A → B
  Dibaca: "A secara fungsional menentukan B"
          "A determines B"
          "B is functionally dependent on A"

CONTOH INTUITIF:

NIM → Nama_Mahasiswa
  "Jika NIM sama, maka Nama_Mahasiswa pasti sama"
  → Benar! Satu NIM hanya untuk satu mahasiswa.
  ✓ Ini adalah Functional Dependency yang valid.

Kode_MK → Nama_MK, SKS
  "Jika Kode_MK sama, maka Nama_MK dan SKS pasti sama"
  → Benar! Satu kode MK punya satu nama dan satu jumlah SKS.
  ✓ Ini adalah Functional Dependency yang valid.

Nama → NIM
  "Jika Nama sama, maka NIM pasti sama"
  → TIDAK BENAR! Ada mahasiswa bernama sama tapi NIM berbeda.
  ✗ Bukan Functional Dependency yang valid.

INGAT: FD bukan tentang nilai spesifik dalam data saat ini.
FD adalah tentang ATURAN SEMANTIK BISNIS yang harus selalu berlaku.

C.3.2 Cara Mengidentifikasi Functional Dependency

Langkah-langkah mengidentifikasi FD dari sebuah relasi:

LANGKAH 1: Tentukan semua atribut dalam relasi

LANGKAH 2: Untuk setiap pasang (atau grup) atribut, tanyakan:
  "Apakah mengetahui nilai [A] sudah cukup untuk menentukan nilai [B]?"
  "Bisakah dua baris memiliki nilai [A] yang sama tetapi [B] yang berbeda?"

LANGKAH 3: Identifikasi PK (sumber semua FD yang "kuat")

LANGKAH 4: Cari FD yang melibatkan kolom non-kunci → ini kandidat masalah normalisasi

CONTOH — Relasi: FAKTUR(no_faktur, tgl_faktur, id_pembeli, nama_pembeli, 
                               kota_pembeli, kode_buku, judul_buku, harga, qty, subtotal)

IDENTIFIKASI FD:

Dari no_faktur:
  no_faktur → tgl_faktur        ✓ (satu faktur punya satu tanggal)
  no_faktur → id_pembeli        ✓ (satu faktur dibuat oleh satu pembeli)
  no_faktur, kode_buku → qty    ✓ (dalam faktur tertentu, qty item tertentu sudah pasti)

Dari id_pembeli:
  id_pembeli → nama_pembeli     ✓ (satu ID pembeli punya satu nama)
  id_pembeli → kota_pembeli     ✓ (satu ID pembeli punya satu kota)

Dari kode_buku:
  kode_buku → judul_buku        ✓ (satu kode buku punya satu judul)
  kode_buku → harga             ✓ (satu buku punya satu harga)

Derived:
  no_faktur, kode_buku → subtotal  ✓ (subtotal = qty × harga, diturunkan)

PK dari relasi ini:
  (no_faktur, kode_buku) — karena satu faktur bisa berisi banyak buku,
  dan kita perlu tahu faktur mana + buku mana untuk mengidentifikasi satu baris.

C.3.3 Jenis-Jenis Functional Dependency

Ada tiga jenis FD yang kritis untuk normalisasi:

1. Full Functional Dependency (FD Penuh)

DEFINISI: B fully functionally dependent pada A jika B bergantung pada 
SELURUH A, dan tidak bisa bergantung hanya pada bagian dari A.

Notasi: A → B (dimana A adalah PK komposit dan B tidak bisa ditentukan 
oleh subset manapun dari A)

CONTOH — dalam FAKTUR(no_faktur, kode_buku, qty):
  {no_faktur, kode_buku} → qty
  
  Apakah qty bisa ditentukan oleh no_faktur saja? TIDAK
  (satu faktur bisa punya banyak item dengan qty berbeda)
  
  Apakah qty bisa ditentukan oleh kode_buku saja? TIDAK
  (satu buku muncul di banyak faktur dengan qty berbeda)
  
  → qty fully functionally dependent pada {no_faktur, kode_buku} ✓

2. Partial Dependency (Ketergantungan Parsial)

DEFINISI: B partially dependent pada A jika B bergantung hanya pada 
SEBAGIAN dari A (dimana A adalah PK komposit).

Ini adalah MASALAH yang harus diselesaikan oleh 2NF.

CONTOH — dalam FAKTUR(no_faktur, kode_buku, nama_pembeli, judul_buku, qty):
  PK: {no_faktur, kode_buku}
  
  no_faktur → nama_pembeli
  (nama_pembeli hanya bergantung pada no_faktur, bukan pada kombinasi keduanya!)
  → nama_pembeli PARTIALLY DEPENDENT pada PK ← MASALAH!
  
  kode_buku → judul_buku
  (judul_buku hanya bergantung pada kode_buku, bukan pada kombinasi keduanya!)
  → judul_buku PARTIALLY DEPENDENT pada PK ← MASALAH!
  
  {no_faktur, kode_buku} → qty
  (qty bergantung pada keduanya, tidak bisa hanya satu)
  → qty FULLY DEPENDENT pada PK ✓

3. Transitive Dependency (Ketergantungan Transitif)

DEFINISI: C transitively dependent pada A jika:
  A → B dan B → C, sehingga A → C (melalui perantara B)
  dan B bukan merupakan candidate key dari relasi tersebut.

Ini adalah MASALAH yang harus diselesaikan oleh 3NF.

CONTOH — dalam KARYAWAN(emp_id, nama, dept_id, nama_dept, lokasi_dept):
  PK: emp_id
  
  emp_id → dept_id        ✓ (karyawan punya satu departemen)
  dept_id → nama_dept     ✓ (departemen punya satu nama)
  dept_id → lokasi_dept   ✓ (departemen punya satu lokasi)
  
  Sehingga: emp_id → dept_id → nama_dept
  
  nama_dept TRANSITIVELY DEPENDENT pada emp_id (melalui dept_id) ← MASALAH!
  
  Kita bisa menentukan nama_dept dari emp_id, tapi HANYA melalui perantara dept_id.
  dept_id bukanlah candidate key → ini adalah transitive dependency.

C.3.4 Visualisasi Ketiga Jenis Dependency

RINGKASAN VISUAL:

FULL FD (baik, tidak ada masalah):
  {A, B} ──────────────────→ C
   PK komposit               Non-key attr

PARTIAL DEPENDENCY (masalah 2NF):
  A ──────────────────────→ C   ← C hanya bergantung pada A!
  │                              Bukan pada seluruh {A, B}
  {A, B}
  │
  B ──────────────────────→ D   ← D hanya bergantung pada B!

TRANSITIVE DEPENDENCY (masalah 3NF):
  A ──────────→ B ──────────→ C
  PK           Non-key attr   Non-key attr
               (mediator)
               ↑
               Ini bukan candidate key!
               Itulah masalahnya.

C.4 Materi 3: First Normal Form (1NF)

C.4.1 Definisi dan Syarat 1NF

Sebuah relasi memenuhi First Normal Form (1NF) jika:

  1. Semua atribut memiliki nilai atomik (tidak bisa dibagi lagi, single value)
  2. Tidak ada repeating groups (kelompok kolom berulang)
  3. Tidak ada multivalued attribute (setiap sel berisi tepat satu nilai)
  4. Semua baris unik (ada primary key)
PELANGGARAN 1NF — CONTOH 1: Multivalued dalam Satu Sel

SEBELUM 1NF (pelanggaran: nomor_hp berisi banyak nilai):
  | mahasiswa_id | nama  | nomor_hp                    |
  |--------------|-------|-----------------------------|
  | M001         | Andi  | 081234, 085678, 089012      | ← PELANGGARAN!
  | M002         | Budi  | 087654                      |

SETELAH 1NF:
  MAHASISWA:
  | mahasiswa_id | nama  |
  |--------------|-------|
  | M001         | Andi  |
  | M002         | Budi  |

  MAHASISWA_HP:
  | mahasiswa_id | nomor_hp |
  |--------------|----------|
  | M001         | 081234   |
  | M001         | 085678   |
  | M001         | 089012   |
  | M002         | 087654   |

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

PELANGGARAN 1NF — CONTOH 2: Repeating Groups (Kolom Berulang)

SEBELUM 1NF (repeating groups: buku1, buku2, buku3, ...):
  | id_peminjam | nama  | buku1     | tgl_pinjam1 | buku2          | tgl_pinjam2 |
  |-------------|-------|-----------|-------------|----------------|-------------|
  | P001        | Andi  | Belajar R | 2025-01-10  | Data Mining    | 2025-01-10  |
  | P002        | Budi  | Python 3  | 2025-01-11  | NULL           | NULL        |

MASALAH:
  - Jika seseorang meminjam 4 buku, harus tambah 2 kolom lagi
  - NULL yang tidak bermakna
  - Query yang sangat sulit

SETELAH 1NF (pisahkan ke relasi terpisah):
  PEMINJAM:
  | id_peminjam | nama  |
  |-------------|-------|
  | P001        | Andi  |
  | P002        | Budi  |

  PEMINJAMAN:
  | id_peminjam | kode_buku | tgl_pinjam  |
  |-------------|-----------|-------------|
  | P001        | BK001     | 2025-01-10  |
  | P001        | BK002     | 2025-01-10  |
  | P002        | BK003     | 2025-01-11  |

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

PELANGGARAN 1NF — CONTOH 3: Nilai Komposit (Non-Atomik)

SEBELUM 1NF (alamat disimpan satu kolom, tidak atomik):
  | pelanggan_id | nama | alamat_lengkap                           |
  |--------------|------|------------------------------------------|
  | CUS001       | Ani  | Jl. Merdeka No.5, Podosugih, Pekalongan  |

  MASALAH: Tidak bisa filter berdasarkan kota, tidak bisa sort berdasarkan kecamatan

SETELAH 1NF:
  | pelanggan_id | nama | jalan          | kelurahan | kota       |
  |--------------|------|----------------|-----------|------------|
  | CUS001       | Ani  | Jl. Merdeka 5  | Podosugih | Pekalongan |

C.4.2 Apakah Semua Nilai Harus Dipecah?

PERTANYAAN PENTING: Seberapa jauh harus dipecah?

JAWABAN: Bergantung pada kebutuhan bisnis (use case)

CONTOH — Nama Lengkap:
  "Ahmad Fauzi Santoso"
  → Jika hanya ditampilkan: BOLEH satu kolom (nama_lengkap)
  → Jika perlu sort by nama belakang: HARUS pisah (nama_depan, nama_belakang)
  → Jika perlu greeting formal: HARUS pisah (gelar, nama_depan, nama_belakang)

PRINSIP: Setiap atribut harus atomik dari sudut pandang OPERASI BISNIS 
yang akan dilakukan, bukan atomik secara absolut.

C.5 Materi 4: Second Normal Form (2NF)

C.5.1 Definisi dan Syarat 2NF

Sebuah relasi memenuhi Second Normal Form (2NF) jika:

  1. Sudah dalam 1NF, DAN
  2. Setiap atribut non-kunci fully functionally dependent pada seluruh primary key (tidak ada partial dependency)

Catatan Penting: 2NF hanya relevan jika tabelnya memiliki PK komposit. Tabel dengan single-column PK yang sudah 1NF otomatis juga 2NF (tidak mungkin ada partial dependency).

C.5.2 Langkah Mencapai 2NF

ALGORITMA MENCAPAI 2NF:

1. Identifikasi semua partial dependency
   (atribut non-kunci yang hanya bergantung pada SEBAGIAN PK komposit)

2. Untuk setiap partial dependency A → B (dimana A adalah bagian dari PK):
   a. Hapus kolom B dari tabel asli
   b. Buat tabel baru dengan A sebagai PK dan B sebagai atributnya

3. Tabel asli hanya menyimpan atribut yang fully dependent pada seluruh PK

C.5.3 Contoh Penerapan 2NF

TABEL AWAL (sudah 1NF, belum 2NF):

DETAIL_PESANAN(no_pesanan, kode_produk, nama_produk, harga_satuan,
               nama_pembeli, kota_pembeli, qty, subtotal)
               
PK: {no_pesanan, kode_produk}

IDENTIFIKASI FD:
  {no_pesanan, kode_produk} → qty             ← FULL FD ✓
  {no_pesanan, kode_produk} → subtotal        ← FULL FD ✓ (tapi derived)
  no_pesanan → nama_pembeli                   ← PARTIAL DEPENDENCY ✗
  no_pesanan → kota_pembeli                   ← PARTIAL DEPENDENCY ✗
  kode_produk → nama_produk                   ← PARTIAL DEPENDENCY ✗
  kode_produk → harga_satuan                  ← PARTIAL DEPENDENCY ✗

DIAGRAM DEPENDENCY:

  no_pesanan ──â”Ŧ──→ nama_pembeli    ← PARTIAL (masalah!)
               └──→ kota_pembeli    ← PARTIAL (masalah!)

  kode_produk ─â”Ŧ──→ nama_produk     ← PARTIAL (masalah!)
               └──→ harga_satuan    ← PARTIAL (masalah!)

  {no_pesanan, kode_produk} ──→ qty ← FULL ✓
                             ──→ subtotal ← FULL ✓

PROSES DEKOMPOSISI ke 2NF:

LANGKAH 1: Pisahkan setiap kelompok partial dependency menjadi tabel baru

  Dari partial dependency no_pesanan → {nama_pembeli, kota_pembeli}:
  → Buat tabel: PESANAN(no_pesanan, nama_pembeli, kota_pembeli)
                         ^^^^^^^^^^
                         PK

  Dari partial dependency kode_produk → {nama_produk, harga_satuan}:
  → Buat tabel: PRODUK(kode_produk, nama_produk, harga_satuan)
                        ^^^^^^^^^^^
                        PK

LANGKAH 2: Tabel asli hanya simpan atribut yang fully dependent

  DETAIL_PESANAN(no_pesanan*, kode_produk*, qty)
                  ^^^^^^^^^^  ^^^^^^^^^^^
                  PK komposit (keduanya FK juga)

LANGKAH 3: Hapus derived attribute (subtotal = qty × harga, tidak perlu disimpan)

HASIL AKHIR (sudah 2NF):

  PESANAN(no_pesanan, nama_pembeli, kota_pembeli)
           ^^^^^^^^^^
           PK

  PRODUK(kode_produk, nama_produk, harga_satuan)
          ^^^^^^^^^^^
          PK

  DETAIL_PESANAN(no_pesanan*, kode_produk*, qty)
                  ^^^^^^^^^^  ^^^^^^^^^^^
                  PK: {no_pesanan, kode_produk}
                  no_pesanan → FK ke PESANAN
                  kode_produk → FK ke PRODUK

VERIFIKASI: Tidak ada lagi partial dependency di ketiga tabel.
Semua atribut non-kunci fully dependent pada PK masing-masing. ✓

C.5.4 Mengapa 2NF Menyelesaikan Sebagian Anomali?

TABEL SEBELUM 2NF: DETAIL_PESANAN(no_pesanan, kode_produk, nama_produk,
                                   harga_satuan, nama_pembeli, qty)

Update Anomaly: 
  Ubah nama produk kode PRD01 → harus update N baris ✗

Insertion Anomaly:
  Tidak bisa simpan produk baru sebelum ada pesanan ✗

Deletion Anomaly:
  Hapus pesanan terakhir yang berisi PRD01 → data produk hilang ✗

SETELAH 2NF:
  Tabel PRODUK terpisah:
  Update nama produk → hanya 1 baris di PRODUK ✓
  Insert produk baru tanpa pesanan → bisa, cukup insert ke PRODUK ✓
  Hapus semua pesanan → data produk di tabel PRODUK tetap ada ✓

TAPI masih ada masalah lain (transitive dependency) → itulah tugas 3NF!

C.6 Materi 5: Third Normal Form (3NF)

C.6.1 Definisi dan Syarat 3NF

Sebuah relasi memenuhi Third Normal Form (3NF) jika:

  1. Sudah dalam 2NF, DAN
  2. Tidak ada atribut non-kunci yang transitively dependent pada primary key

Dengan kata lain: setiap atribut non-kunci harus bergantung langsung pada PK — bukan pada atribut non-kunci lainnya.

Cara cepat mengidentifikasi pelanggaran 3NF: Jika ada atribut non-kunci A yang menentukan atribut non-kunci B (A → B), maka B transitively dependent pada PK (melalui A). Ini adalah pelanggaran 3NF.

C.6.2 Langkah Mencapai 3NF

ALGORITMA MENCAPAI 3NF:

1. Identifikasi semua transitive dependency
   (atribut non-kunci yang bergantung pada atribut non-kunci lain, bukan pada PK)
   Ciri: Ada FD: X → Y dimana X bukan PK (X hanya atribut non-kunci/FK)

2. Untuk setiap transitive dependency X → Y:
   a. Hapus kolom Y dari tabel asli
   b. Buat tabel baru dengan X sebagai PK dan Y sebagai atributnya
   c. X tetap ada di tabel asli (sebagai FK ke tabel baru)

3. Tabel asli hanya menyimpan atribut yang langsung bergantung pada PK

C.6.3 Contoh Penerapan 3NF

TABEL AWAL (sudah 2NF, belum 3NF):

KARYAWAN(emp_id, nama, jabatan_id, nama_jabatan, gaji_pokok, dept_id, nama_dept, lokasi_dept)
          ^^^^^^
          PK

IDENTIFIKASI FD:
  emp_id → nama              ✓ direct dependency pada PK
  emp_id → jabatan_id        ✓ direct dependency pada PK
  emp_id → gaji_pokok        ✓ direct dependency pada PK
  emp_id → dept_id           ✓ direct dependency pada PK

  jabatan_id → nama_jabatan  ← TRANSITIVE! (jabatan_id bukan PK)
  dept_id → nama_dept        ← TRANSITIVE! (dept_id bukan PK)
  dept_id → lokasi_dept      ← TRANSITIVE! (dept_id bukan PK)

  Rantai ketergantungan:
  emp_id → jabatan_id → nama_jabatan  ← transitive dependency ✗
  emp_id → dept_id → nama_dept        ← transitive dependency ✗
  emp_id → dept_id → lokasi_dept      ← transitive dependency ✗

PROSES DEKOMPOSISI ke 3NF:

LANGKAH 1: Pisahkan transitive dependency jabatan_id → nama_jabatan

  → Buat tabel: JABATAN(jabatan_id, nama_jabatan)
                         ^^^^^^^^^^^
                         PK

LANGKAH 2: Pisahkan transitive dependency dept_id → {nama_dept, lokasi_dept}

  → Buat tabel: DEPARTEMEN(dept_id, nama_dept, lokasi_dept)
                             ^^^^^^^
                             PK

LANGKAH 3: Tabel KARYAWAN hanya simpan atribut yang langsung bergantung pada emp_id

  KARYAWAN(emp_id, nama, jabatan_id*, gaji_pokok, dept_id*)
            ^^^^^^                                ^^^^^^^
            PK        jabatan_id → FK ke JABATAN
                      dept_id → FK ke DEPARTEMEN

HASIL AKHIR (sudah 3NF):

  JABATAN(jabatan_id, nama_jabatan)
           ^^^^^^^^^^^
           PK

  DEPARTEMEN(dept_id, nama_dept, lokasi_dept)
              ^^^^^^^
              PK

  KARYAWAN(emp_id, nama, jabatan_id*, gaji_pokok, dept_id*)
            ^^^^^^
            PK

VERIFIKASI 3NF:
  JABATAN: emp_id? Tidak ada. nama_jabatan bergantung langsung pada jabatan_id ✓
  DEPARTEMEN: nama_dept bergantung langsung pada dept_id ✓
  KARYAWAN: nama, jabatan_id, gaji_pokok, dept_id semua bergantung langsung pada emp_id ✓
  Tidak ada lagi transitive dependency! ✓

C.6.4 Contoh Lengkap End-to-End: 0NF → 1NF → 2NF → 3NF

Kita akan transformasi satu tabel dari bentuk tidak normal (0NF) secara bertahap hingga 3NF, menggunakan domain sistem akademik sederhana.

TABEL AWAL (0NF / Un-normalized Form):

NILAI_MAHASISWA(nim, nama_mahasiswa, kode_mk, nama_mk, sks, kode_prodi, nama_prodi,
                nilai_huruf, nilai_angka, semester, tahun)

Contoh Data:
| nim        | nama_mhs   | kode_mk | nama_mk         | sks | kode_prodi | nama_prodi | nilai_huruf | nilai_angka | smt    | thn  |
|------------|------------|---------|-----------------|-----|------------|------------|------------|------------|--------|------|
| 2021001001 | Andi       | SSD1019 | Data Modelling  | 3   | SSD        | Sains Data | A          | 4.0        | Ganjil | 2025 |
| 2021001001 | Andi       | SSD2034 | Machine Learning| 3   | SSD        | Sains Data | B+         | 3.5        | Ganjil | 2025 |
| 2021001002 | Budi       | SSD1019 | Data Modelling  | 3   | SSD        | Sains Data | B          | 3.0        | Ganjil | 2025 |
| 2021001002 | Budi       | SSD3001 | Data Warehouse  | 3   | SSD        | Sains Data | A-         | 3.7        | Genap  | 2025 |

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

STEP 1: CEK 1NF
  - Apakah ada multivalued dalam satu sel? TIDAK ✓
  - Apakah ada repeating groups? TIDAK ✓
  - Apakah semua nilai atomik? YA ✓
  - PK yang logis: {nim, kode_mk, semester, tahun}
  
  → Tabel sudah 1NF ✓

STEP 2: CEK 2NF
  PK: {nim, kode_mk, semester, tahun}
  
  Identifikasi FD:
  nim → nama_mahasiswa              ← PARTIAL! (hanya bergantung pada nim)
  nim → kode_prodi                  ← PARTIAL! (hanya bergantung pada nim)
  kode_mk → nama_mk                 ← PARTIAL! (hanya bergantung pada kode_mk)
  kode_mk → sks                     ← PARTIAL! (hanya bergantung pada kode_mk)
  
  {nim, kode_mk, semester, tahun} → nilai_huruf  ← FULL ✓
  {nim, kode_mk, semester, tahun} → nilai_angka  ← FULL ✓
  
  → Tabel BELUM 2NF! Ada partial dependency.

DEKOMPOSISI ke 2NF:

  Dari nim → {nama_mahasiswa, kode_prodi}:
  MAHASISWA_2NF(nim, nama_mahasiswa, kode_prodi)

  Dari kode_mk → {nama_mk, sks}:
  MATA_KULIAH_2NF(kode_mk, nama_mk, sks)

  Tabel utama (hanya fully dependent):
  NILAI_2NF(nim*, kode_mk*, semester, tahun, nilai_huruf, nilai_angka)
  PK: {nim, kode_mk, semester, tahun}

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

STEP 3: CEK 3NF
  Periksa ketiga tabel hasil 2NF:

  MAHASISWA_2NF(nim, nama_mahasiswa, kode_prodi):
    nim → nama_mahasiswa   ← direct, OK ✓
    nim → kode_prodi       ← direct, OK ✓
    kode_prodi → nama_prodi? — TUNGGU! nama_prodi TIDAK ADA di tabel ini!
                              Kita sudah memisahkannya? Belum! Periksa lagi...
    
    Dari tabel 2NF ini: kode_prodi → nama_prodi tidak terlihat karena nama_prodi
    tidak ada di tabel ini. Ini karena sudah terpisah. ✓
    
    TAPI: Hati-hati — ada transitive dependency yang TERSEMBUNYI:
    nim → kode_prodi, dan kode_prodi harusnya → nama_prodi
    Tapi nama_prodi tidak ada di tabel ini (sudah benar!).
    
    Hmm, tapi seharusnya kita juga butuh nama_prodi... Mari kita periksa
    tabel mana yang menyimpannya. Ternyata TIDAK ADA! Kita perlu tambahkan.

  REVISI: Tambahkan tabel PRODI:
  PRODI(kode_prodi, nama_prodi)
  
  MAHASISWA_2NF hanya berisi: nim, nama_mahasiswa, kode_prodi
  (kode_prodi adalah FK ke PRODI)

  MATA_KULIAH_2NF(kode_mk, nama_mk, sks):
    kode_mk → nama_mk   ← direct, OK ✓
    kode_mk → sks       ← direct, OK ✓
    Tidak ada transitive dependency → sudah 3NF ✓

  NILAI_2NF(nim*, kode_mk*, semester, tahun, nilai_huruf, nilai_angka):
    {nim, kode_mk, semester, tahun} → nilai_huruf  ← direct ✓
    {nim, kode_mk, semester, tahun} → nilai_angka  ← direct ✓
    nilai_huruf → nilai_angka? 
    
    PERIKSA: A → B+, A- → ... ada pola? YA!
    nilai_huruf → nilai_angka (A = 4.0, B+ = 3.5, dst.)
    ini adalah TRANSITIVE DEPENDENCY! nilai_angka bergantung pada nilai_huruf,
    bukan langsung pada PK.
    
    → PERLU DEKOMPOSISI ke 3NF!

  Dari nilai_huruf → nilai_angka:
  KONVERSI_NILAI(nilai_huruf, nilai_angka)
                 ^^^^^^^^^^^^
                 PK

  NILAI_2NF direvisi → NILAI_3NF:
  NILAI(nim*, kode_mk*, semester, tahun, nilai_huruf, nilai_angka)
  PK: {nim, kode_mk, semester, tahun}
  nilai_huruf → FK ke KONVERSI_NILAI

HASIL AKHIR (semua tabel dalam 3NF):

  PRODI(kode_prodi, nama_prodi)
    - PK: kode_prodi

  MAHASISWA(nim, nama_mahasiswa, kode_prodi)
    - PK: nim
    - FK: kode_prodi → PRODI(kode_prodi)

  MATA_KULIAH(kode_mk, nama_mk, sks)
    - PK: kode_mk

  KONVERSI_NILAI(nilai_huruf, nilai_angka)
    - PK: nilai_huruf

  NILAI(nim, kode_mk, semester, tahun, nilai_huruf)
    - PK: {nim, kode_mk, semester, tahun}
    - FK: nim → MAHASISWA(nim), kode_mk → MATA_KULIAH(kode_mk), nilai_huruf → KONVERSI_NILAI(nilai_huruf)

TOTAL: 5 tabel dari 1 tabel un-normalized

C.7 Ringkasan: Tiga Normal Form dalam Satu Pandangan

╔════════════════════════════════════════════════════════════════════╗
║            RINGKASAN: 1NF, 2NF, 3NF                               ║
╠═══════════â•Ļ════════════════════════â•Ļâ•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•Ŗ
║ NF        ║ SYARAT                 ║ MASALAH YANG DISELESAIKAN     ║
╠═══════════â•Ŧ════════════════════════â•Ŧâ•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•Ŗ
║ 1NF       ║ â€ĸ Nilai atomik         ║ â€ĸ Multivalued attribute       ║
║           ║ â€ĸ Tidak ada repeating  ║ â€ĸ Repeating groups            ║
║           ║   groups               ║ â€ĸ Nilai non-atomik            ║
║           ║ â€ĸ PK ada               ║                               ║
╠═══════════â•Ŧ════════════════════════â•Ŧâ•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•Ŗ
║ 2NF       ║ â€ĸ Sudah 1NF            ║ â€ĸ Partial dependency pada     ║
║           ║ â€ĸ Tidak ada partial    ║   PK komposit                 ║
║           ║   dependency           ║ â€ĸ Redundansi akibat           ║
║           ║ (hanya relevan jika    ║   atribut yang "nebeng"       ║
║           ║  PK komposit)          ║   di tabel yang salah         ║
╠═══════════â•Ŧ════════════════════════â•Ŧâ•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•Ŗ
║ 3NF       ║ â€ĸ Sudah 2NF            ║ â€ĸ Transitive dependency       ║
║           ║ â€ĸ Tidak ada transitive ║ â€ĸ Atribut non-kunci yang      ║
║           ║   dependency           ║   menentukan atribut non-kunci║
║           ║                        ║   lainnya                     ║
╠═══════════â•Ŧ════════════════════════â•Ŧâ•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•Ŗ
║ ANALOGI   ║ 1NF: Setiap sel        ║                               ║
║           ║      berisi SATU nilai  ║                               ║
║           ║                        ║                               ║
║           ║ 2NF: Setiap atribut    ║                               ║
║           ║      bergantung pada   ║                               ║
║           ║      SELURUH PK        ║                               ║
║           ║                        ║                               ║
║           ║ 3NF: Setiap atribut    ║                               ║
║           ║      bergantung HANYA  ║                               ║
║           ║      pada PK, bukan    ║                               ║
║           ║      atribut lain      ║                               ║
╚═══════════╩════════════════════════╩═══════════════════════════════╝

CARA MUDAH MENGINGAT (Parafrase dari William Kent, 1983):
  "Every non-key attribute must depend on the key,
   the whole key, and nothing but the key."
   
  → "the key" = 1NF (ada PK)
  → "the whole key" = 2NF (full dependency, bukan partial)
  → "nothing but the key" = 3NF (tidak ada transitive)

C.8 Studi Kasus: Normalisasi Sistem Pemesanan Hotel

C.8.1 Tabel Un-normalized

PEMESANAN_HOTEL (tabel mentah dari Excel staff hotel):

| id_booking | tgl_booking | nama_tamu   | email_tamu          | no_telp_tamu | id_kamar | tipe_kamar | harga_malam | jml_malam | total_biaya | nama_hotel      | kota_hotel | fasilitas_kamar        |
|------------|-------------|-------------|---------------------|--------------|----------|------------|-------------|-----------|-------------|-----------------|------------|------------------------|
| BK001      | 2025-01-10  | Andi W      | andi@email.com      | 081234567890 | K101     | Deluxe     | 500000      | 3         | 1500000     | Hotel Santika   | Semarang   | AC, WiFi, TV, Kolam    |
| BK002      | 2025-01-11  | Budi S      | budi@email.com      | 087654321098 | K205     | Suite      | 1200000     | 2         | 2400000     | Hotel Santika   | Semarang   | AC, WiFi, TV, Jacuzzi  |
| BK003      | 2025-01-12  | Andi W      | andi@email.com      | 081234567890 | K101     | Deluxe     | 500000      | 1         | 500000      | Hotel Santika   | Semarang   | AC, WiFi, TV, Kolam    |
| BK004      | 2025-01-15  | Citra D     | citra@email.com     | 089012345678 | K101     | Deluxe     | 500000      | 2         | 1000000     | Hotel Mutiara   | Pekalongan | AC, WiFi, TV           |

C.8.2 Langkah 1: Identifikasi Masalah

ANOMALI YANG ADA:

Update Anomaly: Harga kamar K101 naik → update banyak baris
  BK001 (harga: 500000) + BK003 (harga: 500000) + BK004 (harga: 500000)

Insertion Anomaly: Tidak bisa daftarkan tamu baru tanpa booking
  Tidak bisa simpan data Andi W jika belum pesan kamar

Deletion Anomaly: Hapus BK002 → kehilangan info kamar K205 dan Suite

Masalah Multivalued: Kolom fasilitas_kamar berisi banyak nilai! 
  "AC, WiFi, TV, Kolam" = 4 nilai dalam 1 sel → pelanggaran 1NF

C.8.3 Langkah 2: Normalisasi ke 1NF

CEK 1NF:
  Pelanggaran: fasilitas_kamar berisi lebih dari 1 nilai per sel.

TINDAKAN:
  - Pisahkan fasilitas_kamar menjadi tabel tersendiri
  - Tentukan PK yang tepat: {id_booking, id_kamar} → tunggu, lihat lagi...
    → satu booking sudah pasti untuk satu kamar, jadi PK: id_booking saja?
    → Tidak! Tabel ini mencakup info level booking DAN level kamar.
    → Untuk saat ini, PK sementara: id_booking (karena satu booking = satu kamar)

TABEL SETELAH 1NF:

PEMESANAN_1NF(id_booking, tgl_booking, nama_tamu, email_tamu, no_telp_tamu,
              id_kamar, tipe_kamar, harga_malam, jml_malam, total_biaya,
              nama_hotel, kota_hotel)
PK: id_booking

KAMAR_FASILITAS(id_kamar, fasilitas)  ← pisahkan multivalued
PK: {id_kamar, fasilitas}

| id_kamar | fasilitas |
|----------|-----------|
| K101     | AC        |
| K101     | WiFi      |
| K101     | TV        |
| K101     | Kolam     |
| K205     | AC        |
| K205     | WiFi      |
| K205     | TV        |
| K205     | Jacuzzi   |

C.8.4 Langkah 3: Normalisasi ke 2NF

CEK 2NF pada PEMESANAN_1NF:
  PK: id_booking (single column → otomatis 2NF? Cek dulu FD-nya...)
  
  Meski PK single-column, kita perlu cek apakah ada FD internal yang bermasalah:
  
  id_booking → tgl_booking, nama_tamu, email_tamu, no_telp_tamu, id_kamar ✓
  id_booking → jml_malam, total_biaya ✓
  
  id_kamar → tipe_kamar     ← id_kamar bukan PK, tapi menentukan non-key atribut lain
  id_kamar → harga_malam    ← sama, ini bukan 2NF tapi masalah 3NF (transitive)
  id_kamar → nama_hotel     ← transitive dependency via id_kamar
  id_kamar → kota_hotel     ← transitive dependency via id_kamar
  
  email_tamu → nama_tamu    ← email unik per tamu (transitive via email)
  email_tamu → no_telp_tamu ← transitive via email

  PK adalah single column → tidak ada partial dependency → sudah 2NF ✓
  (Masalah yang ada adalah transitive dependency → tangani di 3NF)

CEK 2NF pada KAMAR_FASILITAS:
  PK: {id_kamar, fasilitas} (komposit)
  Tidak ada atribut non-kunci lain → tidak mungkin partial/transitive → sudah 3NF ✓

C.8.5 Langkah 4: Normalisasi ke 3NF

CEK 3NF pada PEMESANAN_1NF:

Transitive dependencies yang ditemukan:

  id_booking → email_tamu → nama_tamu     ← TRANSITIVE ✗
  id_booking → email_tamu → no_telp_tamu  ← TRANSITIVE ✗
  id_booking → id_kamar → tipe_kamar      ← TRANSITIVE ✗
  id_booking → id_kamar → harga_malam     ← TRANSITIVE ✗
  id_booking → id_kamar → nama_hotel      ← TRANSITIVE ✗
  id_booking → id_kamar → kota_hotel      ← TRANSITIVE ✗

DEKOMPOSISI ke 3NF:

Dari email_tamu → {nama_tamu, no_telp_tamu}:
  → Buat tabel: TAMU(email_tamu, nama_tamu, no_telp_tamu)
                     ^^^^^^^^^^
                     PK

Dari id_kamar → {tipe_kamar, harga_malam, nama_hotel, kota_hotel}:
  → Buat tabel: KAMAR(id_kamar, tipe_kamar, harga_malam, nama_hotel, kota_hotel)
                       ^^^^^^^^
                       PK

Tabel PEMESANAN bersih (hanya atribut yang langsung bergantung pada id_booking):
  PEMESANAN(id_booking, tgl_booking, email_tamu*, id_kamar*, jml_malam, total_biaya)
             ^^^^^^^^^^
             PK

HASIL AKHIR (3NF):

  TAMU(email_tamu, nama_tamu, no_telp_tamu)
       ^^^^^^^^^^

  KAMAR(id_kamar, tipe_kamar, harga_malam, nama_hotel, kota_hotel)
         ^^^^^^^^

  PEMESANAN(id_booking, tgl_booking, email_tamu*, id_kamar*, jml_malam)
             ^^^^^^^^^^
             (total_biaya dihapus — derived dari harga_malam × jml_malam)

  KAMAR_FASILITAS(id_kamar*, fasilitas)
                   PK: {id_kamar, fasilitas}

Total: 4 tabel dari 1 tabel mentah. Semua anomali telah teratasi!

VERIFIKASI AKHIR:
  Update harga kamar → update 1 baris di KAMAR ✓
  Insert tamu baru tanpa booking → bisa (insert ke TAMU) ✓
  Hapus semua booking → data TAMU dan KAMAR tetap ada ✓
  Tambah fasilitas kamar baru → insert ke KAMAR_FASILITAS ✓

D. PRAKTIKUM TERBIMBING

D.1 Latihan 1: Identifikasi Anomali dan FD (Berpasangan, 10 menit)

Perhatikan tabel berikut dan jawab pertanyaan di bawahnya:

Tabel: PENDAFTARAN_KURSUS

id_pendaftarannama_pesertaemail_pesertakota_pesertakode_kursusnama_kursusnama_instrukturbiayastatus_bayar
REG001Siti Rahmasiti@mail.comSemarangKRS-01Python DasarPak Hendra500000Lunas
REG002Andi Wijayaandi@mail.comPekalonganKRS-01Python DasarPak Hendra500000Belum
REG003Siti Rahmasiti@mail.comJakartaKRS-02Machine LearningBu Dewi750000Lunas
REG004Budi Santosobudi@mail.comSemarangKRS-01Python DasarPak Hendra500000Lunas

Pertanyaan:

  1. Identifikasi anomali (berikan contoh konkret dari tabel di atas):

    • Update Anomaly: ___________________________________________________
    • Insertion Anomaly: _________________________________________________
    • Deletion Anomaly: __________________________________________________
  2. Identifikasi semua Functional Dependency yang berlaku: (Petunjuk: Pikirkan nilai mana yang "menentukan" nilai lainnya berdasarkan aturan bisnis)

    _____ → nama_kursus _____ → nama_instruktur _____ → biaya _____ → nama_peserta _____ → kota_peserta _____ → status_bayar

  3. Tentukan PK yang tepat untuk tabel ini dan jelaskan alasannya: PK: _______________ Alasan: _________________________________________

  4. Apakah ada partial dependency? Jika ya, sebutkan!

  5. Apakah ada transitive dependency? Jika ya, sebutkan!


D.2 Praktikum: Normalisasi End-to-End (Individual, 20 menit)

Instruksi: Normalisasikan tabel berikut secara bertahap dari 0NF hingga 3NF. Dokumentasikan setiap langkah (cek kondisi, identifikasi masalah, tindakan dekomposisi, hasil).


Tabel: LAPORAN_PENJUALAN (dari sistem toko elektronik)

id_transaksitgl_transaksiid_kasirnama_kasirshift_kasirid_pelanggannama_pelangganno_telp_pelanggankode_barangnama_barangkategori_barangharga_jualqtydiskon_pcttotal_item
TR0012025-01-10KSR01HendraPagiPLG001Andi W08123ELK001Laptop ASUSLaptop80000001107200000
TR0012025-01-10KSR01HendraPagiPLG001Andi W08123ELK005Mouse LogitechAksesoris15000020300000
TR0022025-01-11KSR02SitiSiangPLG002Budi S08765ELK001Laptop ASUSLaptop8000000157600000
TR0032025-01-12KSR01HendraMalamPLG001Andi W08123ELK010Printer CanonPrinter2500000102500000

Panduan Pengerjaan:

LANGKAH 1: Cek 1NF
  - Apakah ada multivalued attribute? _______
  - Apakah ada repeating groups? _______
  - Tentukan PK: _______
  - Apakah sudah 1NF? _______
  - Jika belum: dekomposisi

LANGKAH 2: Cek 2NF
  - PK adalah: _______  (single/komposit?)
  - Jika komposit, identifikasi semua FD:
    ___ → ___   (full/partial?)
    ___ → ___   (full/partial?)
    ...
  - Apakah ada partial dependency? _______
  - Jika ada: dekomposisi

LANGKAH 3: Cek 3NF
  - Untuk setiap tabel hasil 2NF, cek transitive dependency:
    ___ → ___ → ___   (transitive?)
    ...
  - Jika ada: dekomposisi

LANGKAH 4: Tulis hasil akhir dalam notasi skema relasional

E. EVALUASI DAN PENILAIAN

E.1 Kuis Penutup (10 menit, bobot partisipasi)

  1. Jelaskan dengan singkat apa yang dimaksud dengan update anomaly dan berikan satu contoh konkret dari domain yang kamu pilih untuk proyek!

  2. Diberikan tabel KONTRAK(no_kontrak, kode_vendor, nama_vendor, kota_vendor, kode_item, nama_item, harga, qty) dengan PK {no_kontrak, kode_item}. Sebutkan semua partial dependency yang ada dalam tabel ini!

  3. Tabel berikut sudah 2NF: KARYAWAN(emp_id, nama, dept_id, nama_dept, gaji). Apakah tabel ini sudah 3NF? Jika tidak, identifikasi transitive dependency-nya dan lakukan dekomposisi!

  4. Mengapa tabel dengan single-column PK yang sudah 1NF otomatis juga 2NF? Jelaskan alasannya secara konseptual!

  5. Setelah normalisasi, sebuah database yang awalnya 1 tabel menjadi 6 tabel. Apa keuntungan yang diperoleh? Apa kerugian atau potensi masalah yang mungkin muncul?

E.2 Tugas Normalisasi (dikumpulkan sebelum pertemuan 7)

Judul: Normalisasi Logical Model Proyek

Konteks: Tugas ini adalah kelanjutan dari tugas mapping pertemuan 5. Mahasiswa akan mengaudit dan memperbaiki skema relasional yang sudah dibuat, memastikan semuanya memenuhi 3NF.

Ketentuan:

Bagian 1: Audit Skema Existing (analisis)

Untuk setiap tabel dalam logical model dari pertemuan 5:

  • Tuliskan semua Functional Dependency yang berlaku
  • Identifikasi apakah ada pelanggaran 1NF, 2NF, atau 3NF
  • Beri kesimpulan: tabel sudah di normal form mana?

Format tabel audit:

Nama TabelFD yang AdaPelanggaran NFKesimpulan
1NF / 2NF / 3NF / Tidak adaSudah/Belum 3NF

Bagian 2: Dekomposisi (jika ada pelanggaran)

Untuk setiap tabel yang belum 3NF:

  • Tunjukkan langkah dekomposisi secara bertahap (0NF → 1NF → 2NF → 3NF)
  • Tulis skema tabel baru yang dihasilkan

Bagian 3: Skema Final (setelah normalisasi)

  • Tulis ulang skema lengkap semua tabel dalam format notasi relasional
  • Tambahkan komentar singkat: "Tabel ini dalam 3NF karena..."
  • Bandingkan jumlah tabel sebelum dan sesudah normalisasi

Bagian 4: Reflection (setengah halaman)

  • Apakah logical model dari pertemuan 5 sudah sebagian besar 3NF, atau banyak yang perlu diubah?
  • Kesalahan desain apa yang paling sering kamu temukan dalam auditmu sendiri?
  • Bagaimana normalisasi mengubah cara kamu melihat desain tabel?

Format: PDF, minimal 4 halaman, font 11pt, margin 2.5cm Nama file: Normalisasi_[NIM]_[Nama]_[Domain].pdf Deadline: Dikumpulkan ke Ngaji UIN Gusdur sebelum jam kuliah pertemuan 7 dimulai


F. PERSIAPAN PERTEMUAN 7

F.1 Yang Akan Dipelajari

Pertemuan 7 membahas Normalisasi Lanjutan dan Evaluasi Model Data — meliputi Boyce-Codd Normal Form (BCNF), trade-off normalisasi vs performa (kapan tidak menormalisasi?), dan sesi validasi/review model data proyek semester. Ini adalah pertemuan terakhir sebelum UTS.

Topik utama pertemuan 7:

  • BCNF: versi 3NF yang lebih ketat — mengapa 3NF saja terkadang tidak cukup?
  • Trade-off normalisasi vs denormalisasi: kapan aturan boleh "dilanggar" untuk performa?
  • Validasi logical model: checklist komprehensif untuk memastikan model siap
  • Review proyek semester: sesi peer review dan umpan balik

F.2 Bacaan Wajib Sebelum Pertemuan 7

  • Elmasri & Navathe, Chapter 15: Basics of Functional Dependencies and Normalization — Bagian BCNF
  • Hoberman, Chapter 8: When NOT to Normalize

F.3 Pertanyaan Pemantik untuk Pertemuan 7

Bayangkan sebuah sistem e-commerce dengan ratusan ribu transaksi per hari. Tabel utamanya sudah 3NF dengan banyak JOIN diperlukan untuk mengambil data laporan penjualan harian.

  • Apakah kita tetap mempertahankan 3NF meskipun laporan menjadi lambat?
  • Apa alternatif yang bisa dilakukan?
  • Apa risiko "melonggarkan" normalisasi?

G. REFERENSI

G.1 Referensi Utama

  1. Elmasri, R. & Navathe, S. B. (2015). Fundamentals of Database Systems (7th Edition). Pearson. ISBN: 978-0133970777

    • Chapter 14: Basics of Functional Dependencies and Normalization for Relational Databases (bacaan utama pertemuan ini)
    • Section 14.1: Informal Design Guidelines
    • Section 14.2: Functional Dependencies
    • Section 14.3: Normal Forms Based on Primary Keys (1NF, 2NF, 3NF)
  2. Hoberman, S. (2009). Data Modeling Made Simple (2nd Edition). Technics Publications. ISBN: 978-0977140060

    • Chapter 7: Normalization — Why and How
    • Section 7.1–7.4: 1NF, 2NF, 3NF dengan contoh praktis
  3. Connolly, T. & Begg, C. (2014). Database Systems: A Practical Approach to Design, Implementation, and Management (6th Edition). Pearson.

    • Chapter 14: Normalization
    • Section 14.2–14.5: Functional Dependency, 1NF, 2NF, 3NF

G.2 Referensi Pendukung

  1. Date, C. J. (2012). Database Design and Relational Theory: Normal Forms and All That Jazz. O'Reilly Media.

    • Chapter 3: Normalization: Some Preliminaries
    • Chapter 4: First, Second, and Third Normal Forms
  2. Kent, W. (1983). "A Simple Guide to Five Normal Forms in Relational Database Theory." Communications of the ACM, 26(2), 120–125. (Makalah klasik yang memperkenalkan parafrase "the key, the whole key, nothing but the key")

G.3 Referensi Online

  1. Tutorialspoint. "DBMS — Normalization" — https://www.tutorialspoint.com/dbms/database_normalization.htm (opens in a new tab)
  2. Database Star. "Database Normalization: A Step-By-Step Guide" — https://www.databasestar.com/database-normalization/ (opens in a new tab)
  3. Guru99. "1NF, 2NF, 3NF, BCNF in Database Normalization" — https://www.guru99.com/database-normalization.html (opens in a new tab)

G.4 Video Resources

  1. Decomplexify — "Learn Database Normalization — 1NF, 2NF, 3NF, 4NF, 5NF" (YouTube — penjelasan visual terbaik)
  2. freeCodeCamp — "Database Design Course" — Bagian Normalisasi (YouTube)
  3. Khan Academy — "Relational Databases: Data Modeling" (YouTube — pengantar yang ramah pemula)

H. LAMPIRAN

Lampiran A: Lembar Kerja Praktikum Pertemuan 6


LEMBAR KERJA: NORMALISASI DATA Nama: ___________________________ NIM: _______________ Tanggal: ________________________


BAGIAN 1: Identifikasi Anomali — Tabel PENDAFTARAN_KURSUS

Jenis AnomaliContoh Konkret dari TabelDampak
Update Anomaly
Insertion Anomaly
Deletion Anomaly

BAGIAN 2: Identifikasi Functional Dependency

Tuliskan semua FD yang berlaku dalam tabel LAPORAN_PENJUALAN:

Determinant (A)Dependent (B)Jenis FDApakah Masalah?
Full / Partial / TransitiveYa / Tidak

BAGIAN 3: Proses Normalisasi Bertahap

Tabel Awal (tulis nama dan kolom):

_________________________________ (_____________________)
PK: ___________________

CEK 1NF:

  • Multivalued attribute: Ada / Tidak → ___________________________
  • Repeating groups: Ada / Tidak → _______________________________
  • Tindakan: _____________________________________________________
  • Hasil 1NF: ____________________________________________________

CEK 2NF:

  • PK tabel: __________________ (single / komposit)
  • Partial dependency: Ada / Tidak Jika ada: ___________________________________________________
  • Dekomposisi: Tabel baru 1: _______________________________________________ Tabel baru 2: _______________________________________________
  • Hasil 2NF: ___________________________________________________

CEK 3NF:

  • Transitive dependency: Ada / Tidak Jika ada: ___________________________________________________
  • Dekomposisi: Tabel baru 1: _______________________________________________ Tabel baru 2: _______________________________________________
  • Hasil 3NF: ___________________________________________________

BAGIAN 4: Skema Relasional Final

Tulis skema semua tabel hasil normalisasi:

1. _______________________________________________

2. _______________________________________________

3. _______________________________________________

4. _______________________________________________

5. _______________________________________________

Refleksi Singkat (2-3 kalimat):




Lampiran B: Panduan Cepat Identifikasi Normal Form

╔══════════════════════════════════════════════════════════════════╗
║          PANDUAN CEPAT: CEK NORMAL FORM SEBUAH TABEL            ║
â• â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•Ŗ
║                                                                  ║
║  LANGKAH 1: CEK 1NF                                             ║
║  ───────────────────                                             ║
║  Pertanyaan:                                                     ║
║  □ Ada sel yang berisi lebih dari satu nilai? → Tidak 1NF       ║
║  □ Ada kelompok kolom berulang (A1, A2, A3...)? → Tidak 1NF    ║
║  □ Sudah ada PK yang jelas? → Kalau tidak, tentukan dulu        ║
║                                                                  ║
║  Jika semua OK → Lanjut ke 2NF                                  ║
║                                                                  ║
║  LANGKAH 2: CEK 2NF                                             ║
║  ───────────────────                                             ║
║  Prasyarat: PK HARUS KOMPOSIT untuk ada risiko partial dep.     ║
║                                                                  ║
║  Pertanyaan:                                                     ║
║  □ PK-nya komposit? Jika tidak → otomatis 2NF, skip ke 3NF     ║
║  □ Ada atribut non-kunci yang bergantung hanya pada              ║
║    SEBAGIAN PK? → Partial dependency → Tidak 2NF               ║
║                                                                  ║
║  Cara cek: Untuk setiap bagian PK secara terpisah,              ║
║  tanyakan: "Apakah [bagian PK ini] saja sudah cukup             ║
║  menentukan [atribut non-kunci ini]?"                           ║
║  Jika ya → partial dependency!                                  ║
║                                                                  ║
║  Jika semua OK → Lanjut ke 3NF                                  ║
║                                                                  ║
║  LANGKAH 3: CEK 3NF                                             ║
║  ───────────────────                                             ║
║  Pertanyaan:                                                     ║
║  □ Ada atribut non-kunci (X) yang menentukan                    ║
║    atribut non-kunci lain (Y)? X → Y?                          ║
║  □ Apakah X adalah candidate key? Jika tidak → Tidak 3NF       ║
║                                                                  ║
║  Tanda bahaya: Jika ada atribut yang "berasa seperti"           ║
║  FK tapi belum jadi FK → kemungkinan transitive dependency!     ║
║  (misal: ada dept_id dan nama_dept di tabel KARYAWAN)           ║
║                                                                  ║
║  Jika semua OK → Tabel sudah 3NF ✓                              ║
║                                                                  ║
â• â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•â•Ŗ
║                                                                  ║
║  CARA DEKOMPOSISI:                                               ║
║                                                                  ║
║  Partial dependency A → B (A bagian dari PK komposit {A,C}):    ║
║    → Buat tabel baru: TABEL_A(A, B)  ← A jadi PK baru          ║
║    → Hapus B dari tabel asli                                    ║
║    → A tetap di tabel asli sebagai FK ke TABEL_A                ║
║                                                                  ║
║  Transitive dependency X → Y (X adalah non-kunci):              ║
║    → Buat tabel baru: TABEL_X(X, Y)  ← X jadi PK baru          ║
║    → Hapus Y dari tabel asli                                    ║
║    → X tetap di tabel asli sebagai FK ke TABEL_X                ║
║                                                                  ║
╚══════════════════════════════════════════════════════════════════╝

Lampiran C: Checklist Normalisasi (untuk Tugas dan Proyek)

1NF Checklist:

  • Tidak ada sel yang berisi lebih dari satu nilai (tidak ada daftar dalam sel)
  • Tidak ada kelompok kolom berulang (A1, A2, A3, ...)
  • Setiap baris dapat dibedakan secara unik (ada primary key)
  • Setiap kolom berisi nilai dari satu domain yang sama

2NF Checklist (hanya untuk tabel dengan PK komposit):

  • Semua atribut non-kunci bergantung pada SELURUH PK, bukan hanya sebagian
  • Setiap partial dependency sudah dipisah menjadi tabel tersendiri
  • Tabel tersendiri hasil pemisahan sudah diberi PK yang tepat
  • FK sudah ditambahkan ke tabel asal untuk mempertahankan relasi

3NF Checklist:

  • Tidak ada atribut non-kunci yang menentukan atribut non-kunci lain
  • Tidak ada "FD tersembunyi" antar kolom non-kunci (perhatikan kolom yang tampak seperti FK tapi belum jadi FK)
  • Setiap transitive dependency sudah dipisah menjadi tabel tersendiri
  • Tabel hasil pemisahan sudah diberi PK yang tepat
  • FK sudah ditambahkan ke tabel asal

Kelengkapan Umum:

  • Semua tabel hasil normalisasi masih mempertahankan semua informasi asli (lossless)
  • Semua FK terdefinisi dengan benar
  • Nama tabel dan kolom konsisten
  • Derived attribute tidak disimpan sebagai kolom (kecuali ada alasan khusus)

Lampiran D: Contoh Dokumentasi Functional Dependency

Gunakan format diagram FD berikut untuk mendokumentasikan ketergantungan dalam suatu tabel:

FORMAT DIAGRAM FD:

RELASI: NAMA_TABEL(kolom1, kolom2, kolom3, ...)
                    ^^^^^^
                    PK

FD SET:
  F1: kolom1 ──────────────────────────────── kolom2
              (deskripsi mengapa FD ini berlaku)

  F2: kolom1 ──────────────────────────────── kolom3, kolom4
              (satu determinant bisa menentukan banyak atribut)

  F3: kolom3 ──────── kolom5
              MASALAH: kolom3 bukan PK → transitive dependency!

  Rantai transitive:
  kolom1 ──→ kolom3 ──→ kolom5
   PK         non-key    non-key
   ↑          ↑
   determinant yang valid   mediator (bukan PK → masalah 3NF!)

DIAGNOSIS:
  - 1NF: ✓/✗ (alasan)
  - 2NF: ✓/✗ (alasan; jika PK single → otomatis 2NF)
  - 3NF: ✓/✗ (alasan; sebutkan transitive dependency jika ada)

DEKOMPOSISI (jika diperlukan):
  Dari F3 (transitive: kolom3 → kolom5):
  → Tabel baru: TABEL_BARU(kolom3, kolom5)
  → Tabel asli: hapus kolom5, kolom3 menjadi FK ke TABEL_BARU

PENUTUP

Pertemuan 6 melengkapi kemampuan merancang logical model yang benar secara teoritis. Normalisasi bukan sekedar latihan akademik — ini adalah fondasi database yang dapat dipercaya, mudah dikelola, dan bebas dari inkonsistensi yang tersembunyi.

Key Messages Pertemuan 6:

  1. Anomali data (update, insertion, deletion) adalah gejala — penyebabnya adalah redundansi. Normalisasi mengobati penyebab, bukan gejalanya
  2. Functional Dependency adalah bahasa formal untuk mendeskripsikan hubungan atribut — pahami FD, dan normalisasi menjadi mekanis dan sistematis
  3. "The key, the whole key, and nothing but the key" — parafrase paling mudah untuk mengingat syarat 1NF, 2NF, dan 3NF
  4. Setiap dekomposisi harus lossless — kita tidak boleh kehilangan informasi saat memecah tabel
  5. 3NF bukan tujuan akhir — ini adalah standar minimum yang harus dipenuhi sebelum membangun sistem produksi
  6. Ada satu kasus tepi penting di mana tabel yang sudah memenuhi 3NF masih bisa mengalami anomali: ketika sebuah tabel memiliki multiple overlapping candidate keys (dua atau lebih candidate key yang berbagi atribut). Di sinilah 3NF tidak cukup — dan BCNF hadir untuk menutup celah ini

Koneksi ke Proyek Semester: Tugas normalisasi pertemuan ini adalah Tahap 4 dari proyek bertahap — Validated Logical Model. Setelah pertemuan ini, model data kamu seharusnya sudah siap secara teoritis untuk diimplementasikan. Pertemuan 7 (Tahap 5 — peer review) akan memvalidasi model ini, sebelum Pertemuan 9 (Tahap 6 — Physical Model) mengimplementasikannya ke dalam SQL DDL scripts.

Preview Pertemuan 7 (Pertemuan Terakhir Sebelum UTS): Kita akan belajar BCNF — Boyce-Codd Normal Form, versi 3NF yang lebih ketat. Kasus pemicunya: bayangkan sebuah tabel pendaftaran kursus di mana satu instruktur hanya mengajar satu kursus (sehingga instruktur → kursus), tapi satu kursus bisa diajarkan oleh banyak instruktur. Tabel ini bisa memenuhi 3NF namun masih mengandung anomali update. Pertemuan 7 akan mengupas kasus ini secara mendalam, plus mendiskusikan kapan denormalisasi disengaja untuk performa. Bawa hasil tugas normalisasi untuk didiskusikan!


Disusun oleh: Mohammad Reza Maulana, M.Kom Program Studi Sains Data Fakultas Ekonomi dan Bisnis Islam UIN K.H. Abdurrahman Wahid Pekalongan

Revisi: Februari 2026