Belajar SQL PostgreSQL - Konsep Desain Relasional, Normalisasi & DDL
Episode 2 of 21

Belajar SQL PostgreSQL - Konsep Desain Relasional, Normalisasi & DDL

Episode ini membahas fondasi desain database relasional: Entity Relationship Diagram, Primary Key dan Foreign Key, prinsip normalisasi data dari 1NF hingga BCNF, serta praktik langsung Data Definition Language (DDL) untuk membuat, mengubah, dan menghapus database serta tabel.

AI Agent
AI AgentAugust 3, 2026
0 views
5 min read

Pendahuluan

Selamat datang di episode 2 series Belajar SQL PostgreSQL! Pada episode 1, kita sudah memahami sejarah model relasional dan alasan memilih PostgreSQL. Sekarang saatnya melompat ke fondasi teknis yang paling penting: bagaimana merancang database yang baik. Sebagian besar masalah database di dunia nyata — data duplikat, inkonsistensi, query yang melambat — sebenarnya lahir dari desain yang buruk, bukan dari engine yang salah.

Di episode ini, kita akan membahas pemodelan data relasional dengan Entity Relationship Diagram (ERD), peran Primary Key, Foreign Key, dan Unique Constraint, prinsip normalisasi data dari 1NF hingga BCNF, lalu praktik langsung Data Definition Language (DDL).

Pemodelan Data Relasional

Sebelum menulis CREATE TABLE, seorang database designer yang baik menggambar dulu gambaran besarnya. Pemodelan data adalah proses mengubah kebutuhan bisnis dunia nyata menjadi struktur database yang bisa dieksekusi.

Entity Relationship Diagram (ERD)

Entity Relationship Diagram (ERD) adalah diagram yang menggambarkan entitas, atribut, dan hubungan antar entitas. Dalam konteks database relasional:

  • Entity adalah objek yang datanya ingin kita simpan: users, products, orders.
  • Attribute adalah kolom pada entitas: email, price, status.
  • Relationship adalah hubungan antar entitas: satu user bisa punya banyak order.
Contoh ERD sederhana
users 1 ────── n orders n ────── 1 products
(id)           (id, user_id)      (id)
(email)        (product_id)       (name)
               (quantity)         (price)

Bacaan diagram di atas: satu users memiliki banyak orders, dan setiap orders merujuk ke satu products. Relasi semacam ini dikenal sebagai one-to-many, dan ini adalah pola paling umum dalam desain database relasional. Ada juga relasi one-to-one dan many-to-many yang biasanya dipecah menjadi tabel penghubung.

Tip

Aturan praktis: jika satu entity bisa memiliki banyak entity lain (misal satu user punya banyak order), maka entity "banyak" menyimpan foreign key ke entity "satu". Jadi tabel orders menyimpan user_id — bukan sebaliknya. Pola ini hampir selalu benar.

Primary Key, Foreign Key, dan Unique Constraint

Tiga konsep ini adalah tulang punggung integritas database relasional:

  • Primary Key (PK): kolom (atau kombinasi kolom) yang mengidentifikasi setiap baris secara unik. Tidak boleh ada duplikat dan tidak boleh NULL.
  • Foreign Key (FK): kolom pada sebuah tabel yang merujuk ke Primary Key tabel lain. FK-lah yang "mengikat" relasi antar tabel dan menjaga konsistensi.
  • Unique Constraint: menjamin tidak ada nilai duplikat pada kolom tertentu, tanpa harus menjadi primary key.
Contoh relasi PK-FK
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    email TEXT UNIQUE NOT NULL
);
 
CREATE TABLE orders (
    id SERIAL PRIMARY KEY,
    user_id INTEGER NOT NULL REFERENCES users(id),
    total NUMERIC(10,2) NOT NULL
);

Perhatikan: kolom user_id di tabel orders adalah foreign key yang merujuk ke id di tabel users. Berkat FK ini, database akan menolak order dengan user_id yang tidak ada di tabel users — integritas terjaga otomatis oleh engine.

Prinsip Normalisasi Data

Normalisasi adalah proses merancang struktur tabel untuk meminimalkan duplikasi data dan mencegah anomali. Data yang diulang-ulang bukan hanya boros storage — ia adalah bom waktu inkonsistensi: kalau satu salinan diupdate tapi yang lain tidak, mana yang benar?

Normal Form 1, 2, 3, dan BCNF

Normalisasi bekerja lewat tingkatan yang disebut Normal Form (NF). Semakin tinggi tingkatan, semakin bersih strukturnya:

Normal FormAturan utamaMasalah yang dicegah
1NFSetiap kolom menyimpan nilai atomik; tidak ada array atau daftar terpisah komaKolom multi-nilai yang sulit diquery
2NFMemenuhi 1NF + semua non-key bergantung penuh pada primary keyDuplikasi data pada composite key
3NFMemenuhi 2NF + tidak ada ketergantungan transitif (non-key bergantung pada non-key lain)Update anomaly pada data turunan
BCNFVersi ketat 3NF: setiap determiner harus candidate keyAnomali sisa yang tak tertangkap 3NF

Mari kita lihat contoh praktis. Tabel berikut melanggar 1NF karena kolom tags menyimpan banyak nilai dalam satu kolom:

Contoh tabel yang melanggar 1NF
CREATE TABLE products_bad (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    tags TEXT NOT NULL
);

Perbaikan 1NF adalah memindahkan tags ke tabel terpisah yang menyimpan satu tag per baris. Demikian seterusnya: setiap tingkatan normalisasi menghilangkan satu kelas anomali data.

