Post 8: Relasi dalam ERD dan Mengapa Many-to-Many Tidak Baik

šŸ”— Memahami Relasi dalam Database

Relasi adalah hubungan antara dua atau lebih entitas dalam database. Pemahaman yang benar tentang jenis-jenis relasi dan cara mengimplementasikannya sangat penting untuk merancang database yang efisien dan terstruktur.

Jenis-Jenis Relasi dalam ERD

1. One-to-One (1:1)

Definisi: Satu record di tabel A berhubungan dengan tepat satu record di tabel B, dan sebaliknya.

KARYAWAN ——1:1—— DETAIL_KARYAWAN

Contoh Kasus: Setiap karyawan memiliki satu detail informasi pribadi

KARYAWAN
ID_Karyawan (PK) Nama Jabatan
K001 Gilang Ramadhan Manager
DETAIL_KARYAWAN
ID_Detail (PK) ID_Karyawan (FK) Alamat No_KTP
1 K001 Karawang 3201234567890123
CREATE TABLE karyawan (
    id_karyawan VARCHAR(10) PRIMARY KEY,
    nama VARCHAR(100),
    jabatan VARCHAR(50)
);

CREATE TABLE detail_karyawan (
    id_detail INT PRIMARY KEY AUTO_INCREMENT,
    id_karyawan VARCHAR(10) UNIQUE,
    alamat TEXT,
    no_ktp VARCHAR(16),
    FOREIGN KEY (id_karyawan) REFERENCES karyawan(id_karyawan)
);

2. One-to-Many (1:N)

Definisi: Satu record di tabel A dapat berhubungan dengan banyak record di tabel B, tetapi satu record di tabel B hanya berhubungan dengan satu record di tabel A.

JURUSAN ——1:N—— MAHASISWA

Contoh Kasus: Satu jurusan memiliki banyak mahasiswa

JURUSAN
Kode_Jurusan (PK) Nama_Jurusan
TI Teknik Informatika
MAHASISWA
NIM (PK) Nama Kode_Jurusan (FK)
24416255201003 Gilang Ramadhan TI
24416255201004 Budi Santoso TI
CREATE TABLE jurusan (
    kode_jurusan VARCHAR(5) PRIMARY KEY,
    nama_jurusan VARCHAR(100)
);

CREATE TABLE mahasiswa (
    nim VARCHAR(15) PRIMARY KEY,
    nama VARCHAR(100),
    kode_jurusan VARCHAR(5),
    FOREIGN KEY (kode_jurusan) REFERENCES jurusan(kode_jurusan)
);

3. Many-to-Many (M:N)

āš ļø PERINGATAN: Relasi Many-to-Many

Definisi: Satu record di tabel A dapat berhubungan dengan banyak record di tabel B, dan sebaliknya satu record di tabel B dapat berhubungan dengan banyak record di tabel A.

MAHASISWA ——M:N—— MATA_KULIAH

āŒ Relasi ini TIDAK DAPAT diimplementasikan langsung dalam database!

Mengapa Many-to-Many Tidak Baik Digunakan dalam ERD?

🚫 Masalah dengan Relasi Many-to-Many

1. Tidak Dapat Diimplementasikan Langsung

Database relasional TIDAK MENDUKUNG relasi many-to-many secara langsung. Tidak ada cara untuk membuat foreign key yang menghubungkan banyak record ke banyak record lain.

2. Redundansi Data

Jika dipaksakan, akan terjadi duplikasi data yang sangat besar dan tidak efisien.

3. Anomali Update, Insert, dan Delete

  • Update Anomaly: Perubahan data harus dilakukan di banyak tempat
  • Insert Anomaly: Tidak bisa insert data tanpa relasi lengkap
  • Delete Anomaly: Menghapus data dapat menghilangkan informasi penting

4. Sulit Menambahkan Attribute Relasi

Tidak ada tempat untuk menyimpan attribute yang terkait dengan relasi itu sendiri (misalnya: tanggal, nilai, status).

5. Kompleksitas Query

Query menjadi sangat kompleks dan tidak efisien karena harus mencari di banyak record.

6. Performa Buruk

Operasi database menjadi lambat karena harus memproses banyak duplikasi data.

Solusi: Mengubah Many-to-Many menjadi One-to-Many

āŒ SALAH: Many-to-Many Langsung

MAHASISWA ——M:N—— MATA_KULIAH

Masalah:

  • Tidak bisa diimplementasikan
  • Redundansi data tinggi
  • Tidak ada tempat untuk nilai/tanggal

āœ… BENAR: Gunakan Junction Table

MAHASISWA ——1:N—— KRS ——N:1—— MATA_KULIAH

Keuntungan:

  • Dapat diimplementasikan
  • Tidak ada redundansi
  • Bisa simpan attribute tambahan

Implementasi Junction Table (Tabel Perantara)

Langkah-langkah Mengubah M:N menjadi 1:N

Step 1: Identifikasi Relasi Many-to-Many

MAHASISWA ←→ MATA_KULIAH (Many-to-Many)

Step 2: Buat Junction Table (Tabel Perantara)

