Database design adalah kegiatan memutuskan, sebelum menulis kode, data apa saja yang disimpan aplikasi, dipecah ke tabel apa, kolomnya apa saja, dan bagaimana tabel-tabel itu saling terhubung. Mirip menggambar denah sebelum membangun rumah: memindah tembok di kertas itu gampang, memindahnya setelah rumahnya berdiri dan dihuni itu mahal. Database juga begitu. Setelah aplikasi jalan dan tabelnya berisi ribuan baris, mengubah strukturnya berarti ikut memindahkan semua data itu.
🧪 Tebakan cepat: sebuah toko mencatat pesanan di satu tabel, dan nomor HP pembeli ikut ditulis di setiap baris pesanannya. Budi ganti nomor, lalu aplikasinya mengubah nomor di pesanan terbaru Budi saja. Kalau sekarang kamu tanya "nomor HP Budi berapa?", jawabannya satu nomor, dua nomor, atau error? Tebak dulu, jawabannya ada di bagian "Masalah satu tabel serba-ada".
Kedai Senja: contoh yang dipakai sepanjang track
Track ini memakai satu contoh dari awal sampai akhir: Kedai Senja, toko kopi online kecil. Pelanggannya Budi, Siti dan Andi. Produknya Kopi Susu (Rp18.000), Kopi Susu Aren (Rp22.000), Teh Tarik (Rp15.000) dan Roti Bakar (Rp20.000). Pelanggan membuat pesanan, dan tiap pesanan berisi produk.
Cara menulis query (SELECT, WHERE, JOIN) diajarkan di track SQL. Track ini mengajarkan hal yang datang sebelumnya: merancang tabelnya, supaya query-query itu gampang ditulis dan hasilnya benar.
Masalah satu tabel serba-ada
Waktu baru buka, Kedai Senja mencatat semuanya di satu tabel orders, persis seperti spreadsheet:
| id | customer_name | customer_phone | product | price |
|---|---|---|---|---|
| 1 | Budi | 0812-1111-2222 | Kopi Susu | 18000 |
| 2 | Budi | 0812-1111-2222 | Roti Bakar | 20000 |
| 3 | Siti | 0813-5555-6666 | Kopi Susu | 18000 |
| 4 | Andi | 0819-7777-8888 | Teh Tarik | 15000 |
Nomor Budi tertulis dua kali. Budi ganti nomor, dan aplikasinya mengubah pesanan terbarunya saja:
UPDATE orders SET customer_phone = '0812-9999-0000' WHERE id = 2;
-- daftar pelanggan dan nomornya
SELECT DISTINCT customer_name, customer_phone FROM orders;
| customer_name | customer_phone |
|---|---|
| Budi | 0812-1111-2222 |
| Budi | 0812-9999-0000 |
| Siti | 0813-5555-6666 |
| Andi | 0819-7777-8888 |
Budi sekarang punya dua nomor, dan gak ada error sama sekali. Itu jawaban tebakannya. Database gak tahu dua baris itu orang yang sama, jadi dia gak bisa protes. Tabel ini punya tiga penyakit:
- Redundan: data yang sama (nomor Budi) disimpan berulang. Budi punya 40 pesanan? Nomornya tertulis 40 kali, dan ganti nomor berarti mengubah 40 baris.
- Inkonsisten: lupa satu baris saja, datanya saling bertentangan, seperti di atas.
- Hilang tanpa sengaja: Andi membatalkan satu-satunya pesanannya,
DELETE FROM orders WHERE id = 4;. Andi dan nomornya ikut lenyap, padahal dia masih pelanggan. Kebalikannya juga: produk baru Kopi Susu Aren gak bisa dicatat sebelum ada yang memesannya.
Makin besar tabelnya, makin lambat juga: mau daftar pelanggan saja, database harus menyisir semua pesanan.
Desain tiga tabel
Desain yang rapi memberi setiap "benda" tabelnya sendiri, dan pesanan cuma menyimpan nomor id-nya:
CREATE TABLE customers (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
phone TEXT
);
CREATE TABLE products (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
price INTEGER NOT NULL -- rupiah
);
CREATE TABLE orders (
id INTEGER PRIMARY KEY,
customer_id INTEGER NOT NULL REFERENCES customers(id),
product_id INTEGER NOT NULL REFERENCES products(id)
);
id INTEGER PRIMARY KEY: nomor unik tiap baris (primary key), cara pasti menunjuk satu pelanggan walau namanya kembar.customer_id ... REFERENCES customers(id): kolom penunjuk keiddicustomers(foreign key, seperti di pelajaran SQL Relasi Antar Tabel).NOT NULL: kolomnya wajib diisi. Aturan yang dijaga database seperti ini disebut constraint.
Sekarang ganti nomor Budi cukup UPDATE customers SET phone = '0812-9999-0000' WHERE id = 1;: 1 baris berubah, dan semua pesanan Budi ikut melihat nomor barunya lewat customer_id. Membatalkan pesanan Andi menghapus baris di orders, tapi Andi tetap ada di customers. Kopi Susu Aren bisa masuk ke products sebelum ada yang memesan. Satu pesanan berisi beberapa produk? Itu kita rapikan di pelajaran Kardinalitas & Relasi.
Tiga tahap database design
Desain tadi gak langsung ditulis sebagai CREATE TABLE. Biasanya ada tiga tahap:
| Tahap | Pertanyaannya | Di Kedai Senja |
|---|---|---|
| Conceptual | Menentukan entitas dan relasi | Ada pelanggan, produk, pesanan. Pelanggan membuat pesanan, pesanan berisi produk. |
| Logical | Merancang tabel dan kolom | Tabel customers (id, name, phone), orders (id, customer_id, product_id), dan seterusnya. |
| Physical | Implementasi di DBMS | CREATE TABLE di SQLite dengan tipe INTEGER dan TEXT, plus index untuk kolom yang sering dicari. |
- Entitas adalah benda yang datanya disimpan (pelanggan, produk). Relasi adalah hubungan antar entitas ("membuat", "berisi"). Tahap conceptual biasanya digambar sebagai ER diagram, pelajaran berikutnya.
- Tahap logical masih belum peduli database-nya apa. Di sini juga dilakukan normalisasi (1NF dan seterusnya) supaya gak ada data dobel.
- DBMS (Database Management System) adalah software yang menyimpan dan mengelola database: SQLite, MySQL, PostgreSQL. Tahap physical memilih tipe data persis milik DBMS itu (
TEXTdi SQLite,VARCHAR(100)di MySQL), index, dan cara backup.
Tujuannya: efisien, konsisten, mudah diakses
Jadi database design adalah proses merancang struktur tabel, kolom, relasi dan constraint. Tujuannya mengorganisir data agar efisien (gak ada salinan sia-sia, query cepat), konsisten (satu fakta disimpan di satu tempat, jadi gak bisa bertentangan), dan mudah diakses (pertanyaan aplikasi dijawab query yang sederhana).
Tanpa perencanaan, hasilnya seperti tabel pertama tadi: data redundan, inkonsisten, dan query lambat. Server yang lebih besar gak menolong, karena Budi tetap punya dua nomor di server secepat apa pun.
⚠️ Jebakan yang sering ketemu
- "Satu tabel dulu, nanti dirapikan." Nanti itu artinya memindahkan data production sambil aplikasinya dipakai orang. Rapikan selagi tabelnya masih kosong.
- Menunjuk pakai nama, bukan id. Nama bisa kembar dan bisa berubah. Simpan
customer_id, bukancustomer_name. - Mencampur tahap logical dan physical. "Tabel
customerspunya kolomphone" itu logical. "phonebertipeTEXTdi SQLite" itu physical. - Salah ketik teks di latihan. Fungsinya harus mengembalikan teks persis, termasuk huruf besar di awal:
"Menentukan entitas dan relasi", bukan"menentukan entitas & relasi".
TL;DR: Database design adalah merancang tabel, kolom, relasi dan constraint sebelum menulis kode, supaya data efisien, konsisten dan mudah diakses. Satu tabel serba-ada menyimpan data berulang (redundan), gampang bertentangan (Budi punya dua nomor), dan bisa menghapus pelanggan bersama pesanannya. Desain yang rapi memberi tiap benda tabelnya sendiri dan menghubungkannya dengan id. Tahapnya tiga: conceptual (menentukan entitas dan relasi), logical (merancang tabel dan kolom), physical (implementasi di DBMS seperti SQLite, MySQL atau PostgreSQL). Track ini memakai Kedai Senja: customers, products, orders, lalu nanti order_items, profiles dan phone_numbers.