Back to Blog Database & Performance

Dasar Database Relasional & SQL

Contoh kasus: toko online

Satu pelanggan dapat membuat banyak pesanan. Satu pesanan memiliki banyak item. Satu produk bisa muncul pada banyak item pesanan.

Database relasional menyimpan fakta dalam tabel yang saling terhubung lewat key. Desain yang baik mengurangi duplikasi dan menjaga data tetap konsisten ketika aplikasi tumbuh.

Modelkan relasi sebelum menulis query

SQL
CREATE TABLE customers (
  id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(120) NOT NULL,
  email VARCHAR(190) NOT NULL UNIQUE
);
CREATE TABLE orders (
  id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
  customer_id BIGINT UNSIGNED NOT NULL,
  status VARCHAR(30) NOT NULL,
  created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT fk_orders_customer
    FOREIGN KEY (customer_id) REFERENCES customers(id)
);
CREATE TABLE order_items (
  order_id BIGINT UNSIGNED NOT NULL,
  product_id BIGINT UNSIGNED NOT NULL,
  quantity INT UNSIGNED NOT NULL,
  unit_price DECIMAL(12,2) NOT NULL,
  PRIMARY KEY (order_id, product_id)
);

Harga disalin ke order_items.unit_price karena pesanan adalah catatan historis. Jika harga produk berubah besok, total pesanan kemarin tidak boleh ikut berubah.

SELECT yang menjawab pertanyaan bisnis

SQL
SELECT
  o.id,
  c.name AS customer,
  SUM(oi.quantity * oi.unit_price) AS total
FROM orders o
JOIN customers c ON c.id = o.customer_id
JOIN order_items oi ON oi.order_id = o.id
WHERE o.created_at >= CURRENT_DATE - INTERVAL 30 DAY
GROUP BY o.id, c.name
ORDER BY total DESC;

Normalisasi secukupnya

MasalahContoh burukPerbaikan
Data berulangNama pelanggan disimpan di setiap pesananSimpan customer_id dan gunakan relasi.
Nilai majemukKolom produk berisi “1,4,9”Buat tabel order_items.
Atribut bergantung sebagianNama produk di tabel dengan primary key gabunganPindahkan ke tabel products.
Riwayat berubahTotal dihitung dari harga produk terkiniSimpan unit_price saat transaksi.

Transaction menjaga perubahan tetap utuh

Pembuatan pesanan, pengurangan stok, dan penyimpanan item harus berhasil bersama. Bila salah satu gagal, seluruh operasi dibatalkan.

SQL
START TRANSACTION;
INSERT INTO orders (customer_id, status) VALUES (42, 'pending');
SET @order_id = LAST_INSERT_ID();
INSERT INTO order_items (order_id, product_id, quantity, unit_price)
VALUES (@order_id, 7, 2, 125000);
UPDATE products SET stock = stock - 2 WHERE id = 7 AND stock >= 2;
COMMIT;

SQL yang baik dimulai dari model data yang benar. Query canggih tidak dapat sepenuhnya menyelamatkan struktur tabel yang keliru.

Share this article

Related articles

Copied