Laravel Migration: Panduan Membuat dan Mengelola Struktur Database
Database adalah salah satu bagian paling penting dalam aplikasi Laravel. Seiring aplikasi berkembang, struktur database juga biasanya ikut berubah: tabel baru ditambahkan, kolom diperbarui, index dibuat, atau relasi antartabel disesuaikan.
Jika perubahan tersebut dilakukan secara manual melalui database client, tim development akan kesulitan mengetahui perubahan apa saja yang pernah dilakukan.
Di sinilah Laravel Migration berperan.
Migration memungkinkan struktur database didefinisikan menggunakan kode sehingga perubahan database dapat disimpan, dibagikan, dan dijalankan kembali secara konsisten di berbagai environment.
Apa Itu Laravel Migration?
Laravel Migration adalah mekanisme version control untuk struktur database.
Konsepnya mirip dengan Git, tetapi fokusnya pada perubahan schema database.
Misalnya, awalnya aplikasi hanya memiliki tabel users. Kemudian kebutuhan aplikasi berkembang dan membutuhkan tabel posts.
Daripada setiap developer membuat tabel tersebut secara manual, perubahan dapat dibuat dalam sebuah migration:
Migration 1
↓
users table
Migration 2
↓
posts table
Migration 3
↓
comments table
Laravel kemudian dapat menjalankan migration tersebut sesuai urutan.
Mengapa Migration Penting?
Tanpa migration, perubahan database sering dilakukan secara manual.
Misalnya:
Developer A
↓
Menambahkan kolom manually
Developer B
↓
Tidak tahu kolom tersebut sudah ditambahkan
Production
↓
Struktur database berbeda
Dengan migration, perubahan menjadi terdokumentasi:
Migration
↓
Version control
↓
Development
↓
Testing
↓
Production
Beberapa manfaat migration:
- Struktur database tersimpan sebagai kode.
- Perubahan database dapat dilacak melalui Git.
- Developer baru dapat menyiapkan database dengan lebih mudah.
- Schema dapat dibuat konsisten antar-environment.
- Perubahan database dapat dilakukan secara bertahap.
- Laravel menyediakan mekanisme rollback.
Membuat Migration Baru
Migration dibuat menggunakan Artisan.
Contoh:
php artisan make:migration create_posts_table
Laravel akan membuat file migration di:
database/migrations/
Nama file biasanya memiliki timestamp, misalnya:
2026_08_27_120000_create_posts_table.php
Timestamp tersebut membantu Laravel menentukan urutan migration.
Struktur Dasar Migration
Migration biasanya memiliki dua method utama:
public function up(): void
{
//
}
public function down(): void
{
//
}
Method up() digunakan untuk menerapkan perubahan.
Method down() digunakan untuk membatalkan perubahan tersebut.
Contoh sederhana:
public function up(): void
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('posts');
}
Jika migration dijalankan, tabel posts dibuat.
Jika migration di-rollback, tabel tersebut dapat dihapus melalui method down().
Memahami Schema::create()
Untuk membuat tabel baru, Laravel menyediakan:
Schema::create()
Contohnya:
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->decimal('price', 12, 2);
$table->integer('stock');
$table->timestamps();
});
Hasil akhirnya secara konsep akan menjadi tabel seperti:
products
├── id
├── name
├── price
├── stock
├── created_at
└── updated_at
Migration menjadi representasi kode dari struktur tersebut.
Tipe Kolom yang Sering Digunakan
Laravel menyediakan banyak jenis kolom melalui Blueprint.
Beberapa yang paling sering digunakan:
$table->id();
$table->string('name');
$table->text('description');
$table->integer('stock');
$table->boolean('is_active');
$table->date('published_at');
$table->dateTime('scheduled_at');
$table->decimal('price', 12, 2);
$table->timestamps();
Contoh tabel user sederhana:
Schema::create('customers', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->string('phone')->nullable();
$table->boolean('is_active')->default(true);
$table->timestamps();
});
Apa Fungsi timestamps()?
Baris:
$table->timestamps();
biasanya membuat dua kolom:
created_at
updated_at
created_at digunakan untuk mencatat kapan record dibuat.
updated_at digunakan untuk mencatat kapan record terakhir diperbarui.
Kolom ini sangat umum digunakan bersama Eloquent.
Membuat Foreign Key
Migration juga digunakan untuk mendefinisikan relasi database.
Misalnya sebuah post dimiliki oleh seorang user.
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')
->constrained()
->cascadeOnDelete();
$table->string('title');
$table->text('content');
$table->timestamps();
});
Dengan struktur tersebut, posts.user_id menjadi foreign key yang mengacu pada tabel users.
Relasi database sebaiknya dipikirkan sebelum migration dibuat karena perubahan struktur relasional di kemudian hari dapat menjadi lebih kompleks.
Mengubah Tabel yang Sudah Ada
Migration tidak hanya digunakan untuk membuat tabel.
Misalnya tabel users sudah ada dan Anda ingin menambahkan kolom phone.
Buat migration baru:
php artisan make:migration add_phone_to_users_table
Kemudian:
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
$table->string('phone')->nullable();
});
}
Method down() sebaiknya mengembalikan perubahan:
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('phone');
});
}
Perhatikan bahwa Anda tidak perlu mengubah migration lama yang sudah pernah digunakan.
Buat migration baru untuk perubahan baru.
Kenapa Migration Lama Sebaiknya Tidak Diubah?
Misalnya migration pertama membuat:
users
├── id
├── name
└── email
Beberapa minggu kemudian Anda membutuhkan:
users
├── id
├── name
├── email
└── phone
Cara yang lebih aman adalah membuat migration baru:
Migration 1
create_users_table
Migration 2
add_phone_to_users_table
Bukan mengubah isi create_users_table yang sudah pernah dijalankan.
Alasannya sederhana: migration merupakan riwayat perubahan schema.
Jika migration lama diubah setelah pernah dijalankan pada environment lain, struktur database antar-environment dapat menjadi tidak sinkron.
Menjalankan Migration
Untuk menjalankan migration yang belum pernah dijalankan:
php artisan migrate
Laravel akan memeriksa tabel migrations untuk mengetahui migration mana yang sudah dijalankan.
Migration yang belum dijalankan kemudian dieksekusi berdasarkan urutan timestamp.
Melihat Status Migration
Untuk melihat migration yang sudah dan belum dijalankan:
php artisan migrate:status
Output-nya dapat membantu ketika Anda sedang mencari tahu apakah sebuah migration sudah diterapkan.
Misalnya secara konsep:
Migration Status
2026_08_27_120000_create_users_table Ran
2026_08_27_121000_create_posts_table Ran
2026_08_27_122000_add_phone_to_users_table Pending
Dari sini Anda dapat mengetahui migration mana yang masih belum dijalankan.
Rollback Migration
Jika ingin membatalkan batch migration terakhir:
php artisan migrate:rollback
Laravel akan menjalankan method down() dari migration pada batch terakhir.
Misalnya:
public function down(): void
{
Schema::dropIfExists('posts');
}
maka rollback akan menghapus tabel posts.
Rollback sangat berguna selama development ketika Anda ingin mengoreksi migration yang baru dibuat.
Reset dan Refresh Migration
Laravel juga menyediakan beberapa perintah untuk mengulang migration.
Untuk membatalkan seluruh migration:
php artisan migrate:reset
Untuk rollback seluruh migration kemudian menjalankannya kembali:
php artisan migrate:refresh
Untuk menghapus seluruh tabel kemudian menjalankan semua migration dari awal:
php artisan migrate:fresh
Perintah migrate:fresh perlu digunakan dengan hati-hati karena dapat menghapus seluruh tabel pada database yang digunakan.
Jangan sembarangan menjalankannya pada database production.
Migration dan Seeder Itu Berbeda
Migration sering disalahartikan sebagai mekanisme untuk mengisi data.
Padahal migration berfokus pada struktur database.
Seeder berfokus pada data awal atau data contoh.
Contohnya:
Migration
→ Membuat tabel users
Seeder
→ Membuat user administrator
Jadi keduanya memiliki tanggung jawab berbeda.
Dalam project Laravel, keduanya sering digunakan bersama:
php artisan migrate --seed
Perintah tersebut menjalankan migration sekaligus seeding sesuai konfigurasi aplikasi.
Migration dan Model Eloquent Juga Berbeda
Tiga komponen ini sering digunakan bersama, tetapi fungsinya berbeda:
Migration
→ Struktur database
Model
→ Representasi dan interaksi dengan data
Seeder
→ Mengisi data awal
Contohnya:
users table
↑
Migration
↑
User model
↑
Application
Memahami pembagian tanggung jawab ini membuat struktur project Laravel lebih mudah dirawat.
Kesalahan Umum: Menghapus Migration yang Sudah Pernah Dijalankan
Menghapus file migration dari repository tidak otomatis menghapus perubahan yang sudah diterapkan pada database.
Misalnya migration membuat tabel:
create_orders_table
Setelah migration dijalankan, kemudian file tersebut dihapus.
Database tetap dapat memiliki tabel orders.
Migration adalah catatan perubahan, bukan sinkronisasi otomatis dua arah antara file dan database.
Karena itu, jangan menghapus migration lama hanya karena migration tersebut sudah pernah dijalankan.
Kesalahan Umum: Membuat Perubahan Database Secara Manual
Developer kadang memperbaiki masalah dengan langsung menjalankan SQL:
ALTER TABLE users ADD COLUMN phone VARCHAR(255);
Masalahnya, perubahan tersebut belum tentu tercatat di repository.
Developer lain mungkin tidak memiliki kolom tersebut.
Production juga bisa memiliki struktur berbeda dengan development.
Untuk perubahan schema yang memang merupakan bagian dari aplikasi, migration biasanya menjadi pilihan yang lebih baik.
Kesalahan Umum: Salah Urutan Migration
Bayangkan migration pertama membuat:
posts
dengan foreign key:
user_id → users.id
Tetapi migration users dibuat setelah migration posts.
Hal ini dapat menyebabkan masalah ketika database menjalankan migration berdasarkan urutan timestamp.
Pastikan migration yang menyediakan tabel referensi dibuat atau dijalankan sebelum tabel yang bergantung padanya.
Contoh urutan yang masuk akal:
create_users_table
↓
create_posts_table
↓
create_comments_table
Kesalahan Umum: Mengandalkan Rollback di Production
Rollback terlihat sederhana:
php artisan migrate:rollback
Tetapi pada production, perubahan schema dapat berkaitan dengan data yang sudah digunakan aplikasi.
Misalnya migration menambahkan kolom:
phone
dan aplikasi sudah menyimpan data ke kolom tersebut.
Jika migration di-rollback dan kolom dihapus, data tersebut juga dapat hilang.
Karena itu, migration production perlu diperlakukan sebagai bagian penting dari proses deployment.
Untuk perubahan berisiko, pertimbangkan strategi migration yang kompatibel dengan versi aplikasi sebelum dan sesudah deployment.
Praktik yang Baik dalam Menulis Migration
Beberapa kebiasaan sederhana dapat membuat migration lebih mudah dikelola.
Gunakan Nama Migration yang Jelas
Contoh:
php artisan make:migration create_orders_table
atau:
php artisan make:migration add_status_to_orders_table
Nama tersebut langsung menjelaskan tujuan migration.
Satu Migration untuk Satu Perubahan Logis
Daripada membuat satu migration yang mengubah banyak hal sekaligus, pisahkan perubahan berdasarkan tujuan.
Misalnya:
create_orders_table
add_status_to_orders_table
add_payment_method_to_orders_table
Riwayat perubahan menjadi lebih mudah dipahami.
Selalu Perhatikan Method down()
Migration yang baik seharusnya memiliki rollback yang masuk akal.
Jika up() menambahkan kolom:
$table->string('phone')->nullable();
maka down() dapat menghapus kolom tersebut:
$table->dropColumn('phone');
Dengan begitu, migration memiliki arah maju dan mundur yang jelas.
Migration untuk Production
Menjalankan migration di production membutuhkan perhatian lebih besar dibandingkan development.
Sebelum deployment, pertimbangkan:
- Apakah migration kompatibel dengan versi aplikasi saat ini?
- Apakah ada perubahan yang berpotensi mengunci tabel dalam waktu lama?
- Apakah migration menghapus atau mengubah data?
- Apakah database sudah memiliki backup yang sesuai?
- Apakah proses deployment dapat melakukan rollback aplikasi jika migration gagal?
Untuk perubahan database yang besar, migration sebaiknya diuji terlebih dahulu pada database staging yang menyerupai production.
Kesimpulan
Laravel Migration membuat perubahan struktur database menjadi lebih terorganisir dan mudah dilacak.
Konsep penting yang perlu diingat:
- Migration adalah version control untuk struktur database.
up()digunakan untuk menerapkan perubahan.down()digunakan untuk membatalkan perubahan.- Gunakan migration baru untuk perubahan baru, bukan mengubah migration lama yang sudah digunakan.
migratemenjalankan migration yang masih pending.migrate:rollbackmembatalkan batch terakhir.migrate:freshdapat menghapus seluruh tabel, sehingga harus digunakan dengan sangat hati-hati.- Migration berbeda dari model dan seeder.
- Perubahan database production harus diperlakukan sebagai bagian penting dari deployment.
Jika migration dikelola dengan baik, struktur database tidak lagi menjadi sesuatu yang hanya tersimpan di server. Perubahannya menjadi bagian dari source code yang dapat ditinjau, diuji, dibagikan, dan dilacak bersama perkembangan aplikasi Laravel.