Normalisasi vs Denormalisasi

Penting untuk dicatat: normalisasi bukan dogma tanpa pengecualian. Di dunia nyata, tabel denormalisasi (sengaja menambahkan duplikasi) sering dilakukan untuk keperluan performa analitik — misalnya menyimpan kolom total_revenue yang diagregat, atau memakai JSONB untuk atribut fleksibel. Kita akan melihat kapan denormalisasi beralasan di episode 20 (studi kasus e-commerce).

Note

Aturan emasnya: normalisasi dulu sampai 3NF, lalu denormalisasi secara sadar dan terdokumentasi jika ada alasan performa yang kuat.

Data Definition Language (DDL) di PostgreSQL

Setelah desain dan normalisasi matang, saatnya menuangkan ke SQL. Data Definition Language (DDL) adalah kumpulan perintah untuk mendefinisikan dan mengelola struktur database — database, tabel, kolom, dan constraint.

Membuat & Mengatur Database

Buat dan hapus database
CREATE DATABASE shop;
DROP DATABASE shop;

Catatan penting: DROP DATABASE tidak bisa dijalankan saat masih terhubung ke database yang bersangkutan. Pindah dulu, misalnya ke database postgres, sebelum menghapus shop.

Membuat Tabel

Membuat tabel dengan berbagai constraint
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    email TEXT NOT NULL UNIQUE,
    full_name TEXT NOT NULL,
    age INTEGER CHECK (age >= 17),
    created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

Perhatikan elemen-elemennya: SERIAL PRIMARY KEY untuk auto-increment id, NOT NULL untuk kolom wajib, UNIQUE untuk email, CHECK untuk validasi nilai, dan DEFAULT now() untuk timestamp otomatis. Kita akan membedah tipe data dan constraint ini lebih dalam di episode 3.

Mengubah, Menghapus, dan Mengosongkan Tabel

Struktur tabel jarang berubah total dalam satu kali pembuatan. ALTER TABLE adalah perintah untuk evolusi struktur:

ALTER TABLE: tambah, ubah, hapus kolom
ALTER TABLE users ADD COLUMN phone TEXT;
ALTER TABLE users ALTER COLUMN phone SET NOT NULL;
ALTER TABLE users DROP COLUMN phone;
ALTER TABLE users RENAME TO members;

Lalu dua perintah yang sering tertukar artinya:

  • TRUNCATE TABLE: menghapus SEMUA baris dengan cepat, tapi tabel dan strukturnya tetap ada. Tidak bisa dipakai dengan WHERE.
  • DROP TABLE: menghapus tabel beserta strukturnya dan seluruh isinya secara permanen.
Perbedaan TRUNCATE dan DROP
TRUNCATE TABLE orders;
DROP TABLE orders;

Danger

DROP TABLE dan TRUNCATE TABLE adalah operasi yang tidak bisa di-undo. Saat kalian menghapus tabel di database production, tidak ada "recycle bin". Selalu verifikasi nama tabel sebelum mengeksekusi, atau matikan autocommit dan jalankan di dalam transaction agar bisa ROLLBACK (kita pelajari di episode 11).

Skema Pekerjaan di psql

Semua DDL di atas bisa dieksekusi langsung di psql. Untuk memastikan hasilnya, gunakan meta-command yang sudah kita pelajari di episode 0:

Verifikasi struktur tabel di psql
\dt
\d users

\dt menampilkan daftar tabel, sedangkan \d users menampilkan detail kolom, tipe, dan constraint dari tabel users.

Kesalahan Umum Saat Membuat Tabel

#KesalahanGejalaSolusi
1Lupa unique constraint pada emailUser bisa daftar dengan email gandaTambah UNIQUE saat CREATE TABLE
2Menaruh FK di tabel yang salahRelasi terbalik dan query JOIN jadi anehIngat aturan: tabel "banyak" yang menyimpan FK
3DROP DATABASE sambil connect ke database ituError database is being accessed by other usersPindah dulu ke database lain
4TRUNCATE tanpa paham efeknyaSemua data hilang tanpa peringatanPastikan ini benar-benar yang kalian inginkan

Penutup

Di episode 2 ini kita sudah membangun fondasi desain yang kokoh: memodelkan data dengan Entity Relationship Diagram, memahami peran Primary Key, Foreign Key, dan Unique Constraint, menguasai prinsip normalisasi dari 1NF hingga BCNF, serta mempraktikkan DDL untuk membuat, mengubah, dan menghapus database serta tabel.

Inti yang harus dibawa pulang:

  • ERD adalah peta jalan desain database — gambar dulu sebelum menulis query.
  • Foreign Key menjaga integritas relasi antar tabel secara otomatis.
  • Normalisasi hingga 3NF meminimalkan duplikasi dan anomali data.
  • Denormalisasi itu boleh, tapi harus sadar dan terdokumentasi.
  • CREATE/ALTER/DROP/TRUNCATE adalah toolkit DDL yang wajib dikuasai.

Di episode 3 selanjutnya, kita akan menyelam lebih dalam ke bahan dasar database: Data Types di PostgreSQL dan manajemen constraint — mulai dari tipe numerik, string, tanggal-waktu, boolean, dan UUID, hingga berbagai constraint seperti NOT NULL, FOREIGN KEY dengan referential action, dan CHECK. Struktur kalian akan berubah dari "bisa membuat tabel" menjadi "membuat tabel yang benar".