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

Вступ

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

Фасад Schema facade надає підтримку, незалежну від бази даних, для створення та маніпулювання таблицями у всіх підтримуваних системах баз даних Laravel. Зазвичай міграції використовують цей фасад для створення та зміни таблиць і стовпців бази даних.

Генерація Міграцій

Ви можете використовувати команду make:migration Artisan для створення міграції бази даних. Нова міграція буде розміщена у вашому каталозі 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
 
# Вивантажити поточну схему бази даних і видалити всі наявні міграції...
php artisan schema:dump --prune

Коли ви виконуєте цю команду, Laravel запише файл "схеми" в директорію database/schema вашого застосунку. Ім'я файлу схеми буде відповідати підключенню до бази даних. Тепер, коли ви намагаєтеся виконати міграцію вашої бази даних і жодні інші міграції не були виконані, Laravel спочатку виконає SQL інструкції у файлі схеми підключення до бази даних, яке ви використовуєте. Після виконання SQL інструкцій файлу схеми, Laravel виконає всі інші міграції, які не були частиною дампу схеми.

Якщо тести вашого застосунку використовують інше підключення до бази даних, ніж те, яке ви зазвичай використовуєте під час локальної розробки, ви повинні переконатися, що ви згенерували файл схеми, використовуючи це підключення до бази даних, щоб ваші тести могли побудувати вашу базу даних. Ви можете захотіти зробити це після згенерування підключення до бази даних, яке ви зазвичай використовуєте під час локальної розробки:

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

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

Стискання міграцій доступне лише для баз даних MariaDB, MySQL, PostgreSQL та SQLite і використовує клієнт командного рядка бази даних.

Структура Міграцій

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

У межах обох цих методів ви можете використовувати конструктор схем Laravel для виразного створення та модифікації таблиць. Щоб дізнатися про всі методи, доступні в конструкторі Schema, ознайомтеся з його документацією. Наприклад, наступна міграція створює таблицю flights:

<?php
 
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
 
return new class extends Migration
{
/**
* Запустити міграції.
*/
public function up(): void
{
Schema::create('flights', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('airline');
$table->timestamps();
});
}
 
/**
* Скасувати міграції.
*/
public function down(): void
{
Schema::drop('flights');
}
};

Встановлення Підключення Міграції

Якщо ваша міграція буде взаємодіяти з підключенням до бази даних, відмінним від підключення до бази даних за замовчуванням вашого застосунку, ви повинні встановити властивість $connection вашої міграції:

/**
* З’єднання з базою даних, яке слід використовувати для міграції.
*
* @var string
*/
protected $connection = 'pgsql';
 
/**
* Запустити міграції.
*/
public function up(): void
{
// ...
}

Пропуск міграцій

Іноді міграція може бути призначена для підтримки функції, яка ще не активна, і ви не хочете, щоб вона виконувалася. У цьому випадку ви можете визначити метод shouldRun у міграції. Якщо метод shouldRun повертає false, міграція буде пропущена:

use App\Models\Flights;
use Laravel\Pennant\Feature;
 
/**
* Визначити, чи слід виконувати цю міграцію.
*/
public function shouldRun(): bool
{
return Feature::active(Flights::class);
}

Запуск Міграцій

Щоб виконати всі ваші невиконані міграції, виконайте команду Artisan migrate:

php artisan migrate

Якщо ви хочете побачити, які міграції були виконані до цього часу, ви можете скористатися командою Artisan migrate:status:

php artisan migrate:status

Якщо ви хочете побачити SQL інструкції, які будуть виконані міграціями без фактичного їх виконання, ви можете додати прапорець --pretend до команди migrate:

php artisan migrate --pretend

Ізоляція Виконання Міграцій

Якщо ви розгортаєте ваш застосунок на декількох серверах і запускаєте міграції як частину процесу розгортання, ви, ймовірно, не хочете, щоб два сервери намагалися мігрувати базу даних одночасно. Щоб уникнути цього, ви можете використовувати опцію isolated при виклику команди migrate.

