What migrations are and why they exist
Beginner5 min read·lv-14-001
sqlinterview
Concept
Migrations are version-controlled database schema changes. Instead of manually altering the database or sharing SQL dump files, migrations are PHP files that describe schema changes in code — committed to the repository alongside application code.
Why migrations:
- Version control: Schema changes are tracked in git, with history, authorship, and diffs.
- Repeatability: Any developer can run
php artisan migrateand get the same schema. - Environments: Dev, staging, and production schemas stay in sync.
- Rollback:
migrate:rollbackundoes the last batch of migrations, enabling recovery from bad deploys. - Team collaboration: Multiple developers can add migrations independently; conflicts in migration files are explicit.
How migrations work:
- Migration files live in
database/migrations/, namedYYYY_MM_DD_HHMMSS_description.php. php artisan migratereads all migrations not yet in themigrationstable.- Runs each migration's
up()method. - Records the migration name and
batchnumber in themigrationstable. migrate:rollbackfinds the latest batch and runs each migration'sdown()method.
The migrations table: Created by php artisan migrate on first run. Stores migration (filename), batch (integer). All migrations in one migrate run share the same batch number.
Schema facade: Illuminate\Support\Facades\Schema. Used inside migrations to create/modify tables.
Code Example
php
<?php
// database/migrations/2024_01_15_120000_create_orders_table.php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
// up() — apply the change
public function up(): void
{
Schema::create('orders', function (Blueprint $table) {
$table->id(); // BIGINT UNSIGNED AUTO INCREMENT PRIMARY KEY
$table->foreignId('user_id')
->constrained()
->onDelete('cascade');
$table->decimal('total', 10, 2);
$table->string('status', 20)->default('pending');
$table->timestamps(); // created_at, updated_at
});
}
// down() — undo the change (for rollback)
public function down(): void
{
Schema::dropIfExists('orders');
}
};
// Running migrations
// php artisan migrate → run all pending migrations
// php artisan migrate --force → run in production (bypasses prompt)
// php artisan migrate:status → show which migrations have run
// php artisan migrate:rollback → roll back last batch
// php artisan migrate:rollback --step=3 → roll back 3 batches
// php artisan migrate:reset → roll back ALL migrations
// php artisan migrate:fresh → drop all tables + re-migrate (dev only!)
// php artisan migrate:fresh --seed → fresh migrate + seed
// php artisan migrate:refresh → rollback all + re-migrate