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

Присоединяйся к нашему Telegram сообществу @webblend!

Здесь ты найдешь сниппеты по Laravel и полезные советы по веб-разработке.

Введение

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

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

Генерация миграций

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

php artisan make:migration create_flights_table

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

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

Примечание Шаблоны миграций можно настроить с использованием публикации шаблонов.

Сжатие миграций

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

php artisan schema:dump
 
# Dump the current database schema and prune all existing migrations...
php artisan schema:dump --prune

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

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

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

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

Внимание Сжатие миграций доступно только для баз данных MySQL, PostgreSQL и SQLite и использует командный клиент базы данных. Схемные дампы не могут быть восстановлены в базах данных 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 соответствует значению пакета в таблице миграций вашего приложения. Например, следующая команда откатит все миграции в пакете три:

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
 
# Refresh the database and run all database seeds...
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 удалит все таблицы базы данных независимо от их префикса. Эту команду следует использовать осторожно при разработке на базе данных, которая используется другими приложениями.

Таблицы

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

Чтобы создать новую таблицу базы данных, используйте метод 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');
});

Доступные типы столбцов

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

bigIncrements()

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

$table->bigIncrements('id');

bigInteger()

Метод bigInteger создает столбец BIGINT:

$table->bigInteger('votes');

binary()

Метод binary создает столбец BLOB:

$table->binary('photo');

boolean()

Метод boolean создает столбец BOOLEAN:

$table->boolean('confirmed');

char()

Метод char создает столбец CHAR с заданной длиной:

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

dateTimeTz()

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

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

dateTime()

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

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

date()

Метод date создает столбец DATE:

$table->date('created_at');

decimal()

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

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

double()

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

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

enum()

Метод enum создает столбец ENUM с заданными допустимыми значениями:

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

float()

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

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

foreignId()

Метод foreignId создает столбец UNSIGNED BIGINT:

$table->foreignId('user_id');

foreignIdFor()

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

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

foreignUlid()

Метод foreignUlid создает столбец ULID:

$table->foreignUlid('user_id');

foreignUuid()

Метод foreignUuid создает столбец UUID:

$table->foreignUuid('user_id');

geometryCollection()

Метод geometryCollection создает столбец GEOMETRYCOLLECTION эквивалентный:

$table->geometryCollection('positions');

geometry()

Метод geometry создает столбец GEOMETRY эквивалентный:

$table->geometry('positions');

id()

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

$table->id();

increments()

Метод increments создает автоинкрементный столбец UNSIGNED INTEGER эквивалентный в качестве первичного ключа:

$table->increments('id');

integer()

Метод integer создает столбец INTEGER эквивалентный:

$table->integer('votes');

ipAddress()

Метод ipAddress создает столбец VARCHAR эквивалентный:

$table->ipAddress('visitor');

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

json()

Метод json создает столбец JSON эквивалентный:

$table->json('options');

jsonb()

Метод jsonb создает столбец JSONB эквивалентный:

$table->jsonb('options');

lineString()

Метод lineString создает столбец LINESTRING эквивалентный:

$table->lineString('positions');

longText()

Метод longText создает столбец LONGTEXT эквивалентный:

$table->longText('description');

macAddress()

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

$table->macAddress('device');

mediumIncrements()

Метод mediumIncrements создает автоинкрементный столбец UNSIGNED MEDIUMINT эквивалентный в качестве первичного ключа:

$table->mediumIncrements('id');

mediumInteger()

Метод mediumInteger создает столбец MEDIUMINT эквивалентный:

$table->mediumInteger('votes');

mediumText()

Метод mediumText создает столбец MEDIUMTEXT эквивалентный:

$table->mediumText('description');

morphs()

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

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

$table->morphs('taggable');

multiLineString()

Метод multiLineString создает столбец MULTILINESTRING эквивалентный:

$table->multiLineString('positions');

multiPoint()

Метод multiPoint создает столбец MULTIPOINT эквивалентный:

$table->multiPoint('positions');

multiPolygon()

Метод multiPolygon создает столбец MULTIPOLYGON эквивалентный:

$table->multiPolygon('positions');

nullableTimestamps()

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

$table->nullableTimestamps(0);

nullableMorphs()

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

$table->nullableMorphs('taggable');

nullableUlidMorphs()

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

$table->nullableUlidMorphs('taggable');

nullableUuidMorphs()

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

$table->nullableUuidMorphs('taggable');

point()

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

$table->point('position');

polygon()

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

$table->polygon('position');

rememberToken()

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

$table->rememberToken();

set()

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

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

smallIncrements()

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

$table->smallIncrements('id');

smallInteger()

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

$table->smallInteger('votes');

softDeletesTz()

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

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

softDeletes()

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

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

string()

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

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

text()

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

$table->text('description');

timeTz()

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

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

time()

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

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

timestampTz()

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

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

timestamp()

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

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

timestampsTz()

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

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

timestamps()

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

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

tinyIncrements()

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

$table->tinyIncrements('id');

tinyInteger()

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

$table->tinyInteger('votes');

tinyText()

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

$table->tinyText('notes');

unsignedBigInteger()

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

$table->unsignedBigInteger('votes');

unsignedDecimal()

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

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

unsignedInteger()

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

$table->unsignedInteger('votes');

unsignedMediumInteger()

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

$table->unsignedMediumInteger('votes');

unsignedSmallInteger()

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

$table->unsignedSmallInteger('votes');

unsignedTinyInteger()

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

$table->unsignedTinyInteger('votes');

ulidMorphs()

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

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

$table->ulidMorphs('taggable');

uuidMorphs()

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

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

$table->uuidMorphs('taggable');

ulid()

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

$table->ulid('id');

uuid()

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

$table->uuid('id');

year()

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

$table->year('birth_year');

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

В дополнение к типам столбцов, перечисленным выше, существует несколько "модификаторов" столбцов, которые вы можете использовать при добавлении столбца к таблице базы данных. Например, чтобы сделать столбец "допустимым для значения NULL", вы можете использовать метод 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 на схеме построителя blueprint. Этот метод принимает имя столбца, которое должно получить уникальный индекс:

$table->unique('email');

Вы даже можете передать массив столбцов в метод индекса, чтобы создать составной (или композитный) индекс:

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

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

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

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

Класс схемы построителя blueprint Laravel предоставляет методы для создания каждого типа индекса, поддерживаемого 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, предоставляемый схемой построителя blueprint. Этот метод принимает текущее имя индекса в качестве первого аргумента и желаемое имя в качестве второго аргумента:

$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']); // Drops index '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'
);
});

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

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

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

Метод Описание
$table->cascadeOnUpdate(); Обновления должны распространяться.
$table->restrictOnUpdate(); Обновления должны быть ограничены.
$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 Загружен существующий дамп схемы базы данных.