Автоматичні мітки часу - для 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