Миграции подобны системе контроля версий для вашей базы данных, что позволяет вашей команде легко изменять и совместно использовать схему базы данных приложения. Миграции обычно сочетаются с построителем схем, чтобы легко создавать схему базы данных для вашего приложения. Благодаря миграциям вам не придется вручную переносить изменения в схеме БД с локального окружения в рабочее.
Фасад Laravel Schema обеспечивает создание и управления таблицами во всех поддерживаемых СУБД Laravel.
Создание миграций
Создание новой миграции осуществляется командой make:migration
$ php artisan make:migration create_users_table
Новая миграция будет сохранена в директории database/migrations
. Каждое имя файла миграции содержит метку времени, которая позволяет Laravel определять порядок миграций.
Для указания имени таблицы и того, будет ли миграция создавать новую таблицу можно использовать параметры --table
и --create
. Эти параметры предварительно заполняют сгенерированный файл миграции для указанной таблицы:
$ php artisan make:migration create_users_table --create=users
$ php artisan make:migration add_votes_to_users_table --table=users
Если вы хотите указать собственный путь для сохранения сгенерированной миграции, вы можете использовать опцию
--path
при выполнении команды make:migration
. Указанный путь должен быть относительно базового пути вашего приложения.
Структура миграции
Класс миграции по-умолччанию содержит два метода: up()
и down()
. Метод up()
используется для добавления новых таблиц, столбцов или индексов в базу данных, в то время как метод down()
должен отменять операции, выполняемые методом up()
.
В обоих из этих методов вы можете использовать конструктор схемы Laravel для удобного создания и изменения таблиц, не привязываясь к конкретной СУБД. Пример миграции ниже создает таблицу авиарейсов:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateFlightsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('flights', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('airline');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('flights');
}
}
Выполнение миграций
Чтобы запустить все ваши миграции, выполните команду migrate
:
Принудительное выполнение миграции
Некоторые миграции могут привести к потере данных. Чтобы защитить разработчика от непреднамеренного запуска этих команд, перед выполнением операции запрашивается подтверждение. Чтобы заставить команды выполняться без подтверждения, используйте флаг --force
:
$ php artisan migrate --force
Отмена миграций
Для отката последней миграции вы можете использовать команду rollback
. Эта команда откатывает последний «пакет» миграций, который может включать несколько файлов миграции:
$ php artisan migrate:rollback
Вы можете откатить нужное вам количество миграций, указав параметр step
в команде rollback
. Например, следующая команда откатит последние пять миграций:
$ php artisan migrate:rollback --step=5
Команда migrate:reset
откатит все миграции вашего приложения:
$ php artisan migrate:reset
Откат и выполнение миграций в одной команде
Команда migrate: refresh
откатит все ваши миграции и затем выполнит команду migrate
. Эта команда полностью воссоздает всю вашу базу данных:
$ php artisan migrate:refresh
Вы можете откатить и перенастроить нужное количество миграций, указав параметр step
в команде refresh
. Например, следующая команда выполнит откат и перенастроит последние пять миграций:
$ php artisan migrate:refresh --step=5
Удаление всех таблиц с последующим выполнением миграций
Команда migrate: fresh
удалит все таблицы из базы данных, а затем выполнит команду migrate
:
$ php artisan migrate:fresh
Таблицы
Создание таблиц
Чтобы создать новую таблицу базы данных, используйте метод create
фасада Scheme. Метод create принимает два аргумента. Первый - это имя таблицы, а второй - это замыкание, которое получает объект Blueprint, который может использоваться для определения новой таблицы:
Schema::create('users', function (Blueprint $table) {
$table->bigIncrements('id');
});
При создании таблицы вы можете использовать любой из методов построителя схемы для определения столбцов таблицы. Checking For Table / Column Existence
Проверка наличия таблицы / столбца
Вы можете легко проверить наличие таблицы или столбца, используя методы hasTable
и hasColumn
:
if (Schema::hasTable('users')) {
//
}
if (Schema::hasColumn('users', 'email')) {
//
}
Соединение с базой данных и параметры таблицы
Если вы хотите выполнить миграцию с подключением к базе данных, которое не является подключением по умолчанию, используйте метод connection
:
Schema::connection('foo')->create('users', function (Blueprint $table) {
$table->bigIncrements('id');
});
Вы можете использовать следующие команды построителя схемы для определения параметров таблицы:
Команда | Описание |
---|---|
$table->engine = 'InnoDB'; |
Механизм хранения таблиц (MySQL). |
$table->charset = 'utf8'; |
Набор символов по умолчанию для таблицы (MySQL). |
$table->collation = 'utf8_unicode_ci'; |
Параметры сортировки по умолчанию для таблицы (MySQL). |
$table->temporary(); |
Создание временной таблицы (кроме SQL Server). |
Переименование / удаление таблиц
Чтобы переименовать существующую таблицу базы данных, используйте метод rename
:
Schema::rename($from, $to);
Чтобы удалить существующую таблицу, вы можете использовать методы drop
или dropIfExists
:
Schema::drop('users');
Schema::dropIfExists('users');
Переименование таблиц с внешними ключами
Перед переименованием таблицы вы должны убедиться, что любые ограничения внешнего ключа в таблице имеют явное имя в ваших файлах миграции, чтобы не дать Laravel назначать имя на основе соглашения по именованию. В противном случае имя ограничения внешнего ключа будет ссылаться на старое имя таблицы.
Столбцы
Создание столбцов
Метод table
в фасаде Schema может использоваться для обновления существующих таблиц. Как и метод create
, метод table
принимает два аргумента: имя таблицы и замыкание, который получает экземпляр Blueprint, который вы можете использовать для добавления столбцов в таблицу:
Schema::table('users', function (Blueprint $table) {
$table->string('email');
});
Доступные типы столбцов
Конструктор схемы содержит различные типы столбцов, которые вы можете указать при построении таблиц:
Команда | Описание |
---|---|
$table->bigIncrements('id'); |
Автоинкрементный столбец UNSIGNED BIGINT (первичный ключ) |
$table->bigInteger('votes'); |
BIGINT столбец |
$table->binary('data'); |
BLOB столбец |
$table->boolean('confirmed'); |
BOOLEAN столбец |
$table->char('name', 100); |
CHAR столбец с необязательной длиной |
$table->date('created_at'); |
DATE столбец |
$table->dateTime('created_at'); |
DATETIME столбец |
$table->dateTimeTz('created_at'); |
DATETIME (с часовым поясом) столбец |
$table->decimal('amount', 8, 2); |
DECIMAL столбец с точностью (общее количество цифр) и масштабом (десятичные цифры) |
$table->double('amount', 8, 2); |
DOUBLE столбец с точностью (общее количество цифр) и масштабом (десятичные цифры) |
$table->enum('level', ['easy', 'hard']); |
ENUM столбец. |
$table->float('amount', 8, 2); |
FLOAT столбец с точностью (общее количество цифр) и масштабом (десятичные цифры) |
$table->geometry('positions'); |
GEOMETRY столбец |
$table->geometryCollection('positions'); |
GEOMETRYCOLLECTION столбец |
$table->increments('id'); |
Автоинкрементный столбец UNSIGNED INTEGER (первичный ключ) |
$table->integer('votes'); |
INTEGER столбец |
$table->ipAddress('visitor'); |
Столбец IP-адреса |
$table->json('options'); |
JSON столбец |
$table->jsonb('options'); |
JSONB столбец |
$table->lineString('positions'); |
LINESTRING столбец |
$table->longText('description'); |
LONGTEXT столбец |
$table->macAddress('device'); |
столбец MAC-адреса |
$table->mediumIncrements('id'); |
Автоинкрементный столбец UNSIGNED MEDIUMINT (первичный ключ) |
$table->mediumInteger('votes'); |
MEDIUMINT столбец |
$table->mediumText('description'); |
MEDIUMTEXT столбец |
$table->morphs('taggable'); |
Добавляет taggable_id UNSIGNED BIGINT и taggable_type VARCHAR столбцы |
$table->uuidMorphs('taggable'); |
Добавляет taggable_id CHAR (36) и taggable_type VARCHAR (255) столбцы UUID |
$table->multiLineString('positions'); |
MULTILINESTRING столбец |
$table->multiPolygon('positions'); |
MULTIPOLYGON столбец |
$table->nullableMorphs('taggable'); |
Добавляет nullable версию столбцов morphs() |
$table->nullableUuidMorphs('taggable'); |
Добавляет nullable версию столбцов uuidMorphs() |
$table->nullableTimestamps(); |
Псевдоним для метода timestamps() |
$table->point('position'); |
POINT столбец |
$table->polygon('positions'); |
POLYGON столбец |
$table->rememberToken(); |
Добавляет nullable столбец remember_token VARCHAR (100) |
$table->set('flavors', ['strawberry', 'vanilla']); |
SET столбец |
$table->smallIncrements('id'); |
Автоинкрементный столбец UNSIGNED SMALLINT (первичный ключ) |
$table->smallInteger('votes'); |
SMALLINT столбец |
$table->softDeletes(); |
Добавляет nullable столбец TIMESTAMP для мягкого удаления |
$table->softDeletesTz(); |
Добавляет nullable столбец TIMESTAMP (с часовым поясом) для мягкого удаления |
$table->string('name', 100); |
VARCHAR столбец с необязательной длиной |
$table->text('description'); |
TEXT столбец |
$table->time('sunrise'); |
TIME столбец |
$table->timeTz('sunrise'); |
TIME столбец (с часовым поясом) |
$table->timestamp('added_on'); |
TIMESTAMP столбец |
$table->timestampTz('added_on'); |
TIMESTAMP столбец (с часовым поясом) |
$table->timestamps(); |
Добавляет nullable created_at и updated_at TIMESTAMP столбцы |
$table->timestampsTz(); |
Добавляет nullable created_at и updated_at TIMESTAMP столбцы (с часовым поясом) |
$table->tinyIncrements('id'); |
Автоинкрементный столбец UNSIGNED TINYINT (первичный ключ) |
$table->tinyInteger('votes'); |
TINYINT столбец |
$table->unsignedBigInteger('votes'); |
UNSIGNED BIGINT столбец |
$table->unsignedDecimal('amount', 8, 2); |
UNSIGNED DECIMAL столбец с точностью (общее количество цифр) и масштабом (десятичные цифры) |
$table->unsignedInteger('votes'); |
UNSIGNED INTEGER столбец |
$table->unsignedMediumInteger('votes'); |
UNSIGNED MEDIUMINT столбец |
$table->unsignedSmallInteger('votes'); |
UNSIGNED SMALLINT столбец |
$table->unsignedTinyInteger('votes'); |
UNSIGNED TINYINT столбец |
$table->uuid('id'); |
UUID столбец |
$table->year('birth_year'); |
YEAR столбец |
Модификаторы столбцов
В дополнение к перечисленным выше типам столбцов есть несколько «модификаторов» столбцов, которые вы можете использовать при добавлении столбца в таблицу базы данных. Например, чтобы сделать столбец «обнуляемым», вы можете использовать nullable
метод:
Schema::table('users', function (Blueprint $table) {
$table->string('email')->nullable();
});
Ниже приведен список всех доступных модификаторов столбцов. Этот список не включает модификаторы индекса:
|Модификатор|Описание|
|-|-|
|->after('column')
|Помещает столбец «после» другого столбца (MySQL)|
|->autoIncrement()
|Устанавливает столбец INTEGER как автоинкремент (первичный ключ)|
|->charset('utf8')
|Указывает набор символов для столбца (MySQL)|
|->collation('utf8_unicode_ci')
|Указывает параметры кодировки для столбца (MySQL / PostgreSQL / SQL Server)|
|->comment('my comment')
|Добавляет комментарий к колонке (MySQL / PostgreSQL)|
|->default($value)
|Добавляет значение по умолчанию для столбца|
|->first()
|Помещает столбец «первым» в таблице (MySQL)|
|->nullable($value = true)
|Разрешает указывать NULL в качестве значения по-умолчанию|
|->storedAs($expression)
|Создает сохраненный сгенерированный столбец (MySQL)|
|->unsigned()
|Устанавливает для столбцов INTEGER значение UNSIGNED (MySQL)|
|->useCurrent()
|Указывает столбцу TIMESTAMP использовать текущее время в качестве значения по-умолчанию|
|->virtualAs($expression)
|Создает виртуальный сгенерированный столбец (MySQL)|
|->generatedAs($expression)
|Создает столбец идентификаторов с указанными параметрами последовательности (PostgreSQL)|
|->always()
|Определяет приоритет значений последовательности над вводом для столбца идентификаторов (PostgreSQL)|
Изменение столбцов
Перед изменением столбца обязательно добавьте зависимость doctrine/dbal
в ваш файл composer.json
. Библиотека Doctrine DBAL используется для определения текущего состояния столбца и создания запросов SQL, необходимых для внесения указанных изменений в столбец:
$ composer require doctrine/dbal
Обновление аттрибутов столбца
Метод change позволяет изменить некоторые существующие типы столбцов на новый тип или изменить атрибуты столбца. Например, вы можете увеличить размер строкового столбца. Чтобы увидеть метод изменения в действии, давайте увеличим размер столбца имени с 25 до 50:
Schema::table('users', function (Blueprint $table) {
$table->string('name', 50)->change();
});
Мы также можем изменить столбец так, чтобы он мог принимать значение NULL:
Schema::table('users', function (Blueprint $table) {
$table->string('name', 50)->nullable()->change();
});
Переименование столбцов
Чтобы переименовать столбец, вы можете использовать метод renameColumn
в построителе схемы. Перед переименованием столбца обязательно добавьте зависимость doctrine/dbal
в ваш файл composer.json
:
Schema::table('users', function (Blueprint $table) {
$table->renameColumn('from', 'to');
});
Удаление столбцов
Чтобы удалить столбец, используйте метод dropColumn
в построителе схемы. Прежде чем удалять столбцы из базы данных SQLite, вам нужно добавить зависимость doctrine/dbal
в ваш файл composer.json
и выполнить команду composer update в вашем терминале, чтобы установить библиотеку:
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('votes');
});
Вы можете удалить несколько столбцов из таблицы, передав массив имен столбцов в метод dropColumn
:
Schema::table('users', function (Blueprint $table) {
$table->dropColumn(['votes', 'avatar', 'location']);
});
Доступные псевдонимы команд
Команда | Описание |
---|---|
$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() |
Индексы
Создание индексов
Конструктор схем поддерживает несколько типов индексов. Сначала давайте рассмотрим пример, в котором значения столбца должны быть уникальными. Чтобы создать индекс такой индекс, мы можем использовать метод unique
:
$table->string('email')->unique();
Кроме того, вы можете создать индекс после определения столбца. Например:
$table->unique('email');
Вы можете даже передать массив столбцов методу index
для создания составного индекса:
$table->index(['account_id', 'created_at']);
Laravel автоматически сгенерирует имя индекса, но вы можете передать в метод второй аргумент, чтобы указать имя самостоятельно:
$table->unique('email', 'unique_email');
Доступные типы индексов
Каждый метод для определения индекса принимает необязательный второй аргумент для указания имени индекса. Если аргумент не указан, то имя будет получено из имен таблицы и столбцов.
Команда | Описание |
---|---|
$table->primary('id'); |
Добавляет первичный ключ |
$table->primary(['id', 'parent_id']); |
Добавляет составной ключ |
$table->unique('email'); |
Добавляет уникальный индекс |
$table->index('state'); |
Добавляет простой индекс |
$table->spatialIndex('location'); |
Добавляет пространственный индекс. (кроме SQLite) |
Длина индекса и MySQL / MariaDB
Laravel по умолчанию использует набор символов utf8mb4, который включает в себя поддержку хранения «emojis» в базе данных. Если вы используете версию MySQL, более раннюю, чем версия 5.7.7
, или MariaDB, более раннюю, чем версия 10.2.2
, вам может потребоваться вручную настроить длину строки по умолчанию, создаваемую миграциями, чтобы MySQL создавал для них индексы. Вы можете настроить это, вызвав метод Schema::defaultStringLength
в вашем AppServiceProvider
:
use Illuminate\Support\Facades\Schema;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Schema::defaultStringLength(191);
}
Кроме того, вы можете включить опцию innodb_large_prefix
для вашей базы данных. Обратитесь к документации вашей базы данных для получения инструкций о том, как правильно включить эту опцию.
Переименование индексов
Чтобы переименовать индекс, вы можете использовать метод renameIndex
. Этот метод принимает текущее имя индекса в качестве первого аргумента и желаемое имя в качестве второго аргумента:
$table->renameIndex('from', 'to')
Удаление индексов
Чтобы удалить индекс, вы должны указать имя индекса. По умолчанию Laravel автоматически назначает имена индексам. Именя генерируются исходя из имени таблицы, имени индексированного столбца и типа индекса. Вот некоторые примеры:
Команда | Описание |
---|---|
$table->dropPrimary('users_id_primary'); |
Удаление первичного ключа |
$table->dropUnique('users_email_unique'); |
Удаление уникального индекса |
$table->dropIndex('geo_state_index'); |
Удаление обычного индекса |
$table->dropSpatialIndex('geo_location_spatialindex'); |
Удалите пространственного индекса из таблицы (кроме SQLite) |
Если вы передадите массив столбцов в метод, который удаляет индексы, то имя индекса будет сгенерировано на основе имени таблицы, столбцов и типа ключа:
Schema::table('geo', function (Blueprint $table) {
$table->dropIndex(['state']); // Удаляет индекс 'geo_state_index'
});
Ограничения внешнего ключа
Laravel также предоставляет поддержку для создания ограничений внешнего ключа, которые используются для обеспечения ссылочной целостности на уровне базы данных. Например, давайте определим столбец user_id в таблице posts, который ссылается на столбец id в таблице users:
Schema::table('posts', function (Blueprint $table) {
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
});
Вы также можете указать желаемое действие для свойств «при удалении» и «при обновлении» ограничения:
$table->foreign('user_id')
->references('id')->on('users')
->onDelete('cascade');
Чтобы удалить внешний ключ, вы можете использовать метод dropForeign
. Ограничения внешнего ключа используют то же соглашение об именах, что и индексы. Итак, мы объединяем имя таблицы и столбцы в ограничении, а затем добавляем суффикс имени к _foreign
:
$table->dropForeign('posts_user_id_foreign');
Или вы можете передать значение массива, которое будет автоматически использовать имя обычного ограничения при удалении:
$table->dropForeign(['user_id']);
Вы можете включить или отключить ограничения внешнего ключа в своих миграциях, используя следующие методы:
Schema::enableForeignKeyConstraints();
Schema::disableForeignKeyConstraints();