Laravel Migrations – Complete Guide

Table of Contents

  1. Introduction
  2. Why Use Migrations in Laravel?
  3. Creating a Migration
  4. Migration File Structure
  5. Running and Rolling Back Migrations
  6. Common Migration Commands
  7. Adding and Modifying Columns
  8. Foreign Keys & Relationships
  9. Database Indexes
  10. Seeding and Factories
  11. Best Practices
  12. Conclusion

1. Introduction to Laravel Migrations

Migrations in Laravel are like version control for your database. They allow you to create, modify, and share database tables in a structured way. Instead of manually running SQL queries, you define your database structure in migration files, and Laravel manages the rest.

Think of migrations as a blueprint of your database that can be easily shared with your team. When you deploy to production, you just run php artisan migrate, and Laravel automatically updates the database schema.


2. Why Use Migrations in Laravel?

Without migrations, developers usually:

  • Create tables manually in phpMyAdmin or MySQL CLI.

  • Share SQL dumps with other developers.

  • Face errors due to mismatched table structures across environments.

With Laravel migrations:

  • You never manually create tables.

  • Your schema is always consistent across environments.

  • You can rollback changes if something goes wrong.

  • You can track schema changes in Git with your code.

👉 Migrations are a must-have in every professional Laravel application.


3. Creating a Migration

Use the Artisan command:

php artisan make:migration create_posts_table

This will create a new file in:

 
database/migrations/2025_09_19_123456_create_posts_table.php 

The file name has a timestamp + migration name.


4. Migration File Structure Explained

A typical migration file has two methods:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration {
    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');
    }
};
  • up() method → Runs when you apply the migration (php artisan migrate).

  • down() method → Runs when you rollback (php artisan migrate:rollback).


 

 

5. Common Migration Commands in Laravel

Laravel provides powerful Artisan commands to manage migrations.

Command Description
php artisan migrate Run all pending migrations
php artisan migrate:rollback Undo last batch of migrations
php artisan migrate:reset Rollback all migrations
php artisan migrate:refresh Rollback and re-run all migrations
php artisan migrate:fresh Drop all tables and re-run migrations
php artisan migrate:status Check migration status
php artisan make:migration Create a new migration

6. Adding and Modifying Columns in Migrations

You can define different column types in migrations.

Common Column Types

$table->id(); // Primary key
$table->string('title'); // VARCHAR
$table->text('description'); // TEXT
$table->integer('age'); // INT
$table->boolean('is_active'); // TINYINT(1)
$table->decimal('price', 8, 2); // Decimal(8,2)
$table->timestamps(); // created_at & updated_at
$table->softDeletes(); // deleted_at for soft delete

Column Modifiers

$table->string('email')->unique();
$table->integer('votes')->default(0);
$table->string('phone')->nullable();
$table->string('username', 50)->index();

👉 This makes it easy to add rules at the schema level.


7. Foreign Keys & Relationships in Migrations

Defining relationships directly in migrations ensures referential integrity.

Example: Posts & Users

Schema::create('posts', function (Blueprint $table) {
    $table->id();
    $table->string('title');
    $table->foreignId('user_id')->constrained()->onDelete('cascade');
    $table->timestamps();
});
  • foreignId('user_id') → Creates user_id column.

  • constrained() → References id in users table.

  • onDelete('cascade') → Deletes posts if user is deleted.


8. Database Indexes in Migrations

Indexes improve query performance.

$table->string('email')->unique(); // Unique index
$table->index('created_at'); // Simple index
$table->fullText('content'); // Full-text search

9. Seeding and Factories with Migrations

While migrations define your schema, seeders and factories help you populate test data.

Run Seeder

 
php artisan db:seed 

Example Seeder

DB::table('users')->insert([
    'name' => 'John Doe',
    'email' => 'john@example.com',
    'password' => bcrypt('password'),
]);

👉 Use seeders with migrations for quick testing and demo data.


10. Best Practices for Laravel Migrations

  • Always use plural names for tables (users, posts).

  • Keep migrations small and focused.

  • Never manually edit a table in phpMyAdmin → always use migrations.

  • Use rollback-friendly migrations (define down() method properly).

  • Test migrations locally before pushing to production.

  • Use softDeletes() if you want to restore deleted records.

  • Keep schema consistent using version control.


11. Conclusion

In this lesson, we explored Laravel Migrations from beginner to advanced level. You learned how to:

  • Create migrations with Artisan

  • Run and rollback migrations

  • Define schema with columns, modifiers, and indexes

  • Create foreign keys for relationships

  • Use seeding and factories with migrations

  • Follow best practices for production-ready apps

Migrations give your Laravel project structure, flexibility, and teamwork compatibility.