Вступление

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

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

 

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

Чтобы создать миграцию, используйте команду Artisan :make:migration

php artisan make:migration create_users_table

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

--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и downupМетод используется для добавления новых таблиц, столбцов и индексов в базе данных, в то время как downметод должен поменять местами операции , выполняемые upметодом.

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

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

 

Запуск Миграции

Чтобы выполнить все ваши выдающиеся миграции, выполните команду migrateArtisan:

php artisan migrate

Если вы используете виртуальную машину Homestead , вы должны выполнить эту команду изнутри вашей виртуальной машины.

Принуждение к миграции в производство

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

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:freshmigrate

php artisan migrate:fresh

php artisan migrate:fresh --seed

Таблицы

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

Чтобы создать новую таблицу базы данных, используйте createметод на Schemaфасаде. createМетод принимает два аргумента. Первый - это имя таблицы, а второй - Closureэто Blueprintобъект, который получает объект, который может быть использован для определения новой таблицы:

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

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

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

Вы можете легко проверить существование таблицы или столбца , используя 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метод принимает два аргумента: имя таблицы и объект, Closureкоторый получает 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'); ДАТА эквивалентный столбец.
$table->dateTime('created_at'); DATETIME эквивалентный столбец.
$table->dateTimeTz('created_at'); DATETIME (с часовым поясом) эквивалентный столбец.
$table->decimal('amount', 8, 2); DECIMAL эквивалентный столбец с точностью (общее количество цифр) и масштабом (десятичные цифры).
$table->double('amount', 8, 2); Двойной эквивалентный столбец с точностью (общее количество цифр) и масштабом (десятичные цифры).
$table->enum('level', ['easy', 'hard']); ENUM эквивалентный столбец.
$table->float('amount', 8, 2); FLOAT эквивалентный столбец с точностью (общее количество цифр) и масштабом (десятичные цифры).
$table->geometry('positions'); ГЕОМЕТРИЯ эквивалентный столбец.
$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неподписанные столбцы BIGINT иtaggable_typeVARCHAR.
$table->multiLineString('positions'); MULTILINESTRING эквивалентный столбец.
$table->multiPoint('positions'); MULTIPOINT эквивалентный столбец.
$table->multiPolygon('positions'); МНОГОПОЛИГОННЫЙ эквивалентный столбец.
$table->nullableMorphs('taggable'); Добавляет обнуляемые версиистолбцов.morphs()
$table->nullableTimestamps(); Псевдоним метода.timestamps()
$table->point('position'); ТОЧКА эквивалентного столбца.
$table->polygon('positions'); Полигон эквивалентный столбец.
$table->rememberToken(); Добавляет обнуляемыйremember_tokenэквивалентный столбец VARCHAR (100).
$table->set('flavors', ['strawberry', 'vanilla']); Установить эквивалентный столбец.
$table->smallIncrements('id'); Автоинкрементный эквивалентный столбец UNSIGNED SMALLINT (первичный ключ).
$table->smallInteger('votes'); SMALLINT эквивалентный столбец.
$table->softDeletes(); Добавляет обнуляемыйdeleted_atэквивалентный столбец TIMESTAMP для мягкого удаления.
$table->softDeletesTz(); Добавляет обнуляемыйdeleted_atэквивалент столбца TIMESTAMP (с часовым поясом) для мягкого удаления.
$table->string('name', 100); VARCHAR эквивалентный столбец с необязательной длиной.
$table->text('description'); ТЕКСТ эквивалентный столбец.
$table->time('sunrise'); ВРЕМЯ эквивалентный столбец.
$table->timeTz('sunrise'); ВРЕМЯ (с часовым поясом) эквивалентный столбец.
$table->timestamp('added_on'); TIMESTAMP эквивалентный столбец.
$table->timestampTz('added_on'); TIMESTAMP (с часовым поясом) эквивалентный столбец.
$table->timestamps(); Добавляет пустые created_atиupdated_atэквивалентные столбцы TIMESTAMP.
$table->timestampsTz(); Добавляет обнуляемыеcreated_atиupdated_atTIMESTAMP (с часовым поясом) эквивалентные столбцы.
$table->tinyIncrements('id'); Автоинкрементный эквивалентный столбец UNSIGNED TINYINT (первичный ключ).
$table->tinyInteger('votes'); TINYINT эквивалентный столбец.
$table->unsignedBigInteger('votes'); НЕПодписанный эквивалентный столбец BIGINT.
$table->unsignedDecimal('amount', 8, 2); UNSIGNED DECIMAL эквивалентный столбец с точностью (общее количество цифр) и масштабом (десятичные цифры).
$table->unsignedInteger('votes'); Беззнаковый целочисленный эквивалентный столбец.
$table->unsignedMediumInteger('votes'); UNSIGNED MEDIUMINT эквивалентный столбец.
$table->unsignedSmallInteger('votes'); НЕПИСАННЫЙ МАЛЕНЬКИЙ эквивалентный столбец.
$table->unsignedTinyInteger('votes'); UNSIGNED TINYINT эквивалентный столбец.
$table->uuid('id'); UUID эквивалентный столбец.
$table->year('birth_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 / SQL Server).
->comment('my comment') Добавить комментарий к колонке (MySQL / PostgreSQL)
->default($value) Укажите значение по умолчанию для столбца
->first() Поместите столбец «первый» в таблице (MySQL)
->nullable($value = true) Позволяет (по умолчанию) значения NULL вставлять в столбец
->storedAs($expression) Создать сохраненный сгенерированный столбец (MySQL)
->unsigned() Установить для столбцов INTEGER значение UNSIGNED (MySQL)
->useCurrent() Установите столбцы TIMESTAMP для использования CURRENT_TIMESTAMP в качестве значения по умолчанию
->virtualAs($expression) Создать виртуальный сгенерированный столбец (MySQL)
->generatedAs($expression) Создать столбец идентификаторов с указанными параметрами последовательности (PostgreSQL)
->always() Определяет приоритет значений последовательности над вводом для столбца идентификаторов (PostgreSQL)

 

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

Предпосылки

Перед изменением столбца обязательно добавьте зависимость в свой файл. Библиотека Doctrine DBAL используется для определения текущего состояния столбца и создания запросов SQL, необходимых для внесения указанных изменений в столбец:doctrine/dbalcomposer.json

composer require doctrine/dbal

Обновление атрибутов столбца

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

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

Мы также можем изменить столбец так, чтобы он мог обнуляться:

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

Только следующие типы столбцов могут быть изменены: bigInteger, двоичный, логический, дата, dateTime, dateTimeTz, десятичный, целочисленный, json, longText, mediumText, smallInteger, строка, текст, время, unsignedBigInteger, unsignedInteger и unsignedSmallInteger.

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

Чтобы переименовать столбец, вы можете использовать renameColumnметод в построителе схемы. Перед переименованием столбца обязательно добавьте зависимость в ваш файл:doctrine/dbalcomposer.json

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

Переименование любого столбца в таблице, которая также имеет столбец типа, enumв настоящее время не поддерживается.

 

Отбрасывание столбцов

Чтобы удалить столбец, используйте dropColumnметод в построителе схемы. Прежде чем удалять столбцы из базы данных SQLite, вам нужно добавить зависимость в ваш файл и запустить команду в своем терминале для установки библиотеки:doctrine/dbalcomposer.jsoncomposer update

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

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

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

Удаление или изменение нескольких столбцов в рамках одной миграции при использовании базы данных SQLite не поддерживается.

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

команда Описание
$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');

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

$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::defaultStringLengthAppServiceProvider

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'); Удалите пространственный индекс из таблицы «geo» (кроме SQLite).

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

Schema::table('geo', function (Blueprint $table) {
    $table->dropIndex(['state']); // Drops index '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();

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