Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як задати значення за замовчуванням виразом і автоматично оновлювати updated_at?

Автоматичні мітки часу - для TIMESTAMP і DATETIME:

CREATE TABLE posts (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
  • DEFAULT CURRENT_TIMESTAMP - значення при вставці, якщо колонку не передали.
  • ON UPDATE CURRENT_TIMESTAMP - автоматичне оновлення при будь-якій зміні рядка.
  • Дробові секунди - з точністю: DATETIME(6) ... DEFAULT CURRENT_TIMESTAMP(6).

Нюанси ON UPDATE:

  • Спрацьовує, лише якщо значення якоїсь колонки справді змінилося. UPDATE posts SET title = title мітку не оновить.
  • Спрацьовує й на технічні зміни (лічильник переглядів, службовий прапорець) - «оновлено» перестає означати «змінено автором». Тоді краще керувати міткою в застосунку.

Значення за замовчуванням виразом (MySQL 8.0.13+) - вираз у дужках:

CREATE TABLE api_tokens (
    id BINARY(16) NOT NULL DEFAULT (UUID_TO_BIN(UUID(), 1)) PRIMARY KEY,
    expires_at DATETIME NOT NULL DEFAULT (CURRENT_TIMESTAMP + INTERVAL 30 DAY),
    settings JSON NOT NULL DEFAULT (JSON_OBJECT()),
    notes TEXT DEFAULT ('')
);

До 8.0.13 дозволялися лише літерали й CURRENT_TIMESTAMP; TEXT, BLOB і JSON не могли мати значення за замовчуванням узагалі.

Обмеження виразів: без підзапитів, змінних, збережених функцій і посилань на AUTO_INCREMENT-колонку.

Laravel і мітки часу: Eloquent сам заповнює created_at / updated_at у застосунку (з часовим поясом застосунку) і не покладається на ON UPDATE. Але масові оновлення через Query Builder (DB::table()->update()) Eloquent не бачить - там updated_at не зміниться, якщо в базі немає ON UPDATE. $table->timestamp('updated_at')->useCurrentOnUpdate() додає його в міграції.

Часові пояси: CURRENT_TIMESTAMP обчислюється в поясі сесії MySQL. Якщо він не збігається з поясом застосунку, мітки, поставлені базою й застосунком, розійдуться на кілька годин.

Докладніше в документації: Ініціалізація TIMESTAMP і DATETIME

1

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання