Миграции и структура базы данных
Проектирование базы данных интернет-магазина. Создание таблиц товаров и категорий с помощью системы контроля версий баз данных Laravel (Миграций).
Миграции: Git для вашей базы данных
При разработке интернет-магазина в команде (или даже в одиночку при переносе проекта на хостинг) возникает проблема: как синхронизировать структуру базы данных? Если вы вручную создадите таблицу products через phpMyAdmin, то при деплое (публикации) приложения вам придется делать это снова на боевом сервере. И здесь на помощь приходят Миграции Laravel.
Миграции — это система контроля версий для вашей базы данных. Вместо SQL-запросов вы описываете структуру таблиц с помощью PHP-кода. Laravel сам переведет этот код в нужный диалект SQL (MySQL, PostgreSQL, SQLite). Каждая миграция содержит два метода: up() (выполняется при накатывании миграции, например, создание таблицы) и down() (выполняется при откате, отменяет действия метода up, например, удаляет таблицу).
Для создания миграции используется Artisan-команда php artisan make:migration create_products_table. Laravel создаст файл в папке database/migrations с временной меткой в имени (чтобы гарантировать правильный порядок выполнения). Внутри вы используете фасад Schema и класс Blueprint для определения колонок: строк, чисел, дат и связей (внешних ключей).
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
// Метод up() создает таблицу и колонки
public function up() {
Schema::create('products', function (Blueprint $table) {
$table->id(); // Первичный ключ, автоинкремент (bigint (BIGINT UNSIGNED)
// Внешний ключ, связывающий товар с таблицей categories
// cascadeOnDelete() удалит товары, если удалить их категорию
$table->foreignId('category_id')->constrained()->cascadeOnDelete();
$table->string('name'); // VARCHAR(255)
$table->text('description')->nullable(); // Текст, может быть NULL
$table->decimal('price', 8, 2); // Число с плавающей точкой (999999.99)
// Автоматически создает колонки created_at и updated_at
$table->timestamps();
});
}
// Метод down() отменяет изменения (вызывается при откате)
public function down() {
Schema::dropIfExists('products');
}
};
Типы данных и Внешние ключи
В примере выше мы использовали специфичные для Laravel методы определения колонок. Разберем их подробнее, так как правильная структура БД критична для e-commerce.
Метод $table->decimal('price', 8, 2) идеально подходит для хранения цен. В отличие от типа float, decimal не имеет проблем с потерей точности при математических операциях (что недопустимо при работе с деньгами). Цифра 8 означает общее количество знаков, а 2 — количество знаков после запятой.
Метод $table->foreignId('category_id')->constrained() — это магия Laravel. Он автоматически создает колонку типа BIGINT UNSIGNED, а метод constrained() догадывается (по имени колонки category_id), что внешний ключ должен ссылаться на колонку id в таблице categories. Метод cascadeOnDelete() гарантирует целостность данных: если администратор удалит категорию 'Ноутбуки', все ноутбуки в БД будут автоматически удалены, предотвращая появление 'осиротевших' записей.
Типичная ошибка: попытка создать таблицу products до создания таблицы categories. Поскольку products ссылается на categories, миграция категорий должна иметь более раннюю дату в имени файла (выполняться первой). Иначе СУБД выдаст ошибку создания внешнего ключа.
Для чего используется метод $table->timestamps() в миграциях Laravel?
Напишите команду Artisan, которая применяет (запускает) все ожидающие миграции в базу данных.
Задание
Сценарий: Вы допустили ошибку в структуре таблицы и нужно ее исправить. База данных пока пустая (находится в разработке).
- Выполните команду php artisan migrate:rollback, чтобы отменить последнюю партию миграций (вызовется метод down()).
- Откройте файл миграции create_products_table.
- Добавьте новое поле: $table->boolean('is_active')->default(true);
- Снова выполните php artisan migrate, чтобы применить обновленную структуру таблиц.