Урок 11

Практические паттерны миграций

Порядок создания

Миграции выполняются в порядке имён файлов. Имя начинается с даты. Если таблица posts ссылается на users, users должна быть создана раньше. Laravel генерирует имена по текущему времени, поэтому миграции создаются в правильном порядке, если ты создаёшь их последовательно.

Одна миграция — одно изменение

Не смешивай в одной миграции создание таблицы и добавление колонки в другую. Лучше несколько маленьких миграций.

Миграции и модели

Миграция описывает схему, модель — логику. Если ты переименовал колонку в миграции, обнови модель (fillable, casts).

Заполнение данными в миграции

Иногда нужно заполнить справочник сразу после создания таблицы:

public function up(): void
{
    Schema::create('roles', function (Blueprint $table) {
        $table->id();
        $table->string('name')->unique();
        $table->timestamps();
    });

    DB::table('roles')->insert([
        ['name' => 'admin', 'created_at' => now(), 'updated_at' => now()],
        ['name' => 'user', 'created_at' => now(), 'updated_at' => now()],
    ]);
}

Но лучше для этого использовать сидер.

Транзакции

PostgreSQL и MySQL поддерживают транзакционный DDL. Если миграция упадёт — изменения откатятся. Laravel не оборачивает миграции в транзакцию автоматически, но можно указать:

public $withinTransaction = true;

Условные миграции

public function up(): void
{
    if (!Schema::hasColumn('posts', 'status')) {
        Schema::table('posts', function (Blueprint $table) {
            $table->string('status')->default('draft');
        });
    }
}

Миграции без down

Если откат невозможен (например, удалил колонку с данными):

public function down(): void
{
    // невозможно восстановить данные
}

Отдельные миграции для индексов

Иногда индексы добавляют отдельной миграцией, чтобы не блокировать таблицу при создании:

php artisan make:migration add_indexes_to_posts_table --table=posts
public function up(): void
{
    Schema::table('posts', function (Blueprint $table) {
        $table->index('status');
        $table->index('published_at');
    });
}

Антипаттерны

  • Редактирование накатанной миграции
  • Использование migrate:fresh на продакшене
  • Отсутствие down
  • Смешивание схемы и данных в одной миграции
  • Долгие блокирующие операции без учёта нагрузки