Обновление записи MySQL без изменения timestamp: руководство
Быстрый ответ
Если желаете обновить определенное поле, не затрагивая при этом временную метку, важно явно указать ее текущее значение. Для этого можете воспользоваться приведенным ниже примером:
UPDATE ваша_таблица
SET столбец1 = 'новое_значение',
временная_метка = временная_метка
WHERE id = целевой_идентификатор_строки;
Такой подход позволяет сохранить исходное значение временной метки в процессе обновления.
Обновление с сохранением временной метки
Если вам необходимо обновить данные в таблице, при этом сохранить временную метку, вам пригодится следующая информация.
Установите стандартные ограничения
Если временная метка в вашей MySQL базе данных автоматически обновляется, вам нужно установить для нее стандартное ограничение и исключить триггер ON UPDATE
.
ALTER TABLE ваша_таблица
CHANGE временная_метка временная_метка DATETIME DEFAULT CURRENT_TIMESTAMP;
Обновляйте без упоминания временной метки
Для сохранения исходного значения временного метки достаточно не включать ее в список обновляемых полей.
UPDATE ваша_таблица
SET столбец1 = 'новое_значение'
WHERE id = целевой_идентификатор_строки;
При необходимости укажите временную метку вручную
Если вам нужно указать значение временной метки в запросе, присвойте ей текущее значение так:
UPDATE ваша_таблица
SET столбец1 = 'новое_значение',
временная_метка = (SELECT временная_метка FROM ваша_таблица WHERE id = целевой_идентификатор_строки)
WHERE id = целевой_идентификатор_строки;
Визуализация
Допустим, мы хотим обновить поле email
в профиле пользователя, однако не хотим менять дату его создания.
Текущий профиль: 👤
UserID: 42 | CreationDate: "2020-01-01"
Обновляем поле email
, при этом гарантируем, что дата создания профиля не изменится:
Командования для обновления:
UPDATE Профили SET Email = 'new.email@example.com' WHERE UserID = 42;
Не включая CreationDate
в список обновляемых полей, мы позволяем временной метке остаться без изменений.
Особые случаи: Регулирование временной метки
Иногда стандартные методы недостаточны для управления временной меткой. Рассмотрим, как решить особо сложные задачи.
Регулирование при частых обновлениях
Если временные метки в вашей таблице обновляются с использованием триггеров, вам нужно их временно отключить.
-- Отключаем триггер
ALTER TABLE ваша_таблица DISABLE TRIGGER ваш_триггер;
-- Выполняем обновление
UPDATE ваша_таблица
SET столбец1 = 'новое_значение'
WHERE id = целевой_идентификатор_строки;
-- Включаем триггер обратно
ALTER TABLE ваша_таблица ENABLE TRIGGER ваш_триггер;
Отключение автообновлений в ORM
При использовании ORM-фреймворков может происходить автоматическое обновление временных меток. Однако это можно обойти:
# Пример использования Python с SQLAlchemy
запись = сессия.query(ВашаМодель).get(целевой_идентификатор_строки)
запись.столбец1 = 'новое_значение'
# Производим манипуляции с временной меткой
сессия.expire(запись, ['временная_метка'])
сессия.refresh(запись)
# Фиксируем изменения
сессия.commit()
Ведение истории изменений
Если точность временных меток оказывается критически важной, то может быть полезно создать отдельную таблицу для целей аудита.
CREATE TABLE ваша_таблица_аудит (
audit_id INT AUTO_INCREMENT PRIMARY KEY,
ваша_таблица_id INT,
измененный_столбец varchar(255),
старое_значение varchar(255),
новое_значение varchar(255),
изменено TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Так, каждое обновление фиксируется в отдельной таблице, не затрагивая временную метку основной таблицы:
START TRANSACTION;
UPDATE ваша_таблица
SET столбец1 = 'новое_значение'
WHERE id = целевой_идентификатор_строки;
INSERT INTO ваша_таблица_аудит (ваша_таблица_id, измененный_столбец, старое_значение, новое_значение)
VALUES (целевой_идентификатор_строки, 'столбец1', 'старое_значение', 'новое_значение');
COMMIT;
Полезные материалы
- Руководство по MySQL 8.0: Автоматическая инициализация и обновление TIMESTAMP и DATETIME
- SQL Server | Microsoft Learn: Установление значений по умолчанию для столбцов
- Документация PostgreSQL о функциях триггеров
- Oracle SQL Reference: Справочник форматирования моделей
- Zlib: Кросс-платформенный упрощенный оберточный класс для C++ на Stack Overflow
- Управление часовыми поясами в MySQL: Установка часового пояса на UTC – обсуждение на Stack Overflow