Studi Kasus #1: Aplikasi Wisata Indonesia – Gambaran Proyek dan Perancangan Database


Studi Kasus #1: Aplikasi Wisata Indonesia – Gambaran Proyek dan Perancangan Database

Halo, calon developer handal! 

Selamat datang di seri studi kasus Aplikasi Wisata Indonesia. Di seri ini, kita akan membangun sebuah aplikasi web lengkap yang menampilkan informasi tempat wisata, penginapan, dan transportasi di Indonesia. Aplikasi ini akan memiliki halaman publik untuk melihat daftar dan detail, serta halaman admin untuk mengelola konten. Teknologi yang digunakan: Node.js (backend), React (frontend), dan MySQL (database).

Sebelum mulai ngoding, kita perlu merancang database dengan baik. Database adalah fondasi aplikasi. Jika rancangan database bagus, pengembangan selanjutnya akan lebih mudah. Di artikel pertama ini, kita akan membahas:

  • Gambaran umum proyek dan fitur-fitur yang akan dibuat.
  • Perancangan struktur database (ERD dan tabel).
  • Relasi antar tabel.
  • SQL untuk membuat tabel-tabel tersebut.

Yuk, kita mulai! 

Fitur Aplikasi Wisata Indonesia

Aplikasi yang akan kita bangun memiliki fitur-fitur berikut:

  • Halaman Publik:
    • Menampilkan daftar tempat wisata, penginapan, dan transportasi (bisa difilter berdasarkan kategori).
    • Halaman detail untuk masing-masing entitas yang menampilkan: foto cover, nama, lokasi, deskripsi, fasilitas, galeri foto, dan daftar paket/layanan beserta harga.
    • Fitur pencarian berdasarkan nama atau lokasi.
  • Halaman Admin (dengan autentikasi):
    • CRUD (Create, Read, Update, Delete) untuk kategori, tempat wisata, penginapan, transportasi, galeri, dan paket harga.
    • Upload gambar untuk cover dan galeri.

Untuk memenuhi fitur di atas, kita perlu menyimpan data seperti:

  • Kategori (misal: "Wisata Alam", "Hotel", "Travel")
  • Data tempat wisata, penginapan, transportasi (ada kesamaan, tapi bisa beda atribut). Kita bisa buat tabel terpisah atau satu tabel dengan tipe. Untuk fleksibilitas, kita buat tabel terpisah.
  • Galeri foto (bisa untuk semua entitas).
  • Paket/layanan (misal: tiket masuk, kamar hotel, sewa kendaraan) beserta harga.
  • User admin.

Perancangan Database

Kita akan menggunakan MySQL sebagai database. Berikut adalah struktur tabel yang akan kita buat. (Nama database: wisata_db)

Daftar Tabel

Nama Tabel Keterangan
categories Menyimpan kategori untuk wisata, penginapan, transportasi.
destinations Data tempat wisata.
accommodations Data penginapan (hotel, villa, homestay).
transportations Data transportasi (travel, rental mobil, dll).
galleries Menyimpan foto-foto (cover dan galeri) untuk semua entitas.
packages Menyimpan paket/layanan beserta harga (misal: tiket masuk, paket wisata, tipe kamar, dll).
users Data admin (untuk autentikasi).

Relasi Antar Tabel

Berikut adalah hubungan antar tabel:

  • destinations, accommodations, transportations masing-masing memiliki category_id yang merujuk ke categories(id).
  • galleries memiliki kolom entity_id dan entity_type untuk menghubungkan ke entitas mana gambar tersebut dimiliki. entity_type bisa bernilai 'destination', 'accommodation', 'transportation'.
  • packages juga memiliki entity_id dan entity_type dengan cara yang sama.
  • users berdiri sendiri.

Pendekatan dengan entity_type membuat kita tidak perlu membuat tabel galeri terpisah untuk setiap entitas, dan lebih mudah untuk dikembangkan.

Struktur Detail Tabel

1. Tabel categories