Коли надано опцію isolated, Laravel отримає атомарний блок, використовуючи драйвер кешу вашого застосунку, перед спробою виконати ваші міграції. Усі інші спроби виконати команду migrate, поки цей блок утримується, не будуть виконані; однак команда все одно завершиться з успішним кодом виходу:

php artisan migrate --isolated

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

Примусове виконання міграцій у виробничому середовищі

Деякі операції міграції є руйнівними, що означає, що вони можуть призвести до втрати даних. Щоб захистити вас від виконання цих команд проти вашої продуктивної бази даних, перед виконанням команд вам буде запропоновано підтвердження. Щоб примусово виконати команди без запиту, використовуйте прапорець --force:

php artisan migrate --force

Відкат Міграцій

Щоб відкотити останню операцію міграції, ви можете скористатися командою Artisan rollback. Ця команда відкатує останню "партію" міграцій, яка може включати декілька файлів міграцій:

php artisan migrate:rollback

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

php artisan migrate:rollback --step=5

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

php artisan migrate:rollback --batch=3

Якщо ви хочете побачити SQL інструкції, які будуть виконані міграціями без фактичного їх виконання, ви можете додати прапорець --pretend до команди migrate:rollback:

php artisan migrate:rollback --pretend

Команда migrate:reset відкотить всі міграції вашого застосунку:

php artisan migrate:reset

Відкат і міграція за допомогою однієї команди

Команда migrate:refresh відкотить усі ваші міграції, а потім виконає команду migrate. Ця команда ефективно відтворює всю вашу базу даних:

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

Ви можете відкотити та повторно виконати обмежену кількість міграцій, вказавши опцію step для команди refresh. Наприклад, наступна команда відкотить та повторно виконає останні п'ять міграцій:

php artisan migrate:refresh --step=5

Видалити всі таблиці та виконати міграцію

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

php artisan migrate:fresh
 
php artisan migrate:fresh --seed

За замовчуванням команда migrate:fresh видаляє таблиці лише з підключення до бази даних за замовчуванням. Однак, ви можете використовувати опцію --database, щоб вказати підключення до бази даних, яке слід мігрувати. Ім'я підключення до бази даних має відповідати підключенню, визначеному у database файлі конфігурації вашого застосунку:

php artisan migrate:fresh --database=admin

Команда migrate:fresh видалить всі таблиці бази даних незалежно від їх префіксу. Цю команду слід використовувати з обережністю при розробці на базі даних, яка спільно використовується з іншими застосунками.

Таблиці

Створення таблиць

Щоб створити нову таблицю бази даних, використовуйте метод create на фасаді Schema. Метод create приймає два аргументи: перший - це назва таблиці, а другий - це замикання, яке отримує об'єкт Blueprint, що може бути використаний для визначення нової таблиці:

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
 
Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('email');
    $table->timestamps();
});

Коли створюєте таблицю, ви можете використовувати будь-які з методів створення стовпців конструктора схем для визначення стовпців таблиці.

Визначення Існування Таблиці / Стовпця

Ви можете визначити існування таблиці, стовпця або індексу, використовуючи методи hasTable, hasColumn та hasIndex:

if (Schema::hasTable('users')) {
// Таблиця "users" існу...
}
 
if (Schema::hasColumn('users', 'email')) {
// Таблиця "users" існує і містить стовпець "email"...
}
 
if (Schema::hasIndex('users', ['email'], 'unique')) {
// Таблиця "users" існує і має унікальний індекс на стовпець "email"...
}

Параметри підключення до бази даних та таблиці

Якщо ви хочете виконати операцію зі схемою на з'єднанні з базою даних, яке не є з'єднанням за замовчуванням вашого застосунку, використовуйте метод connection:

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

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

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

Властивості charset та collation можуть бути використані для вказівки набору символів та колації для створеної таблиці при використанні MariaDB або 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 на екземплярі таблиці. Коментарі до таблиць наразі підтримуються лише MariaDB, MySQL та PostgreSQL:

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