Tabel perantara akan berisi:

  • Foreign Key ke tabel pertama (MAHASISWA)
  • Foreign Key ke tabel kedua (MATA_KULIAH)
  • Attribute tambahan yang terkait dengan relasi

Step 3: Implementasi Database

MAHASISWA
NIM (PK) Nama Jurusan
24416255201003 Gilang Ramadhan TI
24416255201004 Budi Santoso SI
MATA_KULIAH
Kode_MK (PK) Nama_MK SKS
TI101 Basis Data 3
TI102 Pemrograman Web 3
KRS (Junction Table)
ID_KRS (PK) NIM (FK) Kode_MK (FK) Semester Nilai
1 24416255201003 TI101 Ganjil 2024 A
2 24416255201003 TI102 Ganjil 2024 B+
3 24416255201004 TI101 Ganjil 2024 A-
-- Tabel MAHASISWA
CREATE TABLE mahasiswa (
    nim VARCHAR(15) PRIMARY KEY,
    nama VARCHAR(100) NOT NULL,
    jurusan VARCHAR(50)
);

-- Tabel MATA_KULIAH
CREATE TABLE mata_kuliah (
    kode_mk VARCHAR(10) PRIMARY KEY,
    nama_mk VARCHAR(100) NOT NULL,
    sks INT
);

-- Tabel KRS (Junction Table)
CREATE TABLE krs (
    id_krs INT PRIMARY KEY AUTO_INCREMENT,
    nim VARCHAR(15) NOT NULL,
    kode_mk VARCHAR(10) NOT NULL,
    semester VARCHAR(20),
    nilai CHAR(2),
    FOREIGN KEY (nim) REFERENCES mahasiswa(nim)
        ON DELETE CASCADE
        ON UPDATE CASCADE,
    FOREIGN KEY (kode_mk) REFERENCES mata_kuliah(kode_mk)
        ON DELETE CASCADE
        ON UPDATE CASCADE,
    UNIQUE KEY unique_enrollment (nim, kode_mk)
);

Keuntungan Junction Table:

  • āœ… Dapat diimplementasikan dalam database
  • āœ… Tidak ada redundansi data
  • āœ… Bisa menambahkan attribute relasi (semester, nilai)
  • āœ… Query lebih efisien dengan JOIN
  • āœ… Mudah untuk update, insert, dan delete

Contoh Query dengan Junction Table

1. Menampilkan Mata Kuliah yang diambil Mahasiswa

SELECT m.nim, m.nama, mk.nama_mk, k.nilai
FROM mahasiswa m
JOIN krs k ON m.nim = k.nim
JOIN mata_kuliah mk ON k.kode_mk = mk.kode_mk
WHERE m.nim = '24416255201003';

2. Menampilkan Mahasiswa yang mengambil Mata Kuliah tertentu

SELECT mk.kode_mk, mk.nama_mk, m.nama, k.nilai
FROM mata_kuliah mk
JOIN krs k ON mk.kode_mk = k.kode_mk
JOIN mahasiswa m ON k.nim = m.nim
WHERE mk.kode_mk = 'TI101';

3. Menghitung Jumlah Mahasiswa per Mata Kuliah

SELECT mk.nama_mk, COUNT(k.nim) as jumlah_mahasiswa
FROM mata_kuliah mk
LEFT JOIN krs k ON mk.kode_mk = k.kode_mk
GROUP BY mk.kode_mk, mk.nama_mk;

5 Contoh Kasus Many-to-Many yang Harus Dipecah

Contoh 1: Sistem Penulis dan Buku

āŒ PENULIS ——M:N—— BUKU

↓ DIPECAH MENJADI ↓

āœ… PENULIS ——1:N—— PENULISAN ——N:1—— BUKU

Alasan: Satu buku bisa ditulis banyak penulis, satu penulis bisa menulis banyak buku

CREATE TABLE penulis (
    id_penulis INT PRIMARY KEY,
    nama VARCHAR(100)
);

CREATE TABLE buku (
    isbn VARCHAR(20) PRIMARY KEY,
    judul VARCHAR(200)
);

CREATE TABLE penulisan (
    id_penulisan INT PRIMARY KEY AUTO_INCREMENT,
    id_penulis INT,
    isbn VARCHAR(20),
    peran VARCHAR(50), -- Penulis Utama, Co-Author, Editor
    FOREIGN KEY (id_penulis) REFERENCES penulis(id_penulis),
    FOREIGN KEY (isbn) REFERENCES buku(isbn)
);

Contoh 2: Sistem Dokter dan Pasien

āŒ DOKTER ——M:N—— PASIEN

↓ DIPECAH MENJADI ↓

āœ… DOKTER ——1:N—— PEMERIKSAAN ——N:1—— PASIEN

Alasan: Satu dokter menangani banyak pasien, satu pasien bisa diperiksa banyak dokter

CREATE TABLE dokter (
    id_dokter INT PRIMARY KEY,
    nama VARCHAR(100),
    spesialisasi VARCHAR(50)
);

CREATE TABLE pasien (
    id_pasien INT PRIMARY KEY,
    nama VARCHAR(100),
    no_rm VARCHAR(20)
);

