Mengubah dan Merancang · Pelajaran 8 dari 9

Merancang tabel dan normalisasi

10 menit baca · BelajarCode

Rancangan tabel yang buruk menyebabkan masalah yang sulit diperbaiki belakangan. Perhatikan catatan penjualan warung yang disimpan dalam satu tabel besar:

Tabel datar yang bermasalah
no_notatanggalpelangganteleponprodukhargajumlah
12026-09-01Bu Sari0812000111Kopi susu, Roti bakar15000, 180002, 1
22026-09-01Pak Budi0813000222Kopi susu150003
32026-09-02Bu Sari0812000999Teh tarik120001

Masalahnya:

  • Banyak nilai dalam satu sel: "Kopi susu, Roti bakar" sulit dicari dan dihitung.
  • Data ganda: nama dan telepon Bu Sari disalin di setiap nota. Nomor teleponnya bahkan sudah tidak konsisten.
  • Anomali perubahan: jika harga kopi susu naik, banyak baris harus diubah, dan mudah ada yang terlewat.
  • Anomali penghapusan: menghapus satu-satunya nota Pak Budi juga menghapus data Pak Budi.

Normalisasi

Normalisasi memecah tabel supaya setiap fakta disimpan di satu tempat.

Bentuk normal
BentukSyarat sederhana
1NFSetiap sel berisi satu nilai, tidak ada daftar dalam satu sel
2NF1NF, dan setiap kolom bergantung pada seluruh kunci, bukan sebagian
3NF2NF, dan tidak ada kolom yang bergantung pada kolom bukan kunci lainnya

Hasil normalisasi catatan warung:

SQL
1CREATE TABLE pelanggan (id INTEGER PRIMARY KEY, nama TEXT, telepon TEXT);2CREATE TABLE produk (id INTEGER PRIMARY KEY, nama TEXT, harga INTEGER);3CREATE TABLE nota (id INTEGER PRIMARY KEY, tanggal TEXT, pelanggan_id INTEGER REFERENCES pelanggan(id));4CREATE TABLE detail_nota (5    nota_id INTEGER REFERENCES nota(id),6    produk_id INTEGER REFERENCES produk(id),7    jumlah INTEGER,8    harga_saat_beli INTEGER,9    PRIMARY KEY (nota_id, produk_id)10);1112INSERT INTO pelanggan VALUES (1, 'Bu Sari', '0812000999'), (2, 'Pak Budi', '0813000222');13INSERT INTO produk VALUES (1, 'Kopi susu', 15000), (2, 'Roti bakar', 18000), (3, 'Teh tarik', 12000);14INSERT INTO nota VALUES (1, '2026-09-01', 1), (2, '2026-09-01', 2), (3, '2026-09-02', 1);15INSERT INTO detail_nota VALUES16    (1, 1, 2, 15000), (1, 2, 1, 18000),17    (2, 1, 3, 15000),18    (3, 3, 1, 12000);1920SELECT n.id AS nota, p.nama AS pelanggan, SUM(d.jumlah * d.harga_saat_beli) AS total21FROM nota n22JOIN pelanggan p ON p.id = n.pelanggan_id23JOIN detail_nota d ON d.nota_id = n.id24GROUP BY n.id, p.nama25ORDER BY n.id;
Hasil
nota | pelanggan | total
1 | Bu Sari | 48000
2 | Pak Budi | 45000
3 | Bu Sari | 12000
  • Data pelanggan cukup disimpan sekali. Mengganti nomor telepon Bu Sari hanya mengubah satu baris.
  • detail_nota adalah tabel penghubung nota dan produk dengan kunci gabungan (nota_id, produk_id).
  • harga_saat_beli sengaja disimpan, karena harga produk bisa berubah. Nota lama tetap harus mencatat harga saat transaksi terjadi. Ini contoh keputusan rancangan yang disengaja, bukan data ganda.

Indeks

Indeks mempercepat pencarian pada kolom tertentu, mirip indeks di bagian belakang buku. Tanpa indeks, DBMS memeriksa seluruh baris. Dengan indeks (biasanya berbentuk B-tree), pencarian menjadi logaritmik.

SQL
1CREATE INDEX idx_nota_tanggal ON nota(tanggal);23SELECT id, tanggal FROM nota WHERE tanggal = '2026-09-01';
Hasil
id | tanggal
1 | 2026-09-01
2 | 2026-09-01

Indeks juga punya biaya: memakan ruang dan memperlambat INSERT dan UPDATE, karena indeks ikut diperbarui. Buat indeks untuk kolom yang sering dipakai di WHERE, JOIN, dan ORDER BY.

Cek pemahaman

Kenapa menyimpan nama dan telepon pelanggan di setiap baris penjualan dianggap rancangan yang buruk?

Latihan

Normalisasi data kursus

Tabel berikut menyimpan pendaftaran kursus: (nama_siswa, email_siswa, judul_kursus, nama_pengajar, tanggal_daftar). Satu siswa bisa mendaftar banyak kursus, dan satu pengajar bisa mengajar banyak kursus. Pecah menjadi tabel-tabel yang ternormalisasi.

Tandai pelajaran ini selesai

Masuk ke aplikasi untuk mencatat kemajuan, lalu lanjutkan ke pelajaran berikutnya dari perangkat mana pun.

Buka di aplikasi