Studi Kasus MySQL: Membuat Database Toko Online Sederhana
Akhirnya kita sampai di Bab 8, sekaligus bab terakhir dari Series Belajar Database MySQL dari Nol.
Selama tujuh bab sebelumnya, kita sudah mempelajari berbagai konsep dasar dan lanjutan MySQL.
Mulai dari mengenal database, memasang MySQL dan DBeaver, membuat tabel, menjalankan CRUD, menghubungkan tabel menggunakan foreign key dan JOIN, membuat laporan dengan GROUP BY, hingga mengenal index dan transaction.
Sekarang waktunya menggabungkan semuanya menjadi sebuah proyek kecil.
Kita akan membuat database toko online sederhana yang bisa menyimpan produk, pelanggan, pesanan, dan detail pembelian.
Di akhir tutorial, kita akan mempunyai database yang dapat digunakan untuk mencatat transaksi dan menghasilkan laporan penjualan.
Tentu saja, ini belum menjadi aplikasi e-commerce lengkap seperti marketplace besar.
Belum ada keranjang belanja, pembayaran otomatis, pengiriman, ataupun integrasi backend.
Namun, fondasi database yang kita buat sudah cukup untuk memahami bagaimana data transaksi saling terhubung.
Dan yang paling penting, seluruh praktik dapat dikerjakan langsung menggunakan MySQL dan DBeaver.
Apa yang Akan Kita Bangun?
Kita akan membuat empat tabel utama.
| Tabel | Fungsi |
|---|---|
pelanggan | Menyimpan informasi pelanggan |
produk | Menyimpan daftar produk, harga, dan stok |
pesanan | Menyimpan informasi pesanan |
detail_pesanan | Menyimpan daftar produk yang dibeli dalam setiap pesanan |
Hubungan antartabelnya:
pelanggan | | 1 : N | pesanan | | 1 : N |detail_pesanan | | N : 1 | produkSatu pelanggan dapat membuat banyak pesanan.
Satu pesanan dapat mempunyai banyak detail pembelian.
Satu produk dapat muncul dalam banyak detail pesanan.
Dengan struktur seperti ini, kita tidak perlu menyalin seluruh informasi pelanggan dan produk ke setiap baris transaksi.
Persiapan Sebelum Praktik
Pastikan kamu sudah mempunyai:
- MySQL Server yang berjalan.
- DBeaver yang terhubung ke MySQL.
- Akses untuk membuat database dan tabel.
- Pemahaman dasar tentang SQL.
Jika belum pernah memasang MySQL atau menggunakan DBeaver, kamu bisa membaca Bab 2 terlebih dahulu.
Penting: Pada bab ini kita menggunakan database baru bernama db_toko_bapakgabut_final.
Kita sengaja tidak menggunakan db_toko_bapakgabut dari bab sebelumnya.
Tujuannya agar pembaca bisa mengikuti studi kasus dari database kosong tanpa mengganggu data latihan yang sudah dibuat.
Langkah 1 — Membuat Database Baru
Buka SQL Editor pada DBeaver.
Kemudian jalankan:
CREATE DATABASE IF NOT EXISTS db_toko_bapakgabut_final;Setelah database dibuat, pilih database tersebut:
USE db_toko_bapakgabut_final;Untuk memastikan database aktif:
SELECT DATABASE() AS database_aktif;Hasil yang diharapkan:
db_toko_bapakgabut_finalPerintah CREATE DATABASE IF NOT EXISTS tidak menghapus database yang sudah ada.
Namun, jika database dengan nama tersebut sudah berisi tabel atau data dari latihan sebelumnya, isi tersebut tetap ada.
Agar hasil tutorial mudah diikuti, sebaiknya gunakan database yang benar-benar kosong.
Jangan menjalankan perintah penghapusan database jika masih ada data penting di dalamnya.
Langkah 2 — Membuat Tabel Pelanggan
Kita mulai dari tabel pelanggan.
CREATE TABLE pelanggan ( id_pelanggan INT AUTO_INCREMENT PRIMARY KEY, nama_pelanggan VARCHAR(100) NOT NULL, email VARCHAR(150) NOT NULL UNIQUE, tanggal_daftar DATE NOT NULL) ENGINE=InnoDB;Penjelasan:
id_pelangganmerupakan primary key.AUTO_INCREMENTmembuat ID bertambah otomatis.nama_pelangganmenyimpan nama pelanggan.emailmenyimpan alamat email.UNIQUEmencegah dua pelanggan menggunakan email yang sama.tanggal_daftarmenyimpan tanggal pendaftaran.
Pada studi kasus ini, kita menggunakan UNIQUE untuk email agar satu alamat email hanya digunakan oleh satu pelanggan.
Aturan tersebut merupakan keputusan desain untuk contoh aplikasi kita.
Langkah 3 — Membuat Tabel Produk
Sekarang kita membuat tabel produk.
CREATE TABLE produk ( id_produk INT AUTO_INCREMENT PRIMARY KEY, nama_produk VARCHAR(100) NOT NULL, harga DECIMAL(12,2) NOT NULL, stok INT NOT NULL DEFAULT 0, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, INDEX idx_produk_nama (nama_produk)) ENGINE=InnoDB;Kita menggunakan DECIMAL(12,2) untuk menyimpan harga agar perhitungan nominal tidak bergantung pada representasi floating point biner.
Kolom stok menggunakan nilai default nol.
Kita juga langsung membuat index pada nama_produk.
Index ini dapat membantu pencarian berdasarkan nama produk ketika jumlah data semakin besar dan kondisi query sesuai.
Pada tabel kecil, MySQL mungkin tetap memilih full table scan.
Langkah 4 — Membuat Tabel Pesanan
Tabel pesanan menyimpan informasi utama transaksi.
CREATE TABLE pesanan ( id_pesanan INT AUTO_INCREMENT PRIMARY KEY, id_pelanggan INT NOT NULL, tanggal_pesanan DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, status_pesanan VARCHAR(20) NOT NULL DEFAULT 'baru', CONSTRAINT fk_pesanan_pelanggan FOREIGN KEY (id_pelanggan) REFERENCES pelanggan(id_pelanggan) ON UPDATE RESTRICT ON DELETE RESTRICT, INDEX idx_pesanan_pelanggan_tanggal ( id_pelanggan, tanggal_pesanan )) ENGINE=InnoDB;Kolom id_pelanggan merupakan foreign key yang mengacu pada tabel pelanggan.
Artinya, setiap pesanan harus mempunyai pelanggan yang valid.
Kita menggunakan ON DELETE RESTRICT agar pelanggan yang masih mempunyai pesanan tidak dapat dihapus begitu saja.
Composite index pada id_pelanggan dan tanggal_pesanan disiapkan untuk mendukung pola pencarian riwayat pesanan berdasarkan pelanggan dan tanggal.
Langkah 5 — Membuat Tabel Detail Pesanan
Sekarang kita membuat tabel penghubung antara pesanan dan produk.
CREATE TABLE detail_pesanan ( id_detail INT AUTO_INCREMENT PRIMARY KEY, id_pesanan INT NOT NULL, id_produk INT NOT NULL, jumlah INT NOT NULL, harga_satuan DECIMAL(12,2) NOT NULL, CONSTRAINT fk_detail_pesanan FOREIGN KEY (id_pesanan) REFERENCES pesanan(id_pesanan) ON UPDATE RESTRICT ON DELETE RESTRICT, CONSTRAINT fk_detail_produk FOREIGN KEY (id_produk) REFERENCES produk(id_produk) ON UPDATE RESTRICT ON DELETE RESTRICT) ENGINE=InnoDB;Tabel tersebut mempunyai dua foreign key:
id_pesananmengacu pada tabelpesanan.id_produkmengacu pada tabelproduk.
Kita menyimpan harga_satuan pada detail transaksi karena harga produk dapat berubah di kemudian hari.
Misalnya, sebuah mouse dibeli seharga Rp135.000.
Jika harga produk naik menjadi Rp150.000 minggu depan, nilai transaksi lama harus tetap menggunakan harga saat pembelian.
Langkah 6 — Memeriksa Struktur Database
Sekarang jalankan:
SHOW TABLES;Hasil yang diharapkan:
pelangganprodukpesanandetail_pesananUrutan tampilannya bisa berbeda.
Untuk memeriksa struktur tabel:
DESCRIBE pelanggan;DESCRIBE produk;DESCRIBE pesanan;DESCRIBE detail_pesanan;Untuk melihat foreign key dan index secara lebih lengkap, gunakan:
SHOW CREATE TABLE pesanan;SHOW CREATE TABLE detail_pesanan;Sampai di sini, kita sudah menyelesaikan struktur dasar database toko online.
Langkah 7 — Mengisi Data Pelanggan
Sekarang kita tambahkan empat pelanggan.
INSERT INTO pelanggan ( nama_pelanggan, email, tanggal_daftar)VALUES ('Andi', 'andi@example.com', '2026-10-01'), ('Budi', 'budi@example.com', '2026-10-02'), ('Citra', 'citra@example.com', '2026-10-03'), ('Dina', 'dina@example.com', '2026-10-04');Periksa hasilnya:
SELECT *FROM pelangganORDER BY id_pelanggan;Karena email menggunakan UNIQUE, menjalankan INSERT yang sama untuk kedua kalinya akan menghasilkan error duplicate key.
Hal tersebut merupakan perilaku yang diharapkan.
Langkah 8 — Mengisi Data Produk
Tambahkan lima produk.
INSERT INTO produk ( nama_produk, harga, stok)VALUES ('Keyboard Mechanical', 325000, 20), ('Mouse Wireless', 135000, 25), ('Monitor 24 Inch', 1650000, 8), ('USB Flashdisk 64GB', 85000, 40), ('Headset Gaming', 275000, 12);Periksa:
SELECT id_produk, nama_produk, harga, stokFROM produkORDER BY id_produk;Sekarang toko kita sudah mempunyai pelanggan dan produk.
Tetapi belum ada transaksi.
Kita akan menambahkan transaksi menggunakan transaction agar pembuatan pesanan, detail pembelian, dan pengurangan stok dilakukan sebagai satu kesatuan.
Langkah 9 — Membuat Transaksi Pembelian Pertama
Skenarionya:
Andi membeli satu Keyboard Mechanical dan dua Mouse Wireless.
Totalnya:
Keyboard Mechanical1 × 325000 = 325000
Mouse Wireless2 × 135000 = 270000
Total = 595000Kita akan menggunakan transaction.
Penting: Jalankan langkah-langkah berikut secara berurutan pada satu sesi koneksi MySQL yang sama.
Jangan langsung menjalankan COMMIT jika salah satu perintah gagal.
9.1 Menentukan ID Pelanggan dan Produk
Pertama, cari ID berdasarkan email dan nama produk.
SELECT id_pelanggan, nama_pelangganFROM pelangganWHERE email = 'andi@example.com';SELECT id_produk, nama_produk, harga, stokFROM produkWHERE nama_produk IN ( 'Keyboard Mechanical', 'Mouse Wireless');Jika data dimasukkan pada database kosong sesuai urutan tutorial, biasanya ID Andi adalah 1, Keyboard Mechanical adalah 1, dan Mouse Wireless adalah 2.
Namun, kita tidak akan bergantung pada asumsi tersebut.
Gunakan variabel sesi:
SET @id_andi = ( SELECT id_pelanggan FROM pelanggan WHERE email = 'andi@example.com');
SET @id_keyboard = ( SELECT id_produk FROM produk WHERE nama_produk = 'Keyboard Mechanical' LIMIT 1);
SET @id_mouse = ( SELECT id_produk FROM produk WHERE nama_produk = 'Mouse Wireless' LIMIT 1);Pastikan semua variabel mempunyai nilai:
SELECT @id_andi AS id_andi, @id_keyboard AS id_keyboard, @id_mouse AS id_mouse;Jika salah satu bernilai NULL, jangan melanjutkan transaksi.
9.2 Memulai Transaction
Jalankan:
START TRANSACTION;Kunci baris produk yang akan dibeli:
SELECT id_produk, nama_produk, harga, stokFROM produkWHERE id_produk IN (@id_keyboard, @id_mouse)ORDER BY id_produkFOR UPDATE;Periksa bahwa:
- Stok Keyboard Mechanical minimal 1.
- Stok Mouse Wireless minimal 2.
Jika stok tidak mencukupi, jalankan:
ROLLBACK;Dan hentikan proses pembelian.
9.3 Membuat Pesanan
Jika stok mencukupi, buat pesanan:
INSERT INTO pesanan ( id_pelanggan, status_pesanan)VALUES ( @id_andi, 'baru');Ambil ID pesanan:
SET @id_pesanan_andi = LAST_INSERT_ID();9.4 Membuat Detail Pesanan
Tambahkan dua produk ke detail pesanan:
INSERT INTO detail_pesanan ( id_pesanan, id_produk, jumlah, harga_satuan)VALUES (@id_pesanan_andi, @id_keyboard, 1, 325000), (@id_pesanan_andi, @id_mouse, 2, 135000);Nilai harga satuan pada contoh ini merupakan harga transaksi yang sudah kita tetapkan.
Dalam aplikasi nyata, backend harus memastikan harga yang digunakan sesuai dengan aturan bisnis dan sumber harga tepercaya.
9.5 Mengurangi Stok
Sekarang kurangi stok keyboard:
UPDATE produkSET stok = stok - 1WHERE id_produk = @id_keyboard AND stok >= 1;Segera setelah UPDATE tersebut, periksa jumlah baris yang berubah:
SELECT ROW_COUNT() AS keyboard_diubah;Hasil yang diharapkan adalah 1.
Jika hasilnya bukan 1, jalankan ROLLBACK dan jangan lanjutkan.
Kemudian kurangi stok mouse:
UPDATE produkSET stok = stok - 2WHERE id_produk = @id_mouse AND stok >= 2;Segera periksa:
SELECT ROW_COUNT() AS mouse_diubah;Hasil yang diharapkan juga 1.
Jika hasilnya bukan 1, jalankan ROLLBACK.
9.6 Menyimpan Transaksi
Jika semua langkah berhasil, jalankan:
COMMIT;Sekarang pesanan Andi, detail pembelian, dan pengurangan stok sudah disimpan bersama.
Jika ada error sebelum COMMIT, jalankan ROLLBACK pada sesi yang sama.
Catatan: Transaction ini merupakan latihan manual. Pada aplikasi produksi, seluruh proses biasanya diatur oleh backend yang menangani error, retry, validasi harga, dan status transaksi secara terprogram.
Langkah 10 — Membuat Transaksi Pembelian Kedua
Sekarang Budi membeli satu Monitor 24 Inch.
Harga transaksinya Rp1.650.000.
Pertama, ambil ID:
SET @id_budi = ( SELECT id_pelanggan FROM pelanggan WHERE email = 'budi@example.com');
SET @id_monitor = ( SELECT id_produk FROM produk WHERE nama_produk = 'Monitor 24 Inch' LIMIT 1);Periksa:
SELECT @id_budi AS id_budi, @id_monitor AS id_monitor;Jika ID tersedia, mulai transaksi:
START TRANSACTION;Kunci baris monitor:
SELECT id_produk, nama_produk, stokFROM produkWHERE id_produk = @id_monitorFOR UPDATE;Pastikan stok minimal satu.
Jika tidak mencukupi, jalankan ROLLBACK dan hentikan proses.
Buat pesanan:
INSERT INTO pesanan ( id_pelanggan, status_pesanan)VALUES ( @id_budi, 'baru');Ambil ID pesanan:
SET @id_pesanan_budi = LAST_INSERT_ID();Tambahkan detail:
INSERT INTO detail_pesanan ( id_pesanan, id_produk, jumlah, harga_satuan)VALUES ( @id_pesanan_budi, @id_monitor, 1, 1650000);Kurangi stok:
UPDATE produkSET stok = stok - 1WHERE id_produk = @id_monitor AND stok >= 1;Segera periksa:
SELECT ROW_COUNT() AS monitor_diubah;Jika hasilnya 1 dan seluruh langkah sebelumnya berhasil:
COMMIT;Jika gagal:
ROLLBACK;Sampai di sini, kita mempunyai dua pesanan contoh.
Langkah 11 — Menampilkan Riwayat Transaksi dengan JOIN
Sekarang kita ingin menampilkan laporan transaksi.
Gunakan query:
SELECT p.id_pesanan, pl.nama_pelanggan, pr.nama_produk, dp.jumlah, dp.harga_satuan, dp.jumlah * dp.harga_satuan AS subtotalFROM pesanan pINNER JOIN pelanggan pl ON p.id_pelanggan = pl.id_pelangganINNER JOIN detail_pesanan dp ON p.id_pesanan = dp.id_pesananINNER JOIN produk pr ON dp.id_produk = pr.id_produkORDER BY p.id_pesanan, dp.id_detail;Jika mengikuti seluruh langkah dengan database kosong, hasilnya kurang lebih:
| Pelanggan | Produk | Jumlah | Subtotal |
|---|---|---|---|
| Andi | Keyboard Mechanical | 1 | 325000 |
| Andi | Mouse Wireless | 2 | 270000 |
| Budi | Monitor 24 Inch | 1 | 1650000 |
ID pesanan mengikuti nilai AUTO_INCREMENT pada database masing-masing.
Langkah 12 — Membuat Laporan Total Pembelian
Kita ingin mengetahui total nilai pembelian setiap pelanggan.
SELECT pl.id_pelanggan, pl.nama_pelanggan, SUM(dp.jumlah * dp.harga_satuan) AS total_pembelianFROM pelanggan plINNER JOIN pesanan p ON pl.id_pelanggan = p.id_pelangganINNER JOIN detail_pesanan dp ON p.id_pesanan = dp.id_pesananGROUP BY pl.id_pelanggan, pl.nama_pelangganORDER BY total_pembelian DESC;Hasil yang diharapkan:
| Pelanggan | Total Pembelian |
|---|---|
| Budi | 1650000 |
| Andi | 595000 |
Citra dan Dina tidak muncul karena belum mempunyai transaksi.
Jika ingin menampilkan seluruh pelanggan, kita bisa menggunakan LEFT JOIN.
SELECT pl.id_pelanggan, pl.nama_pelanggan, COUNT(DISTINCT p.id_pesanan) AS jumlah_pesanan, COALESCE( SUM(dp.jumlah * dp.harga_satuan), 0 ) AS total_pembelianFROM pelanggan plLEFT JOIN pesanan p ON pl.id_pelanggan = p.id_pelangganLEFT JOIN detail_pesanan dp ON p.id_pesanan = dp.id_pesananGROUP BY pl.id_pelanggan, pl.nama_pelangganORDER BY total_pembelian DESC;Sekarang Citra dan Dina tetap muncul dengan total pembelian nol.
Langkah 13 — Membuat Laporan Produk Terlaris
Untuk menghitung total unit produk yang terjual:
SELECT pr.id_produk, pr.nama_produk, SUM(dp.jumlah) AS total_terjualFROM produk prINNER JOIN detail_pesanan dp ON pr.id_produk = dp.id_produkGROUP BY pr.id_produk, pr.nama_produkORDER BY total_terjual DESC;Hasil contoh:
| Produk | Unit Terjual |
|---|---|
| Mouse Wireless | 2 |
| Keyboard Mechanical | 1 |
| Monitor 24 Inch | 1 |
Tetapi jika ingin mencari produk dengan nilai penjualan terbesar, gunakan:
SELECT pr.id_produk, pr.nama_produk, SUM(dp.jumlah) AS total_unit, SUM(dp.jumlah * dp.harga_satuan) AS total_nilaiFROM produk prINNER JOIN detail_pesanan dp ON pr.id_produk = dp.id_produkGROUP BY pr.id_produk, pr.nama_produkORDER BY total_nilai DESC;Dalam data latihan, Monitor 24 Inch menghasilkan nilai penjualan terbesar.
Ingat bahwa “produk terlaris” dapat memiliki arti berbeda tergantung metrik yang digunakan.
Langkah 14 — Menghitung Total Nilai Penjualan
Sekarang kita ingin mengetahui total nilai seluruh detail pembelian.
SELECT COALESCE( SUM(jumlah * harga_satuan), 0 ) AS total_penjualanFROM detail_pesanan;Jika hanya ada dua transaksi dari tutorial ini, hasilnya:
2245000.00Nilai tersebut berasal dari:
Andi = 595000Budi = 1650000----------------Total = 2245000Pada studi kasus ini, nilai tersebut merupakan total nominal pembelian yang tercatat.
Dalam aplikasi nyata, perhitungan omzet final biasanya perlu memperhatikan status pembayaran, pembatalan, retur, diskon, pajak, dan aturan bisnis lainnya.
Langkah 15 — Menggunakan HAVING
Sekarang kita ingin menampilkan pelanggan dengan total pembelian lebih dari Rp500.000.
SELECT pl.id_pelanggan, pl.nama_pelanggan, SUM(dp.jumlah * dp.harga_satuan) AS total_pembelianFROM pelanggan plINNER JOIN pesanan p ON pl.id_pelanggan = p.id_pelangganINNER JOIN detail_pesanan dp ON p.id_pesanan = dp.id_pesananGROUP BY pl.id_pelanggan, pl.nama_pelangganHAVING SUM(dp.jumlah * dp.harga_satuan) > 500000ORDER BY total_pembelian DESC;Pada data latihan, Andi dan Budi memenuhi kondisi tersebut.
HAVING digunakan karena kita memfilter hasil perhitungan agregasi.
Langkah 16 — Menggunakan Subquery
Kita ingin mencari produk yang harganya lebih tinggi dari rata-rata harga produk.
SELECT id_produk, nama_produk, hargaFROM produkWHERE harga > ( SELECT AVG(harga) FROM produk)ORDER BY harga DESC;Subquery menghitung rata-rata harga seluruh produk.
Query luar kemudian menampilkan produk yang harganya melebihi nilai tersebut.
Kita juga dapat mencari pelanggan yang belum pernah membuat pesanan menggunakan NOT EXISTS.
SELECT pl.id_pelanggan, pl.nama_pelangganFROM pelanggan plWHERE NOT EXISTS ( SELECT 1 FROM pesanan p WHERE p.id_pelanggan = pl.id_pelanggan);Pada data contoh, hasilnya adalah Citra dan Dina.
Langkah 17 — Memeriksa Index dan EXPLAIN
Kita sudah membuat index pada nama produk dan index gabungan pada pesanan.
Periksa:
SHOW INDEX FROM produk;SHOW INDEX FROM pesanan;Sekarang gunakan EXPLAIN:
EXPLAINSELECT id_produk, nama_produk, hargaFROM produkWHERE nama_produk = 'Keyboard Mechanical';Perhatikan kolom possible_keys, key, type, dan rows.
Jika index tidak digunakan, bukan berarti ada kesalahan.
Tabel kita masih sangat kecil, sehingga optimizer mungkin memilih membaca seluruh tabel.
Index biasanya lebih terasa manfaatnya ketika jumlah data dan pola pencarian memang mendukung penggunaannya.
Langkah 18 — Memeriksa Stok Setelah Transaksi
Kita juga perlu memastikan stok berubah sesuai transaksi.
SELECT nama_produk, stokFROM produkORDER BY id_produk;Jika mengikuti data awal dan kedua transaksi berhasil, stok yang diharapkan adalah:
| Produk | Stok Akhir |
|---|---|
| Keyboard Mechanical | 19 |
| Mouse Wireless | 23 |
| Monitor 24 Inch | 7 |
| USB Flashdisk 64GB | 40 |
| Headset Gaming | 12 |
Keyboard berkurang satu.
Mouse berkurang dua.
Monitor berkurang satu.
Produk lainnya tidak berubah.
Jika hasilnya berbeda, periksa apakah transaksi pernah dijalankan lebih dari sekali atau ada perubahan data tambahan.
Langkah 19 — Memahami Batasan Database yang Kita Buat
Database toko online ini sudah mempunyai fondasi relasional yang cukup baik untuk latihan.
Namun, masih ada beberapa hal yang belum kita implementasikan.
Validasi Data
Kita belum menambahkan semua aturan untuk mencegah nilai tidak valid.
Misalnya, jumlah pembelian seharusnya lebih dari nol.
Harga dan stok juga seharusnya tidak negatif.
Pada MySQL 8.0.16 atau lebih baru, kita dapat mempertimbangkan CHECK constraint.
Contohnya:
ALTER TABLE detail_pesananADD CONSTRAINT chk_detail_jumlahCHECK (jumlah > 0);ALTER TABLE produkADD CONSTRAINT chk_produk_stokCHECK (stok >= 0);Perintah tersebut akan gagal jika data yang sudah ada melanggar aturan.
Karena itu, periksa data sebelum menambahkan constraint pada database yang sudah digunakan.
Status Pembayaran
Tabel pesanan saat ini hanya mempunyai status sederhana.
Dalam aplikasi nyata, biasanya diperlukan informasi pembayaran, metode pembayaran, dan status pembayaran yang lebih rinci.
Pengiriman
Kita belum menyimpan alamat pengiriman, jasa pengiriman, atau nomor resi.
Perubahan Harga dan Diskon
Kita sudah menyimpan harga satuan pada detail transaksi.
Namun, belum ada sistem diskon, voucher, pajak, dan perhitungan total akhir yang lebih kompleks.
Audit dan Riwayat Perubahan
Aplikasi yang lebih besar mungkin membutuhkan catatan perubahan data, pengguna yang melakukan perubahan, serta waktu perubahan.
Keamanan Akses
Aplikasi produksi perlu menggunakan akun database dengan hak akses yang sesuai, query berparameter, pengelolaan kredensial yang aman, backup, dan pengawasan aktivitas.
Jangan menggunakan akun database dengan hak administrator untuk seluruh operasi aplikasi.
Semua hal tersebut dapat dikembangkan secara bertahap.
Tujuan studi kasus ini adalah memahami fondasi database, bukan langsung membangun marketplace berskala besar.
Latihan Akhir Series
Sekarang kita akan menguji pemahaman dari Bab 1 sampai Bab 8.
Coba kerjakan latihan berikut menggunakan database db_toko_bapakgabut_final.
Latihan 1 — Tambahkan Produk Baru
Tambahkan produk:
- Nama: Webcam HD.
- Harga: Rp225.000.
- Stok: 10.
Kemudian tampilkan seluruh produk.
Latihan 2 — Tambahkan Pelanggan Baru
Tambahkan pelanggan:
- Nama: Eko.
- Email:
eko@example.com. - Tanggal daftar:
2026-10-10.
Latihan 3 — Buat Transaksi Pembelian
Buat transaksi pembelian untuk Eko:
- Produk: Webcam HD.
- Jumlah: 2.
- Harga satuan: Rp225.000.
Gunakan transaction.
Pastikan stok tersedia sebelum membuat pesanan.
Jika seluruh langkah berhasil, lakukan COMMIT.
Jika ada kegagalan, lakukan ROLLBACK.
Latihan 4 — Buat Laporan Penjualan
Buat query untuk menampilkan:
- Nama pelanggan.
- Jumlah pesanan.
- Total pembelian.
Urutkan berdasarkan total pembelian terbesar.
Latihan 5 — Cari Produk yang Belum Pernah Terjual
Buat query untuk menampilkan produk yang belum pernah muncul pada tabel detail pesanan.
Gunakan NOT EXISTS atau LEFT JOIN.
Coba kerjakan sendiri terlebih dahulu sebelum melihat pembahasannya.
Pembahasan Latihan Akhir
Jawaban Latihan 1
INSERT INTO produk ( nama_produk, harga, stok)VALUES ( 'Webcam HD', 225000, 10);Periksa:
SELECT *FROM produkORDER BY id_produk;Jawaban Latihan 2
INSERT INTO pelanggan ( nama_pelanggan, email, tanggal_daftar)VALUES ( 'Eko', 'eko@example.com', '2026-10-10');Periksa:
SELECT *FROM pelangganWHERE email = 'eko@example.com';Jawaban Latihan 3
Pertama, ambil ID:
SET @id_eko = ( SELECT id_pelanggan FROM pelanggan WHERE email = 'eko@example.com');
SET @id_webcam = ( SELECT id_produk FROM produk WHERE nama_produk = 'Webcam HD' LIMIT 1);Pastikan kedua ID tersedia:
SELECT @id_eko AS id_eko, @id_webcam AS id_webcam;Mulai transaksi:
START TRANSACTION;Kunci produk:
SELECT id_produk, nama_produk, stokFROM produkWHERE id_produk = @id_webcamFOR UPDATE;Pastikan stok minimal dua.
Jika tidak mencukupi, jalankan ROLLBACK dan hentikan proses.
Buat pesanan:
INSERT INTO pesanan ( id_pelanggan, status_pesanan)VALUES ( @id_eko, 'baru');Ambil ID pesanan:
SET @id_pesanan_eko = LAST_INSERT_ID();Tambahkan detail:
INSERT INTO detail_pesanan ( id_pesanan, id_produk, jumlah, harga_satuan)VALUES ( @id_pesanan_eko, @id_webcam, 2, 225000);Kurangi stok:
UPDATE produkSET stok = stok - 2WHERE id_produk = @id_webcam AND stok >= 2;Segera periksa:
SELECT ROW_COUNT() AS jumlah_baris_diubah;Jika hasilnya 1 dan seluruh langkah sebelumnya berhasil, jalankan:
COMMIT;Jika ada kegagalan:
ROLLBACK;Setelah transaksi berhasil, stok Webcam HD seharusnya berkurang dari 10 menjadi 8.
Jawaban Latihan 4
SELECT pl.id_pelanggan, pl.nama_pelanggan, COUNT(DISTINCT p.id_pesanan) AS jumlah_pesanan, COALESCE( SUM(dp.jumlah * dp.harga_satuan), 0 ) AS total_pembelianFROM pelanggan plLEFT JOIN pesanan p ON pl.id_pelanggan = p.id_pelangganLEFT JOIN detail_pesanan dp ON p.id_pesanan = dp.id_pesananGROUP BY pl.id_pelanggan, pl.nama_pelangganORDER BY total_pembelian DESC;Jawaban Latihan 5
SELECT pr.id_produk, pr.nama_produkFROM produk prWHERE NOT EXISTS ( SELECT 1 FROM detail_pesanan dp WHERE dp.id_produk = pr.id_produk);Query tersebut menampilkan produk yang belum pernah tercatat dalam detail pembelian.
Jika kamu sudah menyelesaikan seluruh latihan, berarti kamu sudah mempraktikkan sebagian besar konsep utama dari series ini.
Apa Langkah Selanjutnya Setelah Belajar MySQL?
Setelah memahami dasar MySQL, ada beberapa arah pembelajaran yang bisa kamu lanjutkan.
Pertama, belajar backend API.
Kamu dapat membuat aplikasi menggunakan Node.js dan Express, lalu menghubungkannya ke MySQL.
Dengan begitu, query yang sebelumnya dijalankan secara manual melalui DBeaver dapat digunakan oleh aplikasi.
Kedua, belajar desain database yang lebih kompleks.
Misalnya, menambahkan tabel pembayaran, alamat pengiriman, riwayat stok, dan audit log.
Ketiga, memperdalam optimasi database.
Kamu bisa mempelajari index, execution plan, locking, isolation level, dan strategi pengelolaan query pada data yang lebih besar.
Keempat, belajar keamanan database.
Pelajari prepared statement, pembatasan hak akses, backup, pemulihan data, dan pengelolaan kredensial.
Database bukan hanya soal menyimpan data.
Database juga tentang bagaimana menjaga data tetap benar, mudah diakses, aman, dan dapat digunakan ketika kebutuhan aplikasi berkembang.
Penutup Series Belajar Database MySQL dari Nol
Kita sudah menyelesaikan delapan bab:
- Apa Itu Database? Mengenal Database, DBMS, dan MySQL.
- Cara Install MySQL dan Menghubungkannya ke DBeaver.
- Belajar SQL Dasar: CREATE TABLE, Tipe Data, dan Primary Key.
- Belajar SQL CRUD: INSERT, SELECT, UPDATE, dan DELETE.
- Relasi Tabel MySQL: Foreign Key dan JOIN.
- Query SQL Lanjutan: GROUP BY, HAVING, dan Subquery.
- Index dan Transaction MySQL: Bikin Query Lebih Efisien dan Aman.
- Studi Kasus MySQL: Membuat Database Toko Online Sederhana.
Dari awalnya hanya mengenal istilah database, sekarang kita sudah bisa membuat struktur tabel, menghubungkan data, mencatat transaksi, dan menghasilkan laporan.
Tentu perjalanan belajar database tidak berhenti di sini.
Masih banyak hal yang bisa dipelajari, terutama ketika kita mulai menghubungkan database dengan aplikasi backend dan frontend.
Namun, dengan fondasi yang sudah dibangun selama delapan bab ini, kita mempunyai bekal untuk melanjutkan ke tahap berikutnya.
Terima kasih sudah mengikuti Series Database BapakGabut sampai selesai.
Semoga tutorial ini membantu kamu memahami MySQL dengan cara yang lebih praktis dan tidak terlalu membingungkan.
Sampai jumpa di series berikutnya, Gabuters!
Bagikan Artikel
Buat poster berbagi atau salin tautan artikel ini.
Lanjut membaca
Coba jalur lain
Pilihan konsisten dari artikel lain
Terakhir diperbarui pada , 20 hari yang lalu
Sebagian konten mungkin sudah tidak berlaku