Идёт обновление сайта. Несколько дней возможны сбои в оформлении и переводах. Документация работает — если страница выглядит сломанной, обновите её позже.

Документация
L Laravel L intervention/image
Войти
Главная Laravel 10.x База данных: Миграции

База данных: Миграции

10.x 7 мар 2026 г.

#Введение

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

Фасад Laravel Schema facade предоставляет независимую от СУБД поддержку для создания и изменения таблиц во всех поддерживаемых Laravel системах баз данных. Обычно миграции используют этот фасад для создания и изменения таблиц и колонок базы данных.

#Создание миграций

Для генерации миграции базы данных можно использовать команду make:migration (команда Artisan). Новая миграция будет помещена в каталог database/migrations. Каждое имя файла миграции содержит метку времени, которая позволяет Laravel определить порядок миграций:

php artisan make:migration create_flights_table

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

Если вы хотите указать пользовательский путь для создаваемой миграции, используйте опцию --path при выполнении команды make:migration. Указанный путь должен быть относительным к базовому пути вашего приложения.

Примечание

Шаблоны миграций могут быть настроены с помощью публикации шаблонов.

#Объединение миграций

По мере развития приложения количество миграций может значительно увеличиваться. Это может привести к тому, что каталог database/migrations разрастётся до сотен файлов. При необходимости вы можете "объединить" миграции в один SQL-файл. Для начала выполните команду schema:dump:

php artisan schema:dump

# Сбросить текущую схему базы данных и удалить все существующие миграции...
php artisan schema:dump --prune

При выполнении этой команды Laravel создаст файл "схемы" в каталоге database/schema вашего приложения. Имя файла схемы будет соответствовать имени подключения к базе данных. Теперь, при попытке выполнить миграции, если другие миграции ещё не были выполнены, Laravel сначала выполнит SQL-запросы из файла схемы для используемого подключения к базе данных. После этого Laravel выполнит оставшиеся миграции, которые не были включены в дамп схемы.

Если тесты вашего приложения используют другое подключение к базе данных, отличное от того, что вы обычно используете при локальной разработке, убедитесь, что вы создали дамп схемы для этого подключения, чтобы тесты могли построить базу данных. Желательно сделать это после создания дампа для подключения, которое вы обычно используете при локальной разработке:

php artisan schema:dump
php artisan schema:dump --database=testing --prune

Рекомендуется добавить файл схемы базы данных в систему контроля версий, чтобы новые разработчики в вашей команде могли быстро создать начальную структуру базы данных приложения.

Внимание

Объединение миграций доступно только для баз данных MySQL, PostgreSQL и SQLite и использует командный клиент базы данных.

#Структура миграции

Класс миграции содержит два метода: up и down. Метод up используется для добавления новых таблиц, колонок или индексов в базу данных, а метод down должен отменять операции, выполненные методом up.

В обоих методах вы можете использовать конструктор схем Laravel для выразительного создания и изменения таблиц. Чтобы узнать обо всех доступных методах фасада Schema, ознакомьтесь с его документацией. Например, следующая миграция создаёт таблицу flights:

<?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');
    }
};

#Установка подключения для миграции

Если ваша миграция будет работать с подключением к базе данных, отличным от подключения по умолчанию вашего приложения, следует установить свойство $connection в классе миграции:

/**
 * Подключение к базе данных, которое должно использоваться миграцией.
 *
 * @var string
 */
protected $connection = 'pgsql';

/**
 * Запустить миграции.
 */
public function up(): void
{
    // ...
}

#Запуск миграций

Чтобы выполнить все ожидающие миграции, запустите Artisan-команду migrate:

php artisan migrate

Если вы хотите увидеть, какие миграции уже были выполнены, используйте Artisan-команду migrate:status:

php artisan migrate:status

Если вы хотите увидеть SQL-запросы, которые будут выполнены миграциями, без их фактического запуска, добавьте флаг --pretend к команде migrate:

php artisan migrate --pretend

#Изоляция выполнения миграций

Если вы разворачиваете приложение на нескольких серверах и запускаете миграции в процессе деплоя, вероятно, вы не хотите, чтобы два сервера одновременно пытались выполнить миграции. Чтобы избежать этого, используйте опцию isolated при вызове команды migrate.

При использовании опции isolated Laravel получит атомарную блокировку с помощью драйвера кэша вашего приложения перед запуском миграций. Все остальные попытки запустить команду migrate во время удержания блокировки не будут выполнены; однако команда завершится с успешным кодом возврата:

php artisan migrate --isolated
Внимание

Для использования этой функции ваше приложение должно использовать драйвер кэша memcached, redis, dynamodb, database, file или array в качестве драйвера кэша по умолчанию. Кроме того, все серверы должны работать с одним центральным сервером кэша.

#Принудительный запуск миграций в продакшене

