Laravel Database Migrations: Schema Blueprints & Evolution

Migrations are like version control for your database schema. Instead of manually creating tables inside phpMyAdmin, MySQL Workbench, or pgAdmin, migrations allow your team to define database tables, column types, foreign keys, and indexes using expressive PHP code that can be shared via Git and reproduced automatically on any machine.

1. Anatomy of a Migration File

Generate a new migration using Artisan:

php artisan make:migration create_articles_table

This creates a timestamped file in database/migrations/2026_01_01_000000_create_articles_table.php containing an anonymous class with up() and down() methods:

<?php

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

return new class extends Migration
{
    /**
     * Run the migrations (Builds the table).
     */
    public function up(): void
    {
        Schema::create('articles', function (Blueprint $table) {
            $table->id(); // BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY
            
            // Relational Foreign Key linked to users table
            $table->foreignId('user_id')->constrained()->cascadeOnDelete();
            
            $table->string('title', 255)->index();
            $table->string('slug')->unique();
            $table->text('body');
            $table->boolean('is_published')->default(false);
            $table->timestamp('published_at')->nullable();
            
            // Adds created_at and updated_at TIMESTAMP columns automatically
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations (Drops the table on rollback).
     */
    public function down(): void
    {
        Schema::dropIfExists('articles');
    }
};

2. Common Blueprint Column Types & Modifiers

Column Blueprint Method SQL Equivalent Common Use Case
$table->id() BIGINT UNSIGNED AUTO_INC Standard primary key
$table->string('code', 50) VARCHAR(50) Short text, titles, emails
$table->text('content') TEXT Long article descriptions
$table->decimal('price', 10, 2) DECIMAL(10,2) Currency & financial numbers (Never use float!)
$table->json('settings') JSON Structured dynamic data / preferences
$table->softDeletes() TIMESTAMP nullable Recycle bin / soft deletion (deleted_at)

3. Migration Artisan Commands

# Run all pending migrations
php artisan migrate

# Roll back the absolute last batch of migrations
php artisan migrate:rollback

# Roll back all migrations in history
php artisan migrate:reset

# Drop all tables and re-run all migrations from day one
php artisan migrate:fresh

# Check migration status across all files
php artisan migrate:status

BCA/MCA Exam Viva Question: migrate:refresh vs migrate:fresh

migrate:refresh runs the down() method of each migration to rollback before running up() again. migrate:fresh completely drops all tables directly from the database schema without calling down(), making it much faster during local prototyping.

Frequently Asked Questions (FAQ) - Student & Interview Review

Q1. What does $table->foreignId('user_id')->constrained()->cascadeOnDelete() do?

It creates a foreign key column matching the users table primary key. If a user is deleted from the users table, all related records belonging to that user are deleted automatically by the database engine.

Q2. Can I modify an existing column in a new migration?

Yes! Create a new migration and use the ->change() modifier: $table->string('title', 500)->change();. Laravel 11 natively supports modifying columns without requiring the doctrine/dbal package.

Q3. How does Laravel keep track of which migrations have already run?

Laravel creates a special 'migrations' table in your database on its first run. It logs the migration filename and batch number. Running 'php artisan migrate' only executes files not yet logged in that table.

Explore Related Laravel Tutorials & Next Steps

Broaden your backend architecture, REST API design, and enterprise production engineering expertise:

Database Configuration & Queries

Configure database connections and drivers in config/database.php.

Seeders & Model Factories with Faker

Populate newly migrated tables with rich, realistic mock data for testing.

Eloquent Relationships & Foreign Keys

Define foreign key constraints in migrations that support Eloquent relations.

Production Migration Workflows

Run migrations safely during zero-downtime production deployment pipelines.

Share Share on Facebook Share on Twitter Share on LinkedIn Pin on Pinterest Share on Reddit

You may also like this!