Skip to content

Migrations

Giới thiệu (Introduction)

Migrations là version control cho database. Cho phép team định nghĩa và chia sẻ database schema. Kết hợp với schema builder, migrations giúp xây dựng database schema dễ dàng.

Tạo Migrations (Generating)

bash
php artisan make:migration create_flights_table

Migration mới nằm trong database/migrations. Tên file chứa timestamp để xác định thứ tự.

bash
# Chỉ định path
php artisan make:migration create_flights_table --path=database/custom

# Tự động tạo table
php artisan make:migration create_flights_table --create=flights

# Tự động chỉnh sửa table
php artisan make:migration add_destination_to_flights_table --table=flights

Squashing Migrations

Gộp migrations thành 1 SQL file:

bash
php artisan schema:dump
php artisan schema:dump --prune  # Gộp + xóa migrations cũ

Cấu trúc Migration

php
<?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('flights', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('airline');
            $table->timestamps();
        });
    }

    public function down(): void
    {
        Schema::drop('flights');
    }
};

Chạy Migrations (Running)

bash
php artisan migrate

# Xem SQL sẽ chạy (không thực thi)
php artisan migrate --pretend

# Isolated (chỉ 1 server chạy khi deploy cluster)
php artisan migrate --isolated

Rolling Back

bash
php artisan migrate:rollback          # Rollback batch cuối
php artisan migrate:rollback --step=5 # Rollback 5 migrations
php artisan migrate:reset             # Rollback tất cả
php artisan migrate:refresh           # Rollback + migrate lại
php artisan migrate:refresh --seed    # Rollback + migrate + seed
php artisan migrate:fresh             # Drop tất cả tables + migrate
php artisan migrate:fresh --seed

Tables

Tạo table

php
Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('email');
    $table->timestamps();
});

Kiểm tra tồn tại

php
if (Schema::hasTable('users')) {
    // ...
}

if (Schema::hasColumn('users', 'email')) {
    // ...
}

Table Options

php
Schema::create('users', function (Blueprint $table) {
    $table->engine('InnoDB');
    $table->charset('utf8mb4');
    $table->collation('utf8mb4_unicode_ci');
    $table->temporary(); // Temporary table
    $table->comment('Bảng users');
});

Đổi tên / Xóa Tables

php
Schema::rename('from', 'to');
Schema::drop('users');
Schema::dropIfExists('users');

Columns

Column Types phổ biến

php
$table->id();                        // Auto-increment bigint
$table->bigIncrements('id');
$table->bigInteger('votes');
$table->boolean('confirmed');
$table->char('name', 100);
$table->date('created_at');
$table->dateTime('created_at');
$table->decimal('amount', 8, 2);
$table->double('amount');
$table->enum('difficulty', ['easy', 'hard']);
$table->float('amount');
$table->foreignId('user_id');
$table->integer('votes');
$table->json('options');
$table->jsonb('options');
$table->longText('description');
$table->mediumText('description');
$table->smallInteger('votes');
$table->string('name', 100);
$table->text('description');
$table->time('sunrise');
$table->timestamp('added_at');
$table->timestamps();                // created_at + updated_at
$table->softDeletes();               // deleted_at
$table->uuid('id');
$table->ulid('id');
$table->vector('embedding', 1536);   // Vector column (pgvector)
$table->year('birth_year');

Column Modifiers

php
$table->string('email')->nullable();
$table->string('email')->default('default@example.com');
$table->integer('votes')->unsigned();
$table->string('name')->comment('Tên đầy đủ');
$table->string('email')->unique();
$table->string('name')->after('email');      // MySQL
$table->string('name')->first();             // MySQL
$table->string('name')->charset('utf8');
$table->string('name')->collation('utf8_unicode_ci');
$table->softDeletes()->precision(0);

Sửa đổi Columns

php
// Đổi loại, size
$table->string('name', 50)->change();

// Đổi tên
$table->renameColumn('from', 'to');

// Xóa column
$table->dropColumn('votes');
$table->dropColumn(['votes', 'avatar', 'location']);

Indexes

php
// Tạo index
$table->string('email')->unique();               // Unique index
$table->index('account_id');                     // Basic index
$table->unique('email');                         // Unique index
$table->index(['account_id', 'created_at']);     // Composite index
$table->fullText('body');                        // Full-text index
$table->spatialIndex('location');                // Spatial index

// Rename / Drop index
$table->renameIndex('from', 'to');
$table->dropPrimary('users_id_primary');
$table->dropUnique('users_email_unique');
$table->dropIndex('geo_state_index');
$table->dropFullText('posts_body_fulltext');
$table->dropSpatialIndex('geo_location_spatialindex');

Foreign Key Constraints

php
$table->foreignId('user_id')
    ->constrained()      // References users.id
    ->onUpdate('cascade')
    ->onDelete('cascade');

// Shorthand
$table->foreignId('user_id')
    ->constrained()
    ->cascadeOnUpdate()
    ->cascadeOnDelete();

// Nullable foreign key
$table->foreignId('user_id')
    ->nullable()
    ->constrained();

// Drop foreign key
$table->dropForeign('posts_user_id_foreign');
$table->dropForeign(['user_id']);

// Toggle foreign key constraints
Schema::enableForeignKeyConstraints();
Schema::disableForeignKeyConstraints();
Schema::withoutForeignKeyConstraints(function () {
    // ...
});