Некоторые операции миграций являются разрушительными и могут привести к потере данных. Чтобы защитить вас от случайного запуска таких команд в продакшене, перед выполнением будет запрошено подтверждение. Чтобы принудительно выполнить команды без запроса, используйте флаг --force:

php artisan migrate --force

#Откат миграций

Чтобы откатить последнюю операцию миграции, используйте Artisan-команду rollback. Эта команда откатывает последний "пакет" миграций, который может включать несколько файлов миграций:

php artisan migrate:rollback

Вы можете откатить ограниченное количество миграций, указав опцию step для команды rollback. Например, следующая команда откатит последние пять миграций:

php artisan migrate:rollback --step=5

Вы можете откатить конкретный "пакет" миграций, указав опцию batch для команды rollback, где значение batch соответствует значению пакета в таблице migrations вашего приложения. Например, следующая команда откатит все миграции из пакета номер три:

 php artisan migrate:rollback --batch=3

Если вы хотите увидеть SQL-запросы, которые будут выполнены при откате миграций, без их фактического запуска, добавьте флаг --pretend к команде migrate:rollback:

php artisan migrate:rollback --pretend

Команда migrate:reset откатит все миграции вашего приложения:

php artisan migrate:reset

#Откат и миграция одной командой

Команда migrate:refresh откатит все миграции, а затем выполнит команду migrate. Эта команда фактически пересоздаёт всю базу данных:

php artisan migrate:refresh

# Обновить базу данных и выполнить все сиды...
php artisan migrate:refresh --seed

Вы можете откатить и повторно применить ограниченное количество миграций, указав опцию step для команды refresh. Например, следующая команда откатит и повторно применит последние пять миграций:

php artisan migrate:refresh --step=5

#Удаление всех таблиц и миграция

Команда migrate:fresh удалит все таблицы из базы данных, а затем выполнит команду migrate:

php artisan migrate:fresh

php artisan migrate:fresh --seed

По умолчанию команда migrate:fresh удаляет таблицы только из соединения с базой данных по умолчанию. Однако вы можете использовать опцию --database, чтобы указать соединение с базой данных, которое следует мигрировать. Имя соединения с базой данных должно соответствовать подключению, определённому в database файле конфигурации:

php artisan migrate:fresh --database=admin
Внимание

Команда migrate:fresh удалит все таблицы базы данных независимо от их префикса. Используйте эту команду с осторожностью при разработке на базе данных, которая используется другими приложениями.

#Таблицы

#Создание таблиц

Для создания новой таблицы базы данных используйте метод create фасада Schema. Метод create принимает два аргумента: первый — имя таблицы, второй — замыкание, которое получает объект Blueprint для определения структуры новой таблицы:

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

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

При создании таблицы вы можете использовать любые из методов колонок конструктора схемы для определения колонок таблицы.

#Проверка существования таблицы / колонки

Вы можете проверить существование таблицы или колонки с помощью методов hasTable и hasColumn:

if (Schema::hasTable('users')) {
    // Таблица "users" существует...
}

if (Schema::hasColumn('users', 'email')) {
    // Таблица "users" существует и содержит колонку "email"...
}

#Подключение к базе данных и опции таблицы

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

Schema::connection('sqlite')->create('users', function (Blueprint $table) {
    $table->id();
});

Кроме того, для определения других аспектов создания таблицы можно использовать несколько свойств и методов. Свойство engine позволяет указать движок хранения таблицы при использовании MySQL:

Schema::create('users', function (Blueprint $table) {
    $table->engine = 'InnoDB';

    // ...
});

Свойства charset и collation позволяют указать набор символов и сопоставление для создаваемой таблицы при использовании MySQL:

Schema::create('users', function (Blueprint $table) {
    $table->charset = 'utf8mb4';
    $table->collation = 'utf8mb4_unicode_ci';

    // ...
});

Метод temporary указывает, что таблица должна быть временной. Временные таблицы видимы только в текущей сессии подключения к базе данных и автоматически удаляются при закрытии подключения:

Schema::create('calculations', function (Blueprint $table) {
    $table->temporary();

    // ...
});

Если вы хотите добавить "комментарий" к таблице базы данных, вызовите метод comment у экземпляра таблицы. Комментарии к таблицам поддерживаются в настоящее время только MySQL и Postgres:

Schema::create('calculations', function (Blueprint $table) {
    $table->comment('Business calculations');

    // ...
});

#Обновление таблиц

Метод table фасада Schema используется для обновления существующих таблиц. Как и метод create, метод table принимает два аргумента: имя таблицы и замыкание, которому передаётся экземпляр Blueprint, с помощью которого можно добавить столбцы или индексы в таблицу:

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

Schema::table('users', function (Blueprint $table) {
    $table->integer('votes');
});

#Переименование / удаление таблиц

