Migration Builder Reference
Learn the syntax for creating well-structured database migrations.
📋 Column Types Reference
$$table->id()
Auto-increment primary key
$$table->string()
VARCHAR (default 255)
$$table->text()
TEXT column
$$table->integer()
INTEGER column
$$table->bigInteger()
BIGINT column
$$table->decimal()
DECIMAL column (for money)
$$table->boolean()
BOOLEAN column
$$table->date()
DATE column
$$table->datetime()
DATETIME column
$$table->timestamp()
TIMESTAMP column
$$table->json()
JSON column
$$table->foreignId()
Foreign key column
🔧 Column Modifiers
->nullable()
Allow NULL values
Example: $table->string('name')->nullable()
->default()
Set default value
Example: $table->string('name')->default()
->unique()
Add unique constraint
Example: $table->string('name')->unique()
->index()
Add index for performance
Example: $table->string('name')->index()
->unsigned()
Only positive numbers
Example: $table->string('name')->unsigned()
💡 Complete Migration Example
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->string('title', 200);
$table->text('content');
$table->boolean('published')->default(false);
$table->timestamp('published_at')->nullable();
$table->timestamps();
$table->index('published');
});
🔗 Foreign Keys & Relationships
Basic Foreign Key
$table->foreignId('user_id')
->constrained()
->onDelete('cascade');
Creates a foreign key to the 'users' table with cascade delete
Custom Foreign Key
$table->foreignId('author_id')
->constrained('users') // References 'users' table
->onDelete('set null')
->nullable();
Foreign key to a different table with set null on delete
onDelete Actions
- •
cascade- Delete related records - •
set null- Set foreign key to NULL - •
restrict- Prevent deletion if related records exist - •
no action- Do nothing (database default)
⚡ Indexes for Performance
Single Column Index
$table->index('email');
Speed up queries filtering by email
Composite Index
$table->index(['user_id', 'created_at']);
Optimize queries using both columns
Unique Index
$table->unique('email');
Ensure no duplicate emails
Index on Definition
$table->string('slug')->unique();
Add index while defining column
✨ Migration Best Practices
✅ Do:
- • Use descriptive migration names
-
•
Always provide a
down()method - • Add foreign keys for referential integrity
- • Index frequently queried columns
- • Use appropriate data types (decimal for money)
- • Keep migrations focused (one table/change)
❌ Don't:
- • Edit migrations after they've run in production
- • Forget to add indexes on foreign keys
-
•
Use
string()without a length for large text - • Hardcode IDs or data in migrations
- • Mix schema changes with data changes
- • Forget to handle nullable columns properly
⚙️ Artisan Commands
php artisan make:migration create_posts_table
php artisan make:migration add_status_to_posts_table --table=posts
php artisan migrate
php artisan migrate:rollback
php artisan migrate:fresh
php artisan migrate:fresh --seed
php artisan migrate:status