Lompat ke konten
20 menit bacamateri 19 dari 96

Model pola akses

Turunkan entitas, relasi, key, dan constraint dari daftar baca/tulis yang nyata, bukan dari diagram yang kelihatan rapi.

Ditinjau 26 Oktober 2026

Pertanyaan

Dari kebutuhan baca dan tulis, entitas, key, dan constraint apa yang harus ada di skema?

Setelah baca ini, kamu bisa nulis daftar pola akses dengan frekuensi dan syarat kebenarannya, lalu menurunkan tabel, primary key, unique constraint, dan foreign key dari daftar itu.

Prasyarat dan contoh

Kamu sudah punya beban kerja yang terukur (M01.02) dan paham bentuk API yang bakal membaca dan menulis data (M03).

Sebuah toko online kecil punya 20.000 order per hari, rata-rata 2,5 item per order, dan 300.000 kunjungan halaman produk per hari. Tim biasanya mulai dari gambar kotak-kotak: users, products, orders, order_items. Gambarnya wajar, tapi belum menjawab pertanyaan penting: query apa yang paling sering jalan, dan aturan apa yang nggak boleh dilanggar data?

Skema yang bagus adalah hasil dari daftar akses, bukan sebaliknya. Dua tim dengan entitas sama bisa punya skema berbeda kalau pola akses mereka berbeda.

Mekanisme

Langkah 1: tulis pola akses. Satu baris per operasi, dengan frekuensi, bentuk filter, urutan, dan batas hasil. Untuk toko tadi:

| Kode | Operasi | Frekuensi | Catatan | | ---- | ----------------------------------------- | ------------------ | ------------------------------- | | R1 | Ambil produk berdasarkan id | ~3,5/detik rata2 | Puncak 10x, baca saja | | R2 | Daftar order milik satu user, terbaru dulu | ~1/detik | 20 per halaman | | R3 | Ambil satu order lengkap dengan itemnya | ~0,5/detik | Harus konsisten setelah checkout | | W1 | Buat order beserta itemnya | ~0,23/detik rata2 | Puncak flash sale 50/detik | | W2 | Ubah status order | ~0,5/detik | Urutan status harus valid |

Rata-rata 20.000 order per hari itu sekitar 0,23 per detik. Angka puncak yang menentukan desain, jadi catat keduanya.

Langkah 2: turunkan entitas dan relasi. Entitas muncul karena ada hal yang punya identitas sendiri dan diakses sendiri. order_items jadi tabel terpisah karena satu order punya banyak item dan R3 butuh semuanya. Relasi satu-ke-banyak ditaruh sebagai foreign key di sisi "banyak": order_items.order_id.

Langkah 3: pilih key dari akses. Primary key harus unik dan stabil. Jangan pakai email atau nomor telepon sebagai primary key: keduanya bisa berubah, dan perubahan primary key menjalar ke semua tabel yang mereferensikannya. Pakai identifier sintetis, lalu pasang UNIQUE pada email. Key lain datang dari R2: akses "order milik user X, terbaru dulu" butuh urutan (user_id, created_at). Itu soal indeks, dibahas di M04.03, tapi kebutuhannya lahir dari sini.

Langkah 4: pindahkan aturan bisnis ke constraint. Constraint adalah aturan yang ditegakkan database untuk semua penulis, termasuk skrip sekali jalan dan service lain yang nanti ikut nulis.

CREATE TABLE orders (
  id          BIGINT PRIMARY KEY,
  user_id     BIGINT NOT NULL REFERENCES users(id),
  status      TEXT NOT NULL CHECK (status IN ('baru','dibayar','dikirim','batal')),
  total_cents BIGINT NOT NULL CHECK (total_cents >= 0),
  created_at  TIMESTAMPTZ NOT NULL
);

CREATE TABLE order_items (
  order_id   BIGINT NOT NULL REFERENCES orders(id),
  product_id BIGINT NOT NULL REFERENCES products(id),
  qty        INT NOT NULL CHECK (qty > 0),
  PRIMARY KEY (order_id, product_id)
);

Primary key komposit (order_id, product_id) mencegah produk yang sama masuk dua kali di satu order. Itu aturan bisnis yang sekarang dijaga database, bukan kode aplikasi yang bisa lupa.

Saat rancangan ini gagal

  • Mulai dari diagram, bukan dari akses. Skemanya rapi tapi R2 butuh join empat tabel dan nyisir semua order. Kamu baru sadar setelah ada 10 juta baris.
  • Natural key yang ternyata nggak stabil. Email dipakai sebagai primary key, lalu user ganti email. Semua foreign key harus diubah, atau datanya jadi orphan.
  • Constraint cuma di aplikasi. Dua service menulis ke tabel yang sama dan satu lupa aturan qty > 0. Data jelek masuk, dan baru ketahuan di laporan keuangan.
  • Pola akses yang nggak ditulis. Fitur "cari order berdasarkan nomor telepon penerima" muncul belakangan. Skema nggak punya jalur cepat untuk itu, dan jawabannya jadi pemindaian tabel.

Contoh tandingan: constraint yang terlalu ketat juga merugikan. CHECK yang membatasi status ke empat nilai bagus sekarang, tapi tiap status baru butuh migrasi. Untuk status yang sering berubah, tabel referensi sering lebih luwes.

Latihan

Sebuah aplikasi perpustakaan punya pola akses ini: (R1) daftar pinjaman aktif milik satu anggota, ~5/detik; (R2) cek apakah satu buku fisik sedang dipinjam, ~8/detik; (W1) pinjam buku, ~1/detik. Aturan bisnis: satu buku fisik nggak boleh dipinjam dua orang sekaligus.

Turunkan tabel, key, dan constraint yang melindungi aturan itu.

Lihat pembahasan

Entitas: members, book_copies (buku fisik, bukan judul), dan loans.

Aturan "satu buku fisik, satu peminjam aktif" harus ditegakkan database, bukan hanya cek di kode. Kalau kode cuma SELECT lalu INSERT, dua request bersamaan sama-sama lihat "tersedia" dan keduanya berhasil.

Caranya, kasih kolom returned_at yang kosong selama pinjaman aktif, lalu pasang unique index parsial: CREATE UNIQUE INDEX one_active_loan ON loans(copy_id) WHERE returned_at IS NULL. Insert kedua untuk buku yang sama gagal dengan error unique violation, dan aplikasi menerjemahkannya jadi "buku sedang dipinjam".

Key dari akses: R1 butuh pencarian (member_id) di antara pinjaman aktif, R2 dilayani oleh indeks parsial yang sama. Primary key loans.id sintetis, foreign key ke members dan book_copies.

Jawaban yang bagus memisahkan judul buku dari buku fisik dan menaruh aturan tadi sebagai constraint, bukan sebagai komentar di kode.

Terkait

  • M01.02 Jelaskan beban kerja nyediain angka frekuensi yang dipakai di tabel pola akses.
  • M04.02 bahas gimana pola akses memengaruhi pilihan jenis database.
  • M04.03 bahas indeks yang melayani pola akses ini.
  • M05 Transaksi dan konkurensi bahas lebih lanjut kenapa cek-lalu-tulis nggak aman.
  • Lab L04 melatih pembacaan pola akses terhadap skema.

Catatan

  • Asumsi: basis data relasional dengan transaksi dan constraint. Contoh SQL bergaya PostgreSQL.
  • Yang nggak dibahas: normalisasi formal (1NF sampai BCNF) dan desain skema multi-tenant.
  • Frekuensi di tabel itu perkiraan untuk latihan, bukan data produksi.
  • Terakhir ditinjau: 26 Oktober 2026.

Isi · System Design