Для переименования существующей таблицы используйте метод rename:

use Illuminate\Support\Facades\Schema;

Schema::rename($from, $to);

Для удаления существующей таблицы используйте методы drop или dropIfExists:

Schema::drop('users');

Schema::dropIfExists('users');

#Переименование таблиц с внешними ключами

Перед переименованием таблицы убедитесь, что все ограничения внешних ключей в миграциях имеют явные имена, а не имена, сгенерированные Laravel по умолчанию. Иначе имя ограничения будет ссылаться на старое имя таблицы.

#Колонки

#Создание колонок

Метод table фасада Schema можно использовать для обновления существующих таблиц. Как и метод create, метод table принимает два аргумента: имя таблицы и замыкание, которому передаётся экземпляр Illuminate\Database\Schema\Blueprint, с помощью которого можно добавить столбцы в таблицу:

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

Schema::table('users', function (Blueprint $table) {
    $table->integer('votes');
});

#Доступные типы колонок

Конструктор схемы предоставляет множество методов, соответствующих различным типам колонок, которые можно добавить в таблицы базы данных. Все доступные методы перечислены в таблице ниже:

<style> .collection-method-list > p { columns: 10.8em 3; -moz-columns: 10.8em 3; -webkit-columns: 10.8em 3; } .collection-method-list a { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .collection-method code { font-size: 14px; } .collection-method:not(.first-collection-method) { margin-top: 50px; } </style>

#bigIncrements() {.collection-method .first-collection-method}

Метод bigIncrements создаёт колонку с автоинкрементом типа UNSIGNED BIGINT (первичный ключ):

$table->bigIncrements('id');

#bigInteger() {.collection-method}

Метод bigInteger создаёт колонку типа BIGINT:

$table->bigInteger('votes');

#binary() {.collection-method}

Метод binary создаёт колонку типа BLOB:

$table->binary('photo');

#boolean() {.collection-method}

Метод boolean создаёт колонку типа BOOLEAN:

$table->boolean('confirmed');

#char() {.collection-method}

Метод char создаёт колонку типа CHAR с заданной длиной:

$table->char('name', 100);

#dateTimeTz() {.collection-method}

Метод dateTimeTz создаёт колонку типа DATETIME с учётом часового пояса и необязательной точностью (количество цифр):

$table->dateTimeTz('created_at', $precision = 0);

#dateTime() {.collection-method}

Метод dateTime создаёт колонку типа DATETIME с необязательной точностью (количество цифр):

$table->dateTime('created_at', $precision = 0);

#date() {.collection-method}

Метод date создаёт колонку типа DATE:

$table->date('created_at');

#decimal() {.collection-method}

Метод decimal создаёт колонку типа DECIMAL с заданной точностью (общее количество цифр) и масштабом (количество десятичных знаков):

$table->decimal('amount', $precision = 8, $scale = 2);

#double() {.collection-method}

Метод double создаёт колонку типа DOUBLE с заданной точностью (общее количество цифр) и масштабом (количество десятичных знаков):

$table->double('amount', 8, 2);

#enum() {.collection-method}

Метод enum создаёт колонку типа ENUM с заданным набором допустимых значений:

$table->enum('difficulty', ['easy', 'hard']);

#float() {.collection-method}

Метод float создаёт колонку типа FLOAT с заданной точностью (общее количество цифр) и масштабом (количество десятичных знаков):

$table->float('amount', 8, 2);

#foreignId() {.collection-method}

Метод foreignId создаёт колонку типа UNSIGNED BIGINT:

$table->foreignId('user_id');

#foreignIdFor() {.collection-method}

Метод foreignIdFor добавляет колонку {column}_id для указанного класса модели. Тип колонки будет UNSIGNED BIGINT, CHAR(36) или CHAR(26) в зависимости от типа ключа модели:

$table->foreignIdFor(User::class);

#foreignUlid() {.collection-method}

Метод foreignUlid создаёт колонку типа ULID:

$table->foreignUlid('user_id');

#foreignUuid() {.collection-method}

Метод foreignUuid создаёт колонку типа UUID:

$table->foreignUuid('user_id');

#geometryCollection() {.collection-method}

Метод geometryCollection создаёт колонку типа GEOMETRYCOLLECTION:

$table->geometryCollection('positions');

#geometry() {.collection-method}

Метод geometry создаёт колонку типа GEOMETRY:

$table->geometry('positions');

#id() {.collection-method}

Метод id является псевдонимом метода bigIncrements. По умолчанию создаётся колонка id; однако вы можете передать имя колонки, если хотите использовать другое имя:

$table->id();

#increments() {.collection-method}

Метод increments создаёт колонку с автоинкрементом типа UNSIGNED INTEGER в качестве первичного ключа:

$table->increments('id');

#integer() {.collection-method}

Метод integer создаёт колонку типа INTEGER:

$table->integer('votes');

#ipAddress() {.collection-method}

Метод ipAddress создаёт колонку типа VARCHAR:

$table->ipAddress('visitor');

При использовании Postgres будет создана колонка типа INET.

#json() {.collection-method}

Метод json создаёт колонку типа JSON:

$table->json('options');

#jsonb() {.collection-method}

Метод jsonb создаёт колонку типа JSONB:

$table->jsonb('options');

#lineString() {.collection-method}

Метод lineString создаёт колонку типа LINESTRING:

$table->lineString('positions');

#longText() {.collection-method}

Метод longText создаёт колонку типа LONGTEXT:

$table->longText('description');

#macAddress() {.collection-method}

Метод macAddress создаёт колонку, предназначенную для хранения MAC-адреса. Некоторые СУБД, например PostgreSQL, имеют специальный тип для таких данных. Другие СУБД используют строковый тип:

$table->macAddress('device');

#mediumIncrements() {.collection-method}

Метод mediumIncrements создаёт колонку с автоинкрементом типа UNSIGNED MEDIUMINT в качестве первичного ключа:

$table->mediumIncrements('id');

#mediumInteger() {.collection-method}

Метод mediumInteger создаёт колонку типа MEDIUMINT:

$table->mediumInteger('votes');

#mediumText() {.collection-method}

Метод mediumText создаёт колонку типа MEDIUMTEXT:

$table->mediumText('description');

#morphs() {.collection-method}

Метод morphs — удобный метод, который добавляет колонку {column}_id и колонку {column}_type типа VARCHAR. Тип колонки {column}_id будет UNSIGNED BIGINT, CHAR(36) или CHAR(26) в зависимости от типа ключа модели.

Этот метод предназначен для определения колонок, необходимых для полиморфных отношений Eloquent. В следующем примере будут созданы колонки taggable_id и taggable_type:

$table->morphs('taggable');

#multiLineString() {.collection-method}

Метод multiLineString создаёт колонку типа MULTILINESTRING:

$table->multiLineString('positions');

#multiPoint() {.collection-method}

Метод multiPoint создаёт колонку типа MULTIPOINT:

$table->multiPoint('positions');

#multiPolygon() {.collection-method}

Метод multiPolygon создаёт колонку типа MULTIPOLYGON:

$table->multiPolygon('positions');

#nullableTimestamps() {.collection-method}

Метод nullableTimestamps является псевдонимом метода timestamps:

$table->nullableTimestamps(0);

#nullableMorphs() {.collection-method}

Метод похож на morphs; однако создаваемые столбцы будут "nullable":

$table->nullableMorphs('taggable');

#nullableUlidMorphs() {.collection-method}

Метод похож на ulidMorphs; однако создаваемые столбцы будут "nullable":

$table->nullableUlidMorphs('taggable');

#nullableUuidMorphs() {.collection-method}

Метод похож на uuidMorphs; однако создаваемые столбцы будут "nullable":

$table->nullableUuidMorphs('taggable');

#point() {.collection-method}

Метод point создаёт столбец, эквивалентный типу POINT:

$table->point('position');

#polygon() {.collection-method}

Метод polygon создаёт столбец, эквивалентный типу POLYGON:

$table->polygon('position');

#rememberToken() {.collection-method}

Метод rememberToken создаёт nullable столбец, эквивалентный VARCHAR(100), предназначенный для хранения текущего "remember me" токена аутентификации:

$table->rememberToken();

#set() {.collection-method}

Метод set создаёт столбец, эквивалентный типу SET, с заданным списком допустимых значений:

$table->set('flavors', ['strawberry', 'vanilla']);

#smallIncrements() {.collection-method}

Метод smallIncrements создаёт автоинкрементный столбец, эквивалентный UNSIGNED SMALLINT, который используется в качестве первичного ключа:

$table->smallIncrements('id');

#smallInteger() {.collection-method}

Метод smallInteger создаёт столбец, эквивалентный типу SMALLINT:

$table->smallInteger('votes');

#softDeletesTz() {.collection-method}

Метод softDeletesTz добавляет столбец deleted_at типа TIMESTAMP (с часовым поясом), допускающий NULL, с необязательной точностью (общее количество цифр). Этот столбец предназначен для хранения метки времени deleted_at, необходимой для функционала Eloquent «мягкого удаления»:

$table->softDeletesTz($column = 'deleted_at', $precision = 0);

#softDeletes() {.collection-method}

Метод softDeletes добавляет эквивалентный TIMESTAMP столбец deleted_at, допускающий NULL, с необязательной точностью (общее число цифр). Этот столбец предназначен для хранения временной метки deleted_at, необходимой для механизма мягкого удаления в Eloquent:

$table->softDeletes($column = 'deleted_at', $precision = 0);

#string() {.collection-method}

Метод string создаёт столбец, эквивалентный типу VARCHAR заданной длины:

$table->string('name', 100);

#text() {.collection-method}

Метод text создаёт столбец, эквивалентный типу TEXT:

$table->text('description');

#timeTz() {.collection-method}

Метод timeTz создаёт столбец, эквивалентный типу TIME с учётом часового пояса и необязательной точностью (количество цифр):

$table->timeTz('sunrise', $precision = 0);

#time() {.collection-method}

Метод time создаёт столбец, эквивалентный типу TIME с необязательной точностью (количество цифр):

$table->time('sunrise', $precision = 0);

#timestampTz() {.collection-method}

Метод timestampTz создаёт столбец, эквивалентный типу TIMESTAMP с учётом часового пояса и необязательной точностью (количество цифр):

$table->timestampTz('added_at', $precision = 0);

#timestamp() {.collection-method}

Метод timestamp создаёт столбец, эквивалентный типу TIMESTAMP с необязательной точностью (количество цифр):

$table->timestamp('added_at', $precision = 0);

#timestampsTz() {.collection-method}

Метод timestampsTz создаёт столбцы created_at и updated_at, эквивалентные типу TIMESTAMP с учётом часового пояса и необязательной точностью (количество цифр):

$table->timestampsTz($precision = 0);

#timestamps() {.collection-method}

Метод timestamps создаёт столбцы created_at и updated_at, эквивалентные типу TIMESTAMP с необязательной точностью (количество цифр):

$table->timestamps($precision = 0);

#tinyIncrements() {.collection-method}

Метод tinyIncrements создаёт автоинкрементный столбец, эквивалентный UNSIGNED TINYINT, который используется в качестве первичного ключа:

$table->tinyIncrements('id');

#tinyInteger() {.collection-method}

Метод tinyInteger создаёт столбец, эквивалентный типу TINYINT:

$table->tinyInteger('votes');

#tinyText() {.collection-method}

Метод tinyText создаёт столбец, эквивалентный типу TINYTEXT:

$table->tinyText('notes');

#unsignedBigInteger() {.collection-method}

Метод unsignedBigInteger создаёт столбец, эквивалентный типу UNSIGNED BIGINT:

$table->unsignedBigInteger('votes');

#unsignedDecimal() {.collection-method}

Метод unsignedDecimal создаёт столбец, эквивалентный типу UNSIGNED DECIMAL с необязательной точностью (общее количество цифр) и масштабом (количество десятичных знаков):

$table->unsignedDecimal('amount', $precision = 8, $scale = 2);

#unsignedInteger() {.collection-method}

Метод unsignedInteger создаёт столбец, эквивалентный типу UNSIGNED INTEGER:

$table->unsignedInteger('votes');

#unsignedMediumInteger() {.collection-method}

Метод unsignedMediumInteger создаёт столбец, эквивалентный типу UNSIGNED MEDIUMINT:

$table->unsignedMediumInteger('votes');

#unsignedSmallInteger() {.collection-method}

Метод unsignedSmallInteger создаёт столбец, эквивалентный типу UNSIGNED SMALLINT:

$table->unsignedSmallInteger('votes');

#unsignedTinyInteger() {.collection-method}

Метод unsignedTinyInteger создаёт столбец, эквивалентный типу UNSIGNED TINYINT:

$table->unsignedTinyInteger('votes');

#ulidMorphs() {.collection-method}

Метод ulidMorphs — это удобный метод, который добавляет столбец {column}_id эквивалентный CHAR(26) и столбец {column}_type эквивалентный VARCHAR.

Этот метод предназначен для определения столбцов, необходимых для полиморфных отношений Eloquent, использующих идентификаторы ULID. В следующем примере будут созданы столбцы taggable_id и taggable_type:

$table->ulidMorphs('taggable');

#uuidMorphs() {.collection-method}

Метод uuidMorphs — это удобный метод, который добавляет столбец {column}_id эквивалентный CHAR(36) и столбец {column}_type эквивалентный VARCHAR.

Этот метод предназначен для определения столбцов, необходимых для полиморфных отношений Eloquent, использующих идентификаторы UUID. В следующем примере будут созданы столбцы taggable_id и taggable_type:

$table->uuidMorphs('taggable');

#ulid() {.collection-method}

Метод ulid создаёт столбец, эквивалентный типу ULID:

$table->ulid('id');

#uuid() {.collection-method}

Метод uuid создаёт столбец, эквивалентный типу UUID:

$table->uuid('id');

#year() {.collection-method}

Метод year создаёт столбец, эквивалентный типу YEAR:

$table->year('birth_year');

#Модификаторы столбцов

Помимо перечисленных выше типов столбцов, существует несколько "модификаторов" столбцов, которые можно использовать при добавлении столбца в таблицу базы данных. Например, чтобы сделать столбец "nullable", можно использовать метод nullable:

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

Schema::table('users', function (Blueprint $table) {
    $table->string('email')->nullable();
});

В следующей таблице перечислены все доступные модификаторы столбцов. Этот список не включает модификаторы индексов:

Модификатор Описание
->after('column') Разместить столбец "после" другого столбца (MySQL).
->autoIncrement() Сделать INTEGER столбец автоинкрементным (первичный ключ).
->charset('utf8mb4') Указать набор символов для столбца (MySQL).
->collation('utf8mb4_unicode_ci') Указать сортировку для столбца (MySQL/PostgreSQL/SQL Server).
->comment('my comment') Добавить комментарий к столбцу (MySQL/PostgreSQL).
->default($value) Указать значение по умолчанию для столбца.
->first() Разместить столбец "первым" в таблице (MySQL).
->from($integer) Установить начальное значение автоинкремента (MySQL / PostgreSQL).
->invisible() Сделать столбец "невидимым" для запросов SELECT * (MySQL).
->nullable($value = true) Разрешить вставку NULL в столбец.
->storedAs($expression) Создать вычисляемый сохранённый столбец (MySQL / PostgreSQL).
->unsigned() Сделать INTEGER столбец UNSIGNED (MySQL).
->useCurrent() Установить TIMESTAMP столбец с CURRENT_TIMESTAMP по умолчанию.
->useCurrentOnUpdate() Установить TIMESTAMP столбец с CURRENT_TIMESTAMP при обновлении записи (MySQL).
->virtualAs($expression) Создать виртуальный вычисляемый столбец (MySQL / PostgreSQL / SQLite).
->generatedAs($expression) Создать идентичный столбец с заданными параметрами последовательности (PostgreSQL).
->always() Определяет приоритет значений последовательности над вводом для идентичного столбца (PostgreSQL).
->isGeometry() Установить тип пространственного столбца geometry — по умолчанию geography (PostgreSQL).

#Выражения по умолчанию

Модификатор default принимает значение или экземпляр Illuminate\Database\Query\Expression. Использование экземпляра Expression предотвращает оборачивание значения в кавычки Laravel и позволяет использовать специфичные для базы данных функции. Особенно полезно при назначении значений по умолчанию для JSON столбцов:

<?php

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

return new class extends Migration
{
    /**
     * Выполнить миграции.
     */
    public function up(): void
    {
        Schema::create('flights', function (Blueprint $table) {
            $table->id();
            $table->json('movies')->default(new Expression('(JSON_ARRAY())'));
            $table->timestamps();
        });
    }
};
Внимание

Поддержка выражений по умолчанию зависит от драйвера базы данных, версии базы и типа поля. Пожалуйста, обратитесь к документации вашей базы данных.

#Порядок столбцов

При использовании базы данных MySQL метод after позволяет добавить столбцы после существующего столбца в схеме:

$table->after('password', function (Blueprint $table) {
    $table->string('address_line1');
    $table->string('address_line2');
    $table->string('city');
});

#Изменение столбцов

Метод change позволяет изменить тип и атрибуты существующих столбцов. Например, можно увеличить длину столбца string. Чтобы увидеть метод change в действии, увеличим размер столбца name с 25 до 50. Для этого достаточно задать новое состояние столбца и затем вызвать метод change:

Schema::table('users', function (Blueprint $table) {
    $table->string('name', 50)->change();
});

При изменении столбца необходимо явно указать все модификаторы, которые вы хотите сохранить — любые отсутствующие атрибуты будут удалены. Например, чтобы сохранить атрибуты unsigned, default и comment, нужно явно вызвать каждый из них при изменении столбца:

Schema::table('users', function (Blueprint $table) {
    $table->integer('votes')->unsigned()->default(1)->comment('my comment')->change();
});

#Изменение столбцов в SQLite

Если ваше приложение использует базу данных SQLite, перед изменением столбца необходимо установить пакет doctrine/dbal через Composer. Библиотека Doctrine DBAL используется для определения текущего состояния столбца и создания SQL-запросов для внесения изменений:

composer require doctrine/dbal

Если вы планируете изменять столбцы, созданные с помощью метода timestamp, необходимо также добавить следующую конфигурацию в файл config/database.php вашего приложения:

use Illuminate\Database\DBAL\TimestampType;

'dbal' => [
    'types' => [
        'timestamp' => TimestampType::class,
    ],
],
Внимание

При использовании пакета doctrine/dbal можно изменять следующие типы столбцов: bigInteger, binary, boolean, char, date, dateTime, dateTimeTz, decimal, double, integer, json, longText, mediumText, smallInteger, string, text, time, tinyText, unsignedBigInteger, unsignedInteger, unsignedSmallInteger, ulid и uuid.

#Переименование столбцов

Для переименования столбца можно использовать метод renameColumn, предоставляемый конструктором схемы:

Schema::table('users', function (Blueprint $table) {
    $table->renameColumn('from', 'to');
});

#Переименование столбцов в устаревших базах данных

Если вы используете версию базы данных старше одной из следующих, убедитесь, что установили библиотеку doctrine/dbal через Composer перед переименованием столбца:

  • MySQL < 8.0.3
  • MariaDB < 10.5.2
  • SQLite < 3.25.0

#Удаление столбцов

Для удаления столбца можно использовать метод dropColumn конструктора схемы:

Schema::table('users', function (Blueprint $table) {
    $table->dropColumn('votes');
});

Можно удалить несколько столбцов, передав массив имён столбцов в метод dropColumn:

Schema::table('users', function (Blueprint $table) {
    $table->dropColumn(['votes', 'avatar', 'location']);
});

#Удаление столбцов в устаревших базах данных

Если вы используете версию SQLite ниже 3.35.0, необходимо установить пакет doctrine/dbal через Composer перед использованием метода dropColumn. Удаление или изменение нескольких столбцов в одной миграции с использованием этого пакета не поддерживается.

#Доступные псевдонимы команд

Laravel предоставляет несколько удобных методов для удаления распространённых типов столбцов. Каждый из этих методов описан в таблице ниже:

Команда Описание
$table->dropMorphs('morphable'); Удалить столбцы morphable_id и morphable_type.
$table->dropRememberToken(); Удалить столбец remember_token.
$table->dropSoftDeletes(); Удалить столбец deleted_at.
$table->dropSoftDeletesTz(); Псевдоним метода dropSoftDeletes().
$table->dropTimestamps(); Удалить столбцы created_at и updated_at.
$table->dropTimestampsTz(); Псевдоним метода dropTimestamps().

#Индексы

#Создание индексов

Конструктор схемы Laravel поддерживает несколько типов индексов. В следующем примере создаётся новый столбец email с уникальными значениями. Для создания индекса можно цепочкой вызвать метод unique у определения столбца:

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

Schema::table('users', function (Blueprint $table) {
    $table->string('email')->unique();
});

Альтернативно, индекс можно создать после определения столбца, вызвав метод unique у объекта схемы. Этот метод принимает имя столбца, для которого нужно создать уникальный индекс:

$table->unique('email');

Можно также передать массив столбцов в метод индекса для создания составного (композитного) индекса:

$table->index(['account_id', 'created_at']);

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

$table->unique('email', 'unique_email');

#Доступные типы индексов

Класс конструктора схемы Laravel предоставляет методы для создания каждого поддерживаемого типа индекса. Каждый метод принимает необязательный второй аргумент для указания имени индекса. Если он опущен, имя будет сформировано на основе имени таблицы, столбцов и типа индекса. Ниже описаны доступные методы индексов:

Команда Описание
$table->primary('id'); Добавить первичный ключ.
$table->primary(['id', 'parent_id']); Добавить составной первичный ключ.
$table->unique('email'); Добавить уникальный индекс.
$table->index('state'); Добавить индекс.
$table->fullText('body'); Добавить полнотекстовый индекс (MySQL/PostgreSQL).
$table->fullText('body')->language('english'); Добавить полнотекстовый индекс с указанием языка (PostgreSQL).
$table->spatialIndex('location'); Добавить пространственный индекс (кроме SQLite).

#Длина индексов и MySQL / MariaDB

По умолчанию Laravel использует набор символов utf8mb4. Если вы используете версию MySQL ниже 5.7.7 или MariaDB ниже 10.2.2, возможно, потребуется вручную настроить длину строк по умолчанию, создаваемых миграциями, чтобы MySQL мог создавать индексы. Это можно сделать, вызвав метод Schema::defaultStringLength в методе boot класса App\Providers\AppServiceProvider:

use Illuminate\Support\Facades\Schema;

/**
 * Загрузить сервисы приложения.
 */
public function boot(): void
{
    Schema::defaultStringLength(191);
}

Альтернативно, можно включить опцию innodb_large_prefix для вашей базы данных. Обратитесь к документации вашей базы данных для инструкций по правильному включению этой опции.

#Переименование индексов

Для переименования индекса можно использовать метод renameIndex конструктора схемы. Этот метод принимает текущее имя индекса первым аргументом и новое имя вторым:

$table->renameIndex('from', 'to')
Внимание

Если ваше приложение использует базу данных SQLite, необходимо установить пакет doctrine/dbal через Composer перед использованием метода renameIndex.

#Удаление индексов

Для удаления индекса необходимо указать его имя. По умолчанию Laravel автоматически присваивает имя индексу на основе имени таблицы, столбца и типа индекса. Вот несколько примеров:

Команда Описание
$table->dropPrimary('users_id_primary'); Удалить первичный ключ из таблицы "users".
$table->dropUnique('users_email_unique'); Удалить уникальный индекс из таблицы "users".
$table->dropIndex('geo_state_index'); Удалить обычный индекс из таблицы "geo".
$table->dropFullText('posts_body_fulltext'); Удалить полнотекстовый индекс из таблицы "posts".
$table->dropSpatialIndex('geo_location_spatialindex'); Удалить пространственный индекс из таблицы "geo" (кроме SQLite).

Если передать массив столбцов в метод удаления индекса, имя индекса будет сгенерировано на основе имени таблицы, столбцов и типа индекса:

Schema::table('geo', function (Blueprint $table) {
    $table->dropIndex(['state']); // Удаляет индекс 'geo_state_index'
});

#Внешние ключи

Laravel также поддерживает создание ограничений внешних ключей, которые обеспечивают ссылочную целостность на уровне базы данных. Например, определим столбец user_id в таблице posts, который ссылается на столбец id таблицы users:

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

Schema::table('posts', function (Blueprint $table) {
    $table->unsignedBigInteger('user_id');

    $table->foreign('user_id')->references('id')->on('users');
});

Поскольку этот синтаксис довольно громоздкий, Laravel предоставляет более краткие методы, использующие соглашения для удобства разработчика. При использовании метода foreignId пример выше можно переписать так:

Schema::table('posts', function (Blueprint $table) {
    $table->foreignId('user_id')->constrained();
});

Метод foreignId создаёт столбец, эквивалентный UNSIGNED BIGINT, а метод constrained использует соглашения для определения таблицы и столбца, на которые ссылаются. Если имя вашей таблицы не соответствует соглашениям Laravel, вы можете указать его вручную в методе constrained. Также можно задать имя создаваемого индекса:

Schema::table('posts', function (Blueprint $table) {
    $table->foreignId('user_id')->constrained(
        table: 'users', indexName: 'posts_user_id'
    );
});

Вы также можете указать желаемое действие для свойств "on delete" и "on update" ограничения:

$table->foreignId('user_id')
      ->constrained()
      ->onUpdate('cascade')
      ->onDelete('cascade');

Для этих действий также предоставлен альтернативный выразительный синтаксис:

Метод Описание
$table->cascadeOnUpdate(); Обновления должны каскадироваться.
$table->restrictOnUpdate(); Обновления должны быть ограничены.
$table->noActionOnUpdate(); Нет действия при обновлениях.
$table->cascadeOnDelete(); Удаления должны каскадироваться.
$table->restrictOnDelete(); Удаления должны быть ограничены.
$table->nullOnDelete(); При удалении значение внешнего ключа устанавливается в null.

Любые дополнительные модификаторы столбцов должны вызываться до метода constrained:

$table->foreignId('user_id')
      ->nullable()
      ->constrained();

#Удаление внешних ключей

Для удаления внешнего ключа можно использовать метод dropForeign, передав имя ограничения внешнего ключа для удаления. Имена ограничений внешних ключей формируются по тому же правилу, что и индексы, то есть на основе имени таблицы и столбцов с суффиксом "_foreign":

$table->dropForeign('posts_user_id_foreign');

Альтернативно, можно передать массив с именем столбца, содержащего внешний ключ, в метод dropForeign. Массив будет преобразован в имя ограничения внешнего ключа согласно соглашениям Laravel:

$table->dropForeign(['user_id']);

#Включение и отключение ограничений внешних ключей

Вы можете включать или отключать ограничения внешних ключей в миграциях с помощью следующих методов:

Schema::enableForeignKeyConstraints();

Schema::disableForeignKeyConstraints();

Schema::withoutForeignKeyConstraints(function () {
    // Ограничения отключены внутри этого замыкания...
});
Внимание

В SQLite ограничения внешних ключей по умолчанию отключены. При использовании SQLite убедитесь, что включили поддержку внешних ключей в конфигурации базы данных перед попыткой создать их в миграциях. Кроме того, SQLite поддерживает внешние ключи только при создании таблицы и не при её изменении.

#События

Для удобства каждая операция миграции будет отправлять событие. Все перечисленные ниже события наследуются от базового класса Illuminate\Database\Events\MigrationEvent:

Класс Описание

| Illuminate\Database\Events\MigrationsStarted | Пакет миграций собирается быть выполненным. | | Illuminate\Database\Events\MigrationsEnded | Пакет миграций завершил выполнение. | | Illuminate\Database\Events\MigrationStarted | Одна миграция собирается быть выполненной. | | Illuminate\Database\Events\MigrationEnded | Одна миграция завершила выполнение. | | Illuminate\Database\Events\SchemaDumped | Схема базы данных была выгружена. | | Illuminate\Database\Events\SchemaLoaded | Существующая выгрузка схемы базы данных была загружена. |