CREATE TABLE categories (
  id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  slug VARCHAR(100) NOT NULL UNIQUE,
  description TEXT,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

slug digunakan untuk URL ramah SEO (misal: "wisata-alam").

2. Tabel destinations

CREATE TABLE destinations (
  id INT AUTO_INCREMENT PRIMARY KEY,
  category_id INT NOT NULL,
  name VARCHAR(200) NOT NULL,
  slug VARCHAR(200) NOT NULL UNIQUE,
  location VARCHAR(255) NOT NULL,
  description TEXT,
  facilities TEXT, -- bisa diisi dengan daftar fasilitas dipisah koma atau JSON
  cover_image VARCHAR(255), -- path file gambar cover
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE CASCADE
);

3. Tabel accommodations

CREATE TABLE accommodations (
  id INT AUTO_INCREMENT PRIMARY KEY,
  category_id INT NOT NULL,
  name VARCHAR(200) NOT NULL,
  slug VARCHAR(200) NOT NULL UNIQUE,
  location VARCHAR(255) NOT NULL,
  description TEXT,
  facilities TEXT,
  cover_image VARCHAR(255),
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE CASCADE
);

4. Tabel transportations

CREATE TABLE transportations (
  id INT AUTO_INCREMENT PRIMARY KEY,
  category_id INT NOT NULL,
  name VARCHAR(200) NOT NULL,
  slug VARCHAR(200) NOT NULL UNIQUE,
  location VARCHAR(255) NOT NULL, -- misal lokasi kantor atau rute
  description TEXT,
  facilities TEXT, -- fasilitas kendaraan
  cover_image VARCHAR(255),
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE CASCADE
);

5. Tabel galleries

CREATE TABLE galleries (
  id INT AUTO_INCREMENT PRIMARY KEY,
  entity_type ENUM('destination', 'accommodation', 'transportation') NOT NULL,
  entity_id INT NOT NULL,
  image_url VARCHAR(255) NOT NULL,
  is_cover BOOLEAN DEFAULT FALSE, -- jika ingin menandai cover (bisa juga pakai kolom terpisah di tabel masing-masing)
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

entity_type dan entity_id menjadi foreign key secara implisit (tidak bisa pakai foreign key constraint karena beda tabel). Kita akan menjaga integritas melalui aplikasi.

6. Tabel packages

CREATE TABLE packages (
  id INT AUTO_INCREMENT PRIMARY KEY,
  entity_type ENUM('destination', 'accommodation', 'transportation') NOT NULL,
  entity_id INT NOT NULL,
  name VARCHAR(200) NOT NULL, -- misal "Paket Reguler", "Kamar Deluxe"
  description TEXT,
  price DECIMAL(10,2) NOT NULL,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

7. Tabel users

CREATE TABLE users (
  id INT AUTO_INCREMENT PRIMARY KEY,
  username VARCHAR(50) NOT NULL UNIQUE,
  email VARCHAR(100) NOT NULL UNIQUE,
  password_hash VARCHAR(255) NOT NULL,
  role ENUM('admin', 'editor') DEFAULT 'editor',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Diagram ERD (Sederhana)

Berikut adalah representasi teks hubungan antar tabel:

categories
    id (PK)
    name

destinations
    id (PK)
    category_id (FK -> categories.id)
    ...

accommodations
    id (PK)
    category_id (FK -> categories.id)
    ...

transportations
    id (PK)
    category_id (FK -> categories.id)
    ...

galleries
    id (PK)
    entity_type
    entity_id   (menunjuk ke destinations.id / accommodations.id / transportations.id)
    ...

packages
    id (PK)
    entity_type
    entity_id
    ...
💡 Catatan: Dengan menggunakan entity_type, kita bisa menyimpan data galeri dan paket untuk semua jenis entitas tanpa membuat banyak tabel. Namun, kita tidak bisa membuat foreign key constraint secara langsung. Alternatifnya, buat tabel terpisah (misal destination_galleries, accommodation_galleries) tapi akan lebih banyak tabel. Untuk proyek ini, pendekatan entity_type lebih sederhana.

Contoh Data Dummy

Untuk keperluan pengujian, kita bisa memasukkan data awal. Contoh:

INSERT INTO categories (name, slug) VALUES
('Wisata Alam', 'wisata-alam'),
('Wisata Budaya', 'wisata-budaya'),
('Hotel', 'hotel'),
('Villa', 'villa'),
('Travel', 'travel'),
('Rental Mobil', 'rental-mobil');

INSERT INTO destinations (category_id, name, slug, location, description, facilities, cover_image) VALUES
(1, 'Pantai Kuta', 'pantai-kuta', 'Bali', 'Pantai terkenal dengan pasir putih dan sunset.', 'Parkir, Toilet, Warung', 'kuta.jpg');

INSERT INTO galleries (entity_type, entity_id, image_url) VALUES
('destination', 1, 'kuta1.jpg'),
('destination', 1, 'kuta2.jpg');

INSERT INTO packages (entity_type, entity_id, name, description, price) VALUES
('destination', 1, 'Tiket Masuk', 'Tiket masuk dewasa', 15000),
('destination', 1, 'Tiket Anak', 'Tiket masuk anak-anak', 10000);

Langkah Selanjutnya

Setelah database siap, kita akan mulai membuat backend dengan Node.js dan Express. Di artikel selanjutnya (Studi Kasus #2), kita akan menyiapkan lingkungan development dan membuat server Express serta koneksi ke MySQL.

Pastikan kamu sudah menginstal MySQL dan bisa membuat database. Jika belum, silakan instal terlebih dahulu. Kita akan menggunakan database wisata_db.

Rangkuman

  • Kita telah merancang database untuk aplikasi wisata dengan tabel-tabel utama: categories, destinations, accommodations, transportations, galleries, packages, users.
  • Menggunakan konsep entity_type untuk menghubungkan galeri dan paket ke berbagai entitas.
  • Relasi yang jelas memudahkan pengembangan.

Jika ada pertanyaan atau masukan, silakan tulis di komentar. Sampai jumpa di tutorial berikutnya! 👋😊


Ditulis dengan ❤️ untuk para pengembang yang ingin membangun aplikasi wisata.

Lebih baru Lebih lama

نموذج الاتصال