Home / Artikel / Web Development
Web Development

Schema Database Bukan Sekadar Tabel: Cara Mengubah Struktur MySQL Tanpa Membuat Aplikasi Berhenti

Perubahan kecil pada database bisa membuat fitur gagal, data tidak terbaca, atau proses deploy berhenti di tengah jalan. Dengan strategi migration, kompatibilitas sementara, dan rollback yang jelas, perubahan schema MyS…

Schema Database Bukan Sekadar Tabel: Cara Mengubah Struktur MySQL Tanpa Membuat Aplikasi Berhenti

Menambah kolom pada tabel mungkin terlihat seperti pekerjaan sederhana. Namun di aplikasi web yang sedang dipakai pengguna, perubahan schema database dapat berdampak ke banyak hal sekaligus: query lama, endpoint API, laporan, proses background, hingga kode yang belum sempat ikut diperbarui.

Masalahnya sering bukan karena MySQL tidak mampu mengubah struktur tabel. Masalahnya adalah perubahan dilakukan tanpa memikirkan urutan. Aplikasi lebih dulu membaca kolom baru, padahal kolomnya belum ada. Atau kolom lama langsung dihapus ketika masih ada bagian sistem yang menggunakannya.

Karena itu, perubahan database sebaiknya diperlakukan seperti perubahan kode: dicatat, diuji, dapat ditinjau, dan memiliki jalan kembali.

Apa itu migration dan mengapa penting?

Migration adalah catatan perubahan struktur database yang dapat dijalankan secara teratur. Isinya bisa berupa pembuatan tabel, penambahan kolom, perubahan indeks, atau penghapusan struktur yang sudah tidak digunakan.

Tanpa migration, perubahan database biasanya dilakukan secara manual melalui phpMyAdmin atau terminal. Cara ini memang cepat untuk eksperimen, tetapi sulit dilacak ketika proyek memiliki lebih dari satu lingkungan, misalnya lokal, staging, dan production.

Dengan migration, tim dapat mengetahui:

  • Perubahan apa yang pernah dilakukan.
  • Urutan perubahan yang benar.
  • Versi schema yang sedang digunakan.
  • Langkah yang perlu dijalankan saat menyiapkan server baru.

Migration bukan sekadar alat untuk developer besar. Proyek kecil pun akan terbantu karena database tidak lagi bergantung pada ingatan satu orang.

Jangan langsung mengubah atau menghapus kolom lama

Salah satu kesalahan paling berisiko adalah melakukan perubahan yang tidak kompatibel dalam satu langkah. Contohnya, aplikasi memiliki kolom name, lalu kolom itu langsung diganti menjadi full_name. Jika masih ada kode lama yang menjalankan query terhadap name, aplikasi dapat mengalami error setelah deploy.

Pola yang lebih aman biasanya dilakukan dalam beberapa tahap.

  1. Tambahkan struktur baru tanpa menghapus struktur lama.
  2. Ubah aplikasi agar dapat menggunakan struktur baru.
  3. Pindahkan atau salin data lama ke struktur baru.
  4. Pastikan seluruh bagian aplikasi sudah tidak memakai struktur lama.
  5. Hapus struktur lama pada migration terpisah.

Pola ini sering disebut pendekatan expand and contract. Sistem diperluas terlebih dahulu agar mendukung bentuk baru, kemudian dipersempit setelah semua bagian siap.

Contoh: menambahkan status pesanan

Misalkan tabel orders selama ini hanya memiliki kolom is_paid bertipe angka atau boolean. Tim ingin menggantinya dengan status yang lebih jelas seperti pending, paid, shipped, dan cancelled.

Jangan langsung menghapus is_paid. Langkah pertama dapat berupa penambahan kolom baru:

ALTER TABLE orders
ADD COLUMN status VARCHAR(20) NOT NULL DEFAULT 'pending';

Setelah itu, data lama perlu dipetakan. Pesanan yang memiliki is_paid = 1 dapat diberi status paid, sedangkan sisanya tetap pending.

UPDATE orders
SET status = 'paid'
WHERE is_paid = 1;

Kode aplikasi kemudian diperbarui agar membaca status. Selama masa transisi, beberapa proses mungkin masih menulis ke is_paid. Karena itu, tim perlu menentukan sumber kebenaran dengan jelas. Jangan membiarkan dua kolom berubah tanpa aturan karena nilainya bisa berbeda.

