Ответ
Soft Delete (мягкое удаление) — это паттерн, при котором запись в базе данных не удаляется физически оператором DELETE, а помечается как удалённая с помощью специального флага (например, колонки deleted_at типа TIMESTAMP или is_deleted типа BOOLEAN). Это позволяет сохранять данные для истории, аудита или возможности восстановления.
Типичная реализация:
- В таблицу добавляется поле
deleted_at(NULL по умолчанию). - При "удалении" в это поле записывается текущая дата и время (вместо настоящего удаления).
- Все основные выборки (
SELECT) автоматически фильтруют записи по условиюWHERE deleted_at IS NULL.
Пример на SQL:
-- Создание таблицы
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100),
deleted_at TIMESTAMP NULL DEFAULT NULL
);
-- "Мягкое" удаление пользователя с id = 5
UPDATE users SET deleted_at = NOW() WHERE id = 5;
-- Выборка только активных пользователей
SELECT * FROM users WHERE deleted_at IS NULL;
-- Выборка всех пользователей, включая удалённых
SELECT * FROM users;
-- Восстановление пользователя
UPDATE users SET deleted_at = NULL WHERE id = 5;
Реализация в Laravel Eloquent:
Laravel предоставляет трейт SoftDeletes для удобной работы с этим паттерном.
// В модели
use IlluminateDatabaseEloquentModel;
use IlluminateDatabaseEloquentSoftDeletes;
class User extends Model {
use SoftDeletes; // Добавляет функциональность мягкого удаления
protected $dates = ['deleted_at'];
}
// Использование
$user = User::find(1);
$user->delete(); // Заполняет колонку `deleted_at` текущей датой
// Стандартные запросы игнорируют удалённые записи
$activeUsers = User::all(); // Только где deleted_at IS NULL
// Для работы со всеми записями
$allUsers = User::withTrashed()->get();
$trashedUsers = User::onlyTrashed()->get();
// Восстановление
User::withTrashed()->find(1)->restore(); // Обнуляет deleted_at
// Полное физическое удаление
User::withTrashed()->find(1)->forceDelete();
Преимущества Soft Delete:
- Безопасность данных: Возможность восстановить случайно удалённые данные.
- Целостность ссылок: Внешние ключи не нарушаются, так как запись физически остаётся в таблице.
- Аудит: Сохраняется полная история всех записей.
Недостатки и сложности:
- Усложнение запросов: Необходимо всегда помнить о фильтрации по
deleted_at. В Laravel это решается на уровне ORM. - Рост базы данных: Требуется периодическая архивация или очистка старых "удалённых" записей.
- Уникальные индексы: Могут возникнуть конфликты, если уникальность должна учитывать только активные записи. Решение — использовать составные индексы, включающие
deleted_at.