База Данных: Миграции
Введение
Миграции подобны контролю версий для вашей базы данных, позволяя вашей команде определять и совместно использовать определение схемы базы данных приложения. Если вам когда-либо приходилось просить товарища по команде вручную добавить столбец в их локальную схему базы данных после внесения ваших изменений из системы управления версиями, вы сталкивались с проблемой, которую решает миграция базы данных.
Laravel Schema
фасад обеспечивает независимую от базы данных поддержку для создания и управления таблицами во всех поддерживаемых Laravel системах баз данных. Как правило, миграция будет использовать этот фасад для создания и изменения таблиц и столбцов базы данных.
Создание миграций
Вы можете использовать make:migration
Artisan команду для создания миграции базы данных. Новая миграция будет помещена в ваш каталог database/migrations
. Каждое имя файла миграции содержит отметку времени, которая позволяет Laravel определять порядок миграции:
php artisan make:migration create_flights_table
Laravel будет использовать имя миграции, чтобы попытаться угадать имя таблицы и будет ли миграция создавать новую таблицу. Если Laravel сможет определить имя таблицы по имени миграции, Laravel предварительно заполнит сгенерированный файл миграции указанной таблицей. В противном случае вы можете просто указать таблицу в файле миграции вручную.
Если вы хотите указать собственный путь для сгенерированной миграции, вы можете использовать параметр --path
при выполнении команды make:migration
. Указанный путь должен относиться к базовому пути вашего приложения.
{tip} Заглушки миграции можно настроить с помощью публикации заглушек.
Сжатие миграций
По мере создания приложения вы можете накапливать все больше и больше миграций с течением времени. Это может привести к тому, что ваш каталог 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 файла схемы. После выполнения операторов файла схемы Laravel выполнит все оставшиеся миграции, которые не были частью дампа схемы.
Вы должны зафиксировать файл схемы базы данных в системе управления версиями, чтобы другие новые разработчики в вашей команде могли быстро создать начальную структуру базы данных вашего приложения.
{note} Сжатие миграции доступно только для баз данных 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; class CreateFlightsTable extends Migration{ /** * Run the migrations. * * @return void */ public function up() { Schema::create('flights', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('airline'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::drop('flights'); }}
Анонимные миграции
Как вы могли заметить в приведенном выше примере, Laravel автоматически присваивает имя класса всем миграциям, которые вы создаете с помощью команды make:migration
. Однако при желании вы можете вернуть анонимный класс из файла миграции. Это в первую очередь полезно, если ваше приложение накапливает много миграций, и две из них имеют конфликт имен классов:
<?php use Illuminate\Database\Migrations\Migration; return new class extends Migration{ //};
Настройка соединения миграции
Если ваша миграция будет взаимодействовать с подключением к базе данных, отличным от подключения к базе данных вашего приложения по умолчанию, вы должны установить свойство $connection
вашей миграции:
/** * The database connection that should be used by the migration. * * @var string */protected $connection = 'pgsql'; /** * Run the migrations. * * @return void */public function up(){ //}
Запуск миграций
Чтобы запустить все незавершенные миграции, выполните Artisan-команду migrate
:
php artisan migrate
Если вы хотите увидеть, какие миграции уже были выполнены, вы можете использовать Artisan-команду migrate:status
:
php artisan migrate:status
Принудительное выполнение миграции в продакшене
Некоторые операции миграции являются деструктивными, что означает, что они могут привести к потере данных. Чтобы защитить вас от запуска этих команд в вашей производственной базе данных, вам будет предложено подтвердить перед выполнением команд. Чтобы заставить команды запускаться без приглашения, используйте флаг --force
:
php artisan migrate --force
Откат миграций
Чтобы откатить последнюю операцию миграции, вы можете использовать Artisan-команду 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 // 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
{note} Команда
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')) { // The "users" table exists...} if (Schema::hasColumn('users', 'email')) { // The "users" table exists and has an "email" column...}
Подключение к базе данных и параметры таблицы
Если вы хотите выполнить операцию схемы над подключением к базе данных, которое не является подключением вашего приложения по умолчанию, используйте метод 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(); // ...});
Обновление таблиц
Метод 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 bigInteger binary boolean char dateTimeTz dateTime date decimal double enum float foreignId foreignIdFor foreignUuid geometryCollection geometry id increments integer ipAddress json jsonb lineString longText macAddress mediumIncrements mediumInteger mediumText morphs multiLineString multiPoint multiPolygon nullableMorphs nullableTimestamps nullableUuidMorphs point polygon rememberToken set smallIncrements smallInteger softDeletesTz softDeletes string text timeTz time timestampTz timestamp timestampsTz timestamps tinyIncrements tinyInteger tinyText unsignedBigInteger unsignedDecimal unsignedInteger unsignedMediumInteger unsignedSmallInteger unsignedTinyInteger uuidMorphs uuid year
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
для данного класса модели:
$table->foreignIdFor(User::class);
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');
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
UNSIGNED BIGINT
и эквивалентный столбец {column}_type
VARCHAR
.
Этот метод предназначен для использования при определении столбцов, необходимых для полиморфного отношения 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');
nullableUuidMorphs()
Этот метод аналогичен методу uuidMorphs; однако созданные столбцы будут "nullable":
$table->nullableUuidMorphs('taggable');
point()
Метод point
создает столбец, эквивалентный POINT
:
$table->point('position');
polygon()
Метод polygon
создает столбец, эквивалентный POLYGON
:
$table->polygon('position');
rememberToken()
Метод rememberToken
создает столбец, эквивалентный VARCHAR(100)
, допускающий значение NULL, который предназначен для хранения текущего "запомнить меня" токен аутентификации:
$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
(с часовым поясом), допускающий значение NULL, с необязательной точностью (общее количество цифр). Этот столбец предназначен для хранения метки времени deleted_at
, необходимой для функции "мягкого удаления" Eloquent:
$table->softDeletesTz($column = 'deleted_at', $precision = 0);
softDeletes()
Метод softDeletes
добавляет столбец, эквивалентный deleted_at
TIMESTAMP
, допускающий значение NULL, с необязательной точностью (общее количество цифр). Этот столбец предназначен для хранения метки времени 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');
uuidMorphs()
Метод uuidMorphs
представляет собой удобный метод, который добавляет эквивалентный столбец {column}_id
CHAR(36)
и эквивалентный столбец {column}_type
VARCHAR
.
Этот метод предназначен для использования при определении столбцов, необходимых для полиморфного Eloquent релейшена, в котором используются идентификаторы UUID. В следующем примере будут созданы столбцы taggable_id
и taggable_type
:
$table->uuidMorphs('taggable');
uuid()
Метод uuid
создает эквивалентный столбец UUID
:
$table->uuid('id');
year()
Метод 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). |
->unsigned() |
Установите столбцы INTEGER как UNSIGNED (MySQL). |
->useCurrent() |
Установите столбцы TIMESTAMP для использования CURRENT_TIMESTAMP в качестве значения по умолчанию. |
->useCurrentOnUpdate() |
Установите столбцы TIMESTAMP для использования CURRENT_TIMESTAMP при обновлении записи. |
->virtualAs($expression) |
Создайте виртуальный сгенерированный столбец (MySQL). |
->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; class CreateFlightsTable extends Migration{ /** * Run the migrations. * * @return void */ public function up() { Schema::create('flights', function (Blueprint $table) { $table->id(); $table->json('movies')->default(new Expression('(JSON_ARRAY())')); $table->timestamps(); }); }}
{note} Поддержка выражений по умолчанию зависит от вашего драйвера базы данных, версии базы данных и типа поля. Пожалуйста, обратитесь к документации вашей базы данных.
Порядок столбцов
При использовании базы данных MySQL метод after
может использоваться для добавления столбцов после существующего столбца в схеме:
$table->after('password', function ($table) { $table->string('address_line1'); $table->string('address_line2'); $table->string('city');});
Изменение столбцов
Предпосылки
Перед изменением столбца вы должны установить пакет doctrine/dbal
с помощью менеджера пакетов Composer. Библиотека Doctrine DBAL используется для определения текущего состояния столбца и для создания SQL-запросов, необходимых для внесения запрошенных изменений в ваш столбец:
composer require doctrine/dbal
Если вы планируете изменять столбцы, созданные с помощью метода timestamp
, вы также должны добавить следующую конфигурацию в файл конфигурации config/database.php
вашего приложения:
use Illuminate\Database\DBAL\TimestampType; 'dbal' => [ 'types' => [ 'timestamp' => TimestampType::class, ],],
{note} Если ваше приложение использует Microsoft SQL Server, убедитесь, что вы установили
doctrine/dbal:^3.0
.
Обновление атрибутов столбца
Метод change
позволяет изменять тип и атрибуты существующих столбцов. Например, вы можете увеличить размер столбца string
. Чтобы увидеть метод change
в действии, давайте увеличим размер столбца name
с 25 до 50. Для этого мы просто определяем новое состояние столбца, а затем вызываем метод change
:
Schema::table('users', function (Blueprint $table) { $table->string('name', 50)->change();});
Мы также можем изменить столбец, чтобы он обнулялся:
Schema::table('users', function (Blueprint $table) { $table->string('name', 50)->nullable()->change();});
{note} Можно изменить следующие типы столбцов:
bigInteger
,binary
,boolean
,date
,dateTime
,dateTimeTz
,decimal
,integer
,json
,longText
,mediumText
,smallInteger
,string
,text
,time
,unsignedBigInteger
,unsignedInteger
,unsignedSmallInteger
иuuid
. Чтобы изменить тип столбцаtimestamp
Doctrine type must be registered.
Переименование столбцов
Чтобы переименовать столбец, вы можете использовать метод renameColumn
, предоставляемый чертежом построителя схемы. Перед переименованием столбца убедитесь, что вы установили библиотеку doctrine/dbal
через менеджер пакетов Composer:
Schema::table('users', function (Blueprint $table) { $table->renameColumn('from', 'to');});
{note} Renaming an
enum
column is not currently supported.
Удаление столбцов
Чтобы удалить столбец, вы можете использовать метод dropColumn
в схеме построителя схемы. Если ваше приложение использует базу данных SQLite, вы должны установить пакет doctrine/dbal
через диспетчер пакетов Composer, прежде чем можно будет использовать метод dropColumn
:
Schema::table('users', function (Blueprint $table) { $table->dropColumn('votes');});
Вы можете удалить несколько столбцов из таблицы, передав массив имен столбцов методу dropColumn
:
Schema::table('users', function (Blueprint $table) { $table->dropColumn(['votes', 'avatar', 'location']);});
{note} Удаление или изменение нескольких столбцов в рамках одной миграции при использовании базы данных SQLite не поддерживается.
Доступные псевдонимы команд
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 предоставляет методы для создания каждого типа индекса, поддерживаемого 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; /** * 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'); |
Удалите первичный ключ из таблицы "users". |
$table->dropUnique('users_email_unique'); |
Удалить уникальный индекс из таблицы "users". |
$table->dropIndex('geo_state_index'); |
Удалите базовый индекс из таблицы "geo". |
$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('users');});
Вы также можете указать желаемое действие для свойств «при удалении» и «при обновлении» ограничения:
$table->foreignId('user_id') ->constrained() ->onUpdate('cascade') ->onDelete('cascade');
Для этих действий также предусмотрен альтернативный выразительный синтаксис:
Метод | Описание |
---|---|
$table->cascadeOnUpdate(); |
Обновления должны происходить каскадом. |
$table->restrictOnUpdate(); |
Обновления должны быть ограничены. |
$table->cascadeOnDelete(); |
Удаление должно происходить каскадом. |
$table->restrictOnDelete(); |
Удаление должно быть ограничено. |
$table->nullOnDelete(); |
Удаления должны установить значение внешнего ключа равным нулю. |
Любые дополнительные модификаторы столбцов должны вызываться до метода 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();
{note} SQLite по умолчанию отключает ограничения внешнего ключа. При использовании SQLite обязательно включите поддержку внешнего ключа в конфигурации вашей базы данных, прежде чем пытаться создать их в своих миграциях. Кроме того, SQLite поддерживает внешние ключи только при создании таблицы и не при изменении таблиц.
События
Для удобства каждая операция переноса будет отправлять событие. Все следующие события расширяют базовый класс Illuminate\Database\Events\MigrationEvent
:
Класс | Описание |
---|---|
Illuminate\Database\Events\MigrationsStarted |
Пакет миграций вот-вот будет выполнен. |
Illuminate\Database\Events\MigrationsEnded |
Выполнение пакета миграций завершено. |
Illuminate\Database\Events\MigrationStarted |
Будет выполнена одиночная миграция. |
Illuminate\Database\Events\MigrationEnded |
Выполнение одной миграции завершено. |