Home / Artikel / Web Development
Web Development

Deploy Fitur Baru tanpa Merusak Database: Panduan Praktis Database Migration

Kode aplikasi bisa kembali ke versi lama, tetapi perubahan struktur database tidak selalu mudah dibatalkan. Database migration membantu tim mengelola perubahan tabel, kolom, dan indeks secara teratur agar proses deploy…

Deploy Fitur Baru tanpa Merusak Database: Panduan Praktis Database Migration

Menambahkan fitur baru ke website sering terlihat sederhana: buat kolom baru, ubah tabel, lalu deploy kode. Masalah biasanya muncul ketika perubahan database dilakukan langsung di server produksi tanpa catatan yang jelas. Aplikasi bisa gagal membaca data, proses rollback menjadi rumit, atau developer tidak lagi tahu perubahan apa saja yang sudah diterapkan.

Database migration adalah cara menyimpan perubahan struktur database dalam bentuk file atau skrip yang memiliki urutan jelas. Dengan pendekatan ini, perubahan database diperlakukan seperti kode aplikasi: bisa ditinjau, diuji, dicatat dalam version control, dan diterapkan secara konsisten di berbagai lingkungan.

Mengapa perubahan database perlu dikelola seperti kode?

Bayangkan sebuah tim memiliki database lokal, database untuk pengujian, dan database produksi. Jika perubahan dilakukan manual menggunakan phpMyAdmin atau perintah SQL yang diketik langsung, ketiga lingkungan itu mudah memiliki struktur berbeda.

Di komputer developer, kolom phone_number mungkin sudah tersedia. Namun di server pengujian, kolom tersebut belum dibuat. Aplikasi terlihat baik di komputer lokal, tetapi gagal ketika diuji di tempat lain. Tanpa migration, penyebabnya sering baru diketahui setelah error muncul.

Migration memberikan beberapa manfaat praktis:

  • Riwayat perubahan jelas: setiap perubahan memiliki nama, waktu, dan tujuan yang dapat ditelusuri.
  • Lingkungan lebih konsisten: database lokal, staging, dan produksi dapat mengikuti urutan perubahan yang sama.
  • Review lebih mudah: perubahan SQL dapat diperiksa bersama kode aplikasi sebelum diterapkan.
  • Deploy lebih dapat diulang: developer baru atau server baru tidak perlu menebak-nebak struktur database terakhir.

Contoh sederhana: menambahkan kolom baru

Misalnya aplikasi toko online ingin menyimpan waktu terakhir pelanggan masuk. Perubahan ini dapat ditulis sebagai migration:

ALTER TABLE users
ADD COLUMN last_login_at DATETIME NULL;

Dalam sistem migration modern, perintah tersebut biasanya dibungkus dalam file dengan fungsi up untuk menerapkan perubahan dan fungsi down untuk membatalkannya:

public function up()
{
    Schema::table('users', function ($table) {
        $table->dateTime('last_login_at')->nullable();
    });
}

public function down()
{
    Schema::table('users', function ($table) {
        $table->dropColumn('last_login_at');
    });
}

Contoh tersebut memakai gaya sintaks framework PHP. Nama fungsi dan format file dapat berbeda pada Laravel, Symfony, Phinx, Doctrine, atau tool lain. Prinsipnya tetap sama: satu perubahan penting disimpan sebagai satu langkah yang dapat dilacak.

Migration bukan sekadar kumpulan perintah SQL

Kesalahan umum adalah menganggap migration hanya sebagai tempat menyimpan SQL. Padahal, migration juga perlu menjadi bagian dari strategi perubahan aplikasi.

Jika kolom baru langsung dibuat sebagai NOT NULL, sementara kode lama masih melakukan insert tanpa mengisi kolom tersebut, deploy dapat gagal. Karena itu, perubahan database dan perubahan aplikasi perlu direncanakan dalam urutan yang aman.