Setelah semua proses sudah menggunakan status, kolom is_paid dapat dihapus melalui migration lain. Pemisahan ini membuat perubahan lebih mudah diuji dan mengurangi risiko saat deploy bertahap.

Perhatikan data lama, bukan hanya struktur baru

Migration sering diuji pada database kosong, lalu dianggap aman. Padahal masalah biasanya muncul pada database production yang berisi ratusan ribu atau jutaan baris.

Operasi seperti mengisi nilai untuk seluruh baris, membuat indeks besar, atau mengubah tipe data dapat membutuhkan waktu lama. Selama proses itu berlangsung, tabel mungkin terkunci atau query menjadi lebih lambat.

Sebelum menjalankan perubahan, periksa beberapa hal:

  • Berapa banyak baris yang akan diproses?
  • Apakah query perubahan memakai kondisi yang tepat?
  • Apakah kolom yang ditambahkan memiliki nilai default yang aman?
  • Apakah indeks baru benar-benar dibutuhkan?
  • Apakah perubahan dapat dijalankan bertahap?

Untuk data besar, proses backfill—yaitu mengisi data lama ke struktur baru—dapat dilakukan dalam batch kecil. Misalnya, aplikasi memproses beberapa ribu baris setiap kali jalan, bukan menjalankan satu pembaruan raksasa yang membebani database.

Migration bukan pengganti backup

Migration membantu mengubah schema secara konsisten, tetapi tidak otomatis melindungi data dari kesalahan. Sebelum perubahan penting, pastikan backup dapat dibuat dan benar-benar dapat dipulihkan.

Backup yang tidak pernah diuji hanya memberi rasa aman semu. Tim setidaknya perlu mengetahui kapan backup terakhir dibuat, bagaimana cara memulihkannya, dan berapa lama proses pemulihan berlangsung.

Untuk perubahan yang berisiko, siapkan juga rencana rollback. Namun perlu diingat, rollback struktur tidak selalu berarti data dapat dikembalikan. Jika sebuah kolom dihapus, data di dalamnya mungkin tidak bisa dipulihkan hanya dengan menjalankan perintah kebalikan.

Rollback yang baik bukan sekadar tombol “undo”. Ia harus menjawab: apa yang dikembalikan, dari backup mana, dan bagaimana aplikasi tetap berjalan selama proses tersebut?

Uji migration di lingkungan yang mirip production

Database lokal sering terlalu kecil dan terlalu bersih untuk menggambarkan kondisi nyata. Sebelum deploy, jalankan migration pada staging dengan struktur dan ukuran data yang mendekati production.

Selain memeriksa apakah migration berhasil, uji juga aplikasi setelah perubahan:

  • Apakah halaman lama masih dapat dibuka?
  • Apakah API tetap mengembalikan format yang diharapkan?
  • Apakah proses login, pembayaran, pencarian, dan laporan tetap berjalan?
  • Apakah waktu query berubah secara signifikan?
  • Apakah aplikasi versi lama masih dapat berjalan sementara?

Poin terakhir penting untuk sistem yang memakai beberapa server. Saat deploy berlangsung, tidak semua server selalu berganti versi pada detik yang sama. Schema baru sebaiknya tetap kompatibel untuk sementara dengan kode versi lama.

Yang bisa dilakukan sekarang

Mulailah dari aturan sederhana: setiap perubahan database harus memiliki migration yang tersimpan di repository. Beri nama migration berdasarkan tujuan, bukan hanya nomor, misalnya add_status_to_orders atau create_audit_logs_table.

Kemudian, gunakan checklist sebelum deploy:

  1. Apakah perubahan kompatibel dengan kode yang sedang berjalan?
  2. Apakah data lama sudah dipetakan dengan benar?
  3. Apakah migration sudah diuji pada data berukuran besar?
  4. Apakah ada backup dan prosedur pemulihan?
  5. Apakah langkah monitoring setelah deploy sudah ditentukan?

Perubahan schema yang aman bukan berarti tidak pernah gagal. Artinya, kegagalan dapat dideteksi lebih cepat, dampaknya terbatas, dan tim tahu langkah berikutnya. Dengan memperlakukan database sebagai bagian penting dari arsitektur aplikasi—bukan sekadar tempat menyimpan data—proses pengembangan menjadi lebih tenang dan dapat diprediksi.

– Rio Yotto @rioyotto