Доступні типи стовпців

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

Типи Boolean

Рядки & Текстові Типи

Числові типи

Типи Дати & Часу

Бінарні типи

Об'єкт & Json Типи

UUID & ULID Типи

Типи Простору

Типи Відносин

Типи Спеціальностей

bigIncrements()

Метод bigIncrements створює автоінкрементний стовпець, еквівалентний UNSIGNED BIGINT (первинний ключ):

$table->bigIncrements('id');

bigInteger()

Метод bigInteger створює стовпець, еквівалентний BIGINT:

$table->bigInteger('votes');

binary()

Метод binary створює стовпець, еквівалентний BLOB:

$table->binary('photo');

Коли ви використовуєте MySQL, MariaDB або SQL Server, ви можете передати аргументи length і fixed для створення еквівалентного стовпця VARBINARY або BINARY:

$table->binary('data', length: 16); // VARBINARY(16)
 
$table->binary('data', length: 16, fixed: true); // BINARY(16)

boolean()

Метод boolean створює еквівалентний стовпець типу BOOLEAN:

$table->boolean('confirmed');

char()

Метод char створює еквівалент стовпця CHAR з заданою довжиною:

$table->char('name', length: 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', total: 8, places: 2);

double()

Метод double створює стовпець, еквівалентний DOUBLE:

$table->double('amount');

enum()

Метод enum створює еквівалент стовпця ENUM з заданими допустимими значеннями:

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

float()

Метод float створює еквівалентний стовпець FLOAT з заданою точністю:

$table->float('amount', precision: 53);

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

geography()

Метод geography створює еквівалентний стовпець GEOGRAPHY з вказаним просторовим типом та SRID (Ідентифікатор Просторової Системи Відліку):

$table->geography('coordinates', subtype: 'point', srid: 4326);

Підтримка просторових типів залежить від вашого драйвера бази даних. Будь ласка, зверніться до документації вашої бази даних. Якщо ваш застосунок використовує базу даних PostgreSQL, ви повинні встановити розширення PostGIS перед тим, як метод geography може бути використаний.

geometry()

Метод geometry створює еквівалентний стовпець GEOMETRY з вказаним просторовим типом та SRID (Ідентифікатор Просторової Системи Відліку):

$table->geometry('positions', subtype: 'point', srid: 0);

Підтримка просторових типів залежить від вашого драйвера бази даних. Будь ласка, зверніться до документації вашої бази даних. Якщо ваш застосунок використовує базу даних PostgreSQL, ви повинні встановити розширення PostGIS перед тим, як метод geometry може бути використаний.

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

Коли використовується PostgreSQL, буде створено стовпець INET.

json()

Метод json створює еквівалент стовпця JSON:

$table->json('options');

Коли використовується SQLite, буде створено стовпець TEXT.

jsonb()

Метод jsonb створює еквівалент стовпця JSONB:

$table->jsonb('options');

Коли використовується SQLite, буде створено стовпець TEXT.

longText()

Метод longText створює стовпець, еквівалентний LONGTEXT:

$table->longText('description');

Коли використовуєте MySQL або MariaDB, ви можете застосувати набір символів binary до стовпця, щоб створити еквівалент стовпця LONGBLOB:

$table->longText('data')->charset('binary'); // LONGBLOB

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

Коли ви використовуєте MySQL або MariaDB, ви можете застосувати набір символів binary до стовпця, щоб створити еквівалент стовпця MEDIUMBLOB:

$table->mediumText('data')->charset('binary'); // MEDIUMBLOB

morphs()

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

Цей метод призначений для використання при визначенні стовпців, необхідних для поліморфного Eloquent відношення. У наступному прикладі будуть створені стовпці taggable_id та taggable_type:

$table->morphs('taggable');

nullableMorphs()

Метод подібний до методу morphs; однак стовпці, які створюються, будуть "nullable":

$table->nullableMorphs('taggable');

nullableUlidMorphs()

Метод схожий на метод ulidMorphs; однак, стовпці, які створюються, будуть "nullable":

$table->nullableUlidMorphs('taggable');

nullableUuidMorphs()

Метод схожий на метод uuidMorphs; однак, стовпці, які створюються, будуть "nullable":

$table->nullableUuidMorphs('taggable');

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 (з часовою зоною), який може бути nullable, з необов'язковою точністю до часток секунди. Цей стовпець призначений для зберігання мітки часу deleted_at, необхідної для функціональності "м'якого видалення" в Eloquent:

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

softDeletes()

Метод softDeletes додає стовпець TIMESTAMP з можливістю зберігання нульового значення deleted_at з необов'язковою точністю до часток секунди. Цей стовпець призначений для зберігання мітки часу deleted_at, необхідної для функціональності "м'якого видалення" в Eloquent:

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

string()

Метод string створює еквівалентний стовпець VARCHAR заданої довжини:

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

text()

Метод text створює еквівалент стовпця TEXT:

$table->text('description');

Коли ви використовуєте MySQL або MariaDB, ви можете застосувати набір символів binary до стовпця, щоб створити еквівалент стовпця BLOB:

$table->text('data')->charset('binary'); // BLOB

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

Коли використовуєте MySQL або MariaDB, ви можете застосувати набір символів binary до стовпця, щоб створити еквівалент стовпця TINYBLOB:

$table->tinyText('data')->charset('binary'); // TINYBLOB

unsignedBigInteger()

Метод unsignedBigInteger створює еквівалент стовпця UNSIGNED BIGINT:

$table->unsignedBigInteger('votes');

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

vector()

Метод vector створює стовпець, еквівалентний vector:

$table->vector('embedding', dimensions: 100);

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') Розмістити стовпець після іншого стовпця (MariaDB / MySQL).
->autoIncrement() Зробити стовпець типу INTEGER автоінкрементним (первинний ключ).
->charset('utf8mb4') Вказати кодування символів для стовпця (MariaDB / MySQL).
->collation('utf8mb4_unicode_ci') Вказати зіставлення для стовпця.
->comment('my comment') Додати коментар до стовпця (MariaDB / MySQL / PostgreSQL).
->default($value) Вказати значення за замовчуванням для стовпця.
->first() Розмістити стовпець першим у таблиці (MariaDB / MySQL).
->from($integer) Встановити початкове значення для автоінкрементного поля (MariaDB / MySQL / PostgreSQL).
->invisible() Зробити стовпець "невидимим" для запитів SELECT * (MariaDB / MySQL).
->nullable($value = true) Дозволити вставку значень NULL у стовпець.
->storedAs($expression) Створити збережений генерований стовпець (MariaDB / MySQL / PostgreSQL / SQLite).
->unsigned() Зробити стовпець типу INTEGER беззнаковим (UNSIGNED) (MariaDB / MySQL).
->useCurrent() Встановити значення за замовчуванням CURRENT_TIMESTAMP для стовпців типу TIMESTAMP.
->useCurrentOnUpdate() Використовувати CURRENT_TIMESTAMP при оновленні запису для стовпців типу TIMESTAMP (MariaDB / MySQL).
->virtualAs($expression) Створити віртуальний генерований стовпець (MariaDB / MySQL / SQLite).
->generatedAs($expression) Створити стовпець-ідентифікатор зі вказаними параметрами послідовності (PostgreSQL).
->always() Визначає пріоритет значень послідовності над введеними для стовпця-ідентифікатора (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();
});
}
};

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