CREATE TABLE pemeriksaan (
    id_pemeriksaan INT PRIMARY KEY AUTO_INCREMENT,
    id_dokter INT,
    id_pasien INT,
    tanggal DATE,
    diagnosa TEXT,
    biaya DECIMAL(10,2),
    FOREIGN KEY (id_dokter) REFERENCES dokter(id_dokter),
    FOREIGN KEY (id_pasien) REFERENCES pasien(id_pasien)
);

Contoh 3: Sistem Aktor dan Film

āŒ AKTOR ——M:N—— FILM

↓ DIPECAH MENJADI ↓

āœ… AKTOR ——1:N—— PERAN ——N:1—— FILM

Alasan: Satu aktor bermain di banyak film, satu film memiliki banyak aktor

CREATE TABLE aktor (
    id_aktor INT PRIMARY KEY,
    nama VARCHAR(100),
    negara VARCHAR(50)
);

CREATE TABLE film (
    id_film INT PRIMARY KEY,
    judul VARCHAR(200),
    tahun INT
);

CREATE TABLE peran (
    id_peran INT PRIMARY KEY AUTO_INCREMENT,
    id_aktor INT,
    id_film INT,
    nama_karakter VARCHAR(100),
    tipe_peran VARCHAR(50), -- Utama, Pendukung, Cameo
    FOREIGN KEY (id_aktor) REFERENCES aktor(id_aktor),
    FOREIGN KEY (id_film) REFERENCES film(id_film)
);

Contoh 4: Sistem Supplier dan Produk

āŒ SUPPLIER ——M:N—— PRODUK

↓ DIPECAH MENJADI ↓

āœ… SUPPLIER ——1:N—— PASOKAN ——N:1—— PRODUK

Alasan: Satu supplier menyediakan banyak produk, satu produk bisa dari banyak supplier

CREATE TABLE supplier (
    id_supplier INT PRIMARY KEY,
    nama_supplier VARCHAR(100),
    kota VARCHAR(50)
);

CREATE TABLE produk (
    id_produk INT PRIMARY KEY,
    nama_produk VARCHAR(100),
    kategori VARCHAR(50)
);

CREATE TABLE pasokan (
    id_pasokan INT PRIMARY KEY AUTO_INCREMENT,
    id_supplier INT,
    id_produk INT,
    harga DECIMAL(10,2),
    waktu_pengiriman INT, -- dalam hari
    minimum_order INT,
    FOREIGN KEY (id_supplier) REFERENCES supplier(id_supplier),
    FOREIGN KEY (id_produk) REFERENCES produk(id_produk)
);

Contoh 5: Sistem Siswa dan Ekstrakurikuler

āŒ SISWA ——M:N—— EKSTRAKURIKULER

↓ DIPECAH MENJADI ↓

āœ… SISWA ——1:N—— PENDAFTARAN_EKSKUL ——N:1—— EKSTRAKURIKULER

Alasan: Satu siswa bisa ikut banyak ekstrakurikuler, satu ekstrakurikuler diikuti banyak siswa

CREATE TABLE siswa (
    nis VARCHAR(15) PRIMARY KEY,
    nama VARCHAR(100),
    kelas VARCHAR(10)
);

CREATE TABLE ekstrakurikuler (
    id_ekskul INT PRIMARY KEY,
    nama_ekskul VARCHAR(100),
    pembina VARCHAR(100)
);

CREATE TABLE pendaftaran_ekskul (
    id_pendaftaran INT PRIMARY KEY AUTO_INCREMENT,
    nis VARCHAR(15),
    id_ekskul INT,
    tanggal_daftar DATE,
    status VARCHAR(20), -- Aktif, Non-Aktif
    jabatan VARCHAR(50), -- Ketua, Anggota, Sekretaris
    FOREIGN KEY (nis) REFERENCES siswa(nis),
    FOREIGN KEY (id_ekskul) REFERENCES ekstrakurikuler(id_ekskul)
);

Kesimpulan

> Optimasi query dengan index pada foreign key

Rangkuman

Relasi Many-to-Many adalah konsep yang sering muncul dalam dunia nyata, namun TIDAK DAPAT diimplementasikan langsung dalam database relasional. Solusinya adalah dengan membuat Junction Table (tabel perantara) yang mengubah satu relasi M:N menjadi dua relasi 1:N.

Dengan menggunakan junction table, kita mendapatkan banyak keuntungan: menghilangkan redundansi, memungkinkan penambahan attribute relasi, meningkatkan performa, dan menjaga integritas data. Selalu ingat untuk menambahkan primary key, foreign key constraints, unique constraint, dan index yang sesuai pada junction table Anda.

Melalui 5 contoh yang telah dijelaskan (Mahasiswa-MataKuliah, Penulis-Buku, Dokter-Pasien, Aktor-Film, Supplier-Produk, dan Siswa-Ekstrakurikuler), kita dapat melihat pola yang konsisten dalam mengubah relasi many-to-many menjadi implementasi database yang benar dan efisien.

← Kembali ke Beranda