Pola dua tahap untuk perubahan yang berisiko

  1. Tambahkan struktur baru terlebih dahulu. Buat kolom baru sebagai nullable atau berikan nilai default yang aman.
  2. Deploy kode yang kompatibel. Kode baru mulai menulis data ke kolom tersebut, tetapi masih dapat bekerja jika kolom belum terisi.
  3. Isi data lama secara bertahap. Jika perlu, jalankan proses backfill untuk mengisi nilai pada baris lama.
  4. Perketat aturan setelah aman. Setelah semua data lengkap, barulah kolom dapat diubah menjadi wajib atau diberi indeks tertentu.

Pola ini sering disebut expand and contract. Tahap expand menambahkan struktur tanpa memutus kompatibilitas. Tahap contract menghapus struktur lama setelah tidak lagi digunakan.

Hati-hati saat menghapus atau mengganti nama kolom

Menambahkan kolom biasanya relatif aman. Sebaliknya, menghapus kolom atau mengganti namanya bisa berdampak langsung pada kode lama, laporan, job terjadwal, dan integrasi lain.

Contohnya, kolom name ingin diganti menjadi full_name. Cara yang lebih aman bukan langsung menghapus name. Tambahkan full_name, ubah aplikasi agar menulis ke keduanya untuk sementara, salin data lama, lalu pastikan tidak ada kode yang membaca name. Setelah masa transisi selesai, kolom lama dapat dihapus melalui migration terpisah.

Rollback juga perlu dipahami dengan realistis. Perintah down memang dapat mengembalikan struktur, tetapi belum tentu dapat mengembalikan data yang sudah terhapus atau berubah. Karena itu, rollback migration bukan pengganti backup.

Index: kecil di skrip, besar dampaknya

Migration juga sering digunakan untuk menambahkan index, yaitu struktur tambahan yang membantu database menemukan data lebih cepat. Misalnya, kolom email yang sering dicari dapat diberi index unik:

CREATE UNIQUE INDEX users_email_unique
ON users (email);

Namun index bukan solusi otomatis untuk semua query. Terlalu banyak index dapat memperbesar ukuran database dan membuat proses insert atau update lebih berat karena database harus memperbarui index tersebut. Sebelum menambah index, lihat pola query yang benar-benar digunakan dan periksa rencana eksekusinya bila tersedia.

Checklist sebelum menjalankan migration di produksi

  • Uji migration pada salinan database atau lingkungan staging.
  • Pastikan ada backup yang sudah diuji pemulihannya, bukan sekadar file backup yang belum pernah dibuka.
  • Periksa apakah perubahan dapat mengunci tabel terlalu lama.
  • Pastikan aplikasi versi lama tetap aman selama proses deploy bertahap.
  • Ukur jumlah data yang perlu diubah jika migration melakukan backfill.
  • Catat estimasi waktu, risiko, dan langkah pemulihan.
  • Jalankan perubahan pada waktu dengan trafik rendah jika dampaknya sulit diprediksi.

Apa artinya bagi kita?

Database migration bukan fitur khusus untuk perusahaan besar. Website PHP sederhana, toko online kecil, hingga aplikasi internal akan lebih mudah dirawat jika perubahan database memiliki sejarah yang jelas.

Yang bisa dilakukan sekarang adalah memeriksa perubahan database terakhir. Apakah ada yang hanya tersimpan di catatan pribadi? Apakah database lokal berbeda dengan server produksi? Jika jawabannya ya, mulai dengan membuat migration untuk perubahan berikutnya. Tidak perlu langsung memindahkan seluruh sejarah lama. Yang penting, mulai membangun kebiasaan bahwa perubahan struktur database harus dapat dibaca, diuji, dan diulang.

Dengan cara ini, deploy tidak lagi bergantung pada ingatan satu orang. Tim memiliki jejak perubahan yang sama, risiko dapat dibahas sebelum eksekusi, dan masalah database lebih mudah ditangani ketika aplikasi terus berkembang.

– Rio Yotto @rioyotto