Порядок Стовпців

Коли використовується база даних MariaDB або 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();
});

Метод change не змінює індекси стовпця. Тому ви можете використовувати модифікатори індексу, щоб явно додати або видалити індекс при зміні стовпця:

// Додати індекс...
$table->bigIncrements('id')->primary()->change();
 
// Видалити індекс...
$table->char('postal_code', 10)->unique(false)->change();

Перейменування стовпців

Щоб перейменувати стовпець, ви можете використовувати метод renameColumn, наданий конструктором схем:

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

Видалення стовпців

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

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

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

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

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

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

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

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

Коли створюється індекс, Laravel автоматично згенерує ім'я індексу на основі таблиці, імен стовпців та типу індексу, але ви можете передати другий аргумент методу, щоб вказати ім'я індексу самостійно:

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

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

Клас схеми Laravel blueprint надає методи для створення кожного типу індексу, підтримуваного Laravel. Кожен метод індексу приймає необов'язковий другий аргумент для вказівки імені індексу. Якщо його не вказано, ім'я буде виведено з імен таблиці та стовпця(ів), які використовуються для індексу, а також типу індексу. Кожен з доступних методів індексу описаний у таблиці нижче:

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

Перейменування індексів

Щоб перейменувати індекс, ви можете використовувати метод 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->dropFullText('posts_body_fulltext'); Видалити повнотекстовий індекс із таблиці "posts".
$table->dropSpatialIndex('geo_location_spatialindex'); Видалити просторовий індекс із таблиці "geo" (крім SQLite).

Якщо ви передаєте масив стовпців у метод, який видаляє індекси, стандартне ім'я індексу буде згенеровано на основі імені таблиці, стовпців та типу індексу:

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

Обмеження зовнішнього ключа

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

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
 
Schema::table('posts', function (Blueprint $table) {
    $table->unsignedBigInteger('user_id');
 
    $table->foreign('user_id')->references('id')->on('users');
});

Оскільки цей синтаксис досить багатослівний, Laravel надає додаткові, коротші методи, які використовують конвенції для покращення досвіду розробника. Використовуючи метод foreignId для створення вашої колонки, наведений вище приклад можна переписати так:

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

Метод foreignId створює стовпець, еквівалентний UNSIGNED BIGINT, тоді як метод constrained використовуватиме конвенції для визначення таблиці та стовпця, на які посилаються. Якщо назва вашої таблиці не відповідає конвенціям Laravel, ви можете вручну надати її методу constrained. Крім того, можна вказати ім'я, яке має бути призначене згенерованому індексу:

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

Ви також можете вказати бажану дію для властивостей "on delete" та "on update" обмеження:

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

Також надається альтернативний, виразний синтаксис для цих дій:

Метод Опис
$table->cascadeOnUpdate(); Оновлення повинні каскадуватися.
$table->restrictOnUpdate(); Оновлення повинні бути обмежені.
$table->nullOnUpdate(); Оновлення повинні встановлювати зовнішній ключ у значення null.
$table->noActionOnUpdate(); Жодних дій при оновленні.
$table->cascadeOnDelete(); Видалення повинні каскадуватися.
$table->restrictOnDelete(); Видалення повинні бути обмежені.
$table->nullOnDelete(); Видалення повинні встановлювати зовнішній ключ у значення null.
$table->noActionOnDelete(); Забороняє видалення, якщо існують дочірні записи.

Будь-які додаткові модифікатори стовпців повинні бути викликані перед методом 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, переконайтеся, що увімкнено підтримку зовнішніх ключів у вашій конфігурації бази даних перед тим, як намагатися створити їх у ваших міграціях.

Події

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

Клас Опис
Illuminate\Database\Events\MigrationsStarted Партія міграцій ось-ось буде виконана.
Illuminate\Database\Events\MigrationsEnded Партія міграцій завершила виконання.
Illuminate\Database\Events\MigrationStarted Одна міграція ось-ось буде виконана.
Illuminate\Database\Events\MigrationEnded Одна міграція завершила виконання.
Illuminate\Database\Events\NoPendingMigrations Команда міграції не виявила жодних очікуючих міграцій.
Illuminate\Database\Events\SchemaDumped Вивантаження схеми бази даних завершено.
Illuminate\Database\Events\SchemaLoaded Існуюче вивантаження схеми бази даних завантажено.