Обновление записи MySQL без изменения timestamp: руководство

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Если желаете обновить определенное поле, не затрагивая при этом временную метку, важно явно указать ее текущее значение. Для этого можете воспользоваться приведенным ниже примером:

SQL
Скопировать код
UPDATE ваша_таблица
SET столбец1 = 'новое_значение',
временная_метка = временная_метка
WHERE id = целевой_идентификатор_строки;

Такой подход позволяет сохранить исходное значение временной метки в процессе обновления.

Кинга Идем в IT: пошаговый план для смены профессии

Обновление с сохранением временной метки

Если вам необходимо обновить данные в таблице, при этом сохранить временную метку, вам пригодится следующая информация.

Установите стандартные ограничения

Если временная метка в вашей MySQL базе данных автоматически обновляется, вам нужно установить для нее стандартное ограничение и исключить триггер ON UPDATE.

SQL
Скопировать код
ALTER TABLE ваша_таблица
CHANGE временная_метка временная_метка DATETIME DEFAULT CURRENT_TIMESTAMP;

Обновляйте без упоминания временной метки

Для сохранения исходного значения временного метки достаточно не включать ее в список обновляемых полей.

SQL
Скопировать код
UPDATE ваша_таблица
SET столбец1 = 'новое_значение'
WHERE id = целевой_идентификатор_строки;

При необходимости укажите временную метку вручную

Если вам нужно указать значение временной метки в запросе, присвойте ей текущее значение так:

SQL
Скопировать код
UPDATE ваша_таблица
SET столбец1 = 'новое_значение',
временная_метка = (SELECT временная_метка FROM ваша_таблица WHERE id = целевой_идентификатор_строки)
WHERE id = целевой_идентификатор_строки;

Визуализация

Допустим, мы хотим обновить поле email в профиле пользователя, однако не хотим менять дату его создания.

Markdown
Скопировать код
Текущий профиль: 👤 
UserID: 42 | CreationDate: "2020-01-01"

Обновляем поле email, при этом гарантируем, что дата создания профиля не изменится:

Markdown
Скопировать код
Командования для обновления:
UPDATE Профили SET Email = 'new.email@example.com' WHERE UserID = 42;

Не включая CreationDate в список обновляемых полей, мы позволяем временной метке остаться без изменений.

Особые случаи: Регулирование временной метки

Иногда стандартные методы недостаточны для управления временной меткой. Рассмотрим, как решить особо сложные задачи.

Регулирование при частых обновлениях

Если временные метки в вашей таблице обновляются с использованием триггеров, вам нужно их временно отключить.

SQL
Скопировать код
-- Отключаем триггер
ALTER TABLE ваша_таблица DISABLE TRIGGER ваш_триггер;

-- Выполняем обновление
UPDATE ваша_таблица
SET столбец1 = 'новое_значение'
WHERE id = целевой_идентификатор_строки;

-- Включаем триггер обратно
ALTER TABLE ваша_таблица ENABLE TRIGGER ваш_триггер;

Отключение автообновлений в ORM

При использовании ORM-фреймворков может происходить автоматическое обновление временных меток. Однако это можно обойти:

Python
Скопировать код
# Пример использования Python с SQLAlchemy
запись = сессия.query(ВашаМодель).get(целевой_идентификатор_строки)
запись.столбец1 = 'новое_значение'
# Производим манипуляции с временной меткой
сессия.expire(запись, ['временная_метка'])
сессия.refresh(запись)
# Фиксируем изменения
сессия.commit()

Ведение истории изменений

Если точность временных меток оказывается критически важной, то может быть полезно создать отдельную таблицу для целей аудита.

SQL
Скопировать код
CREATE TABLE ваша_таблица_аудит (
    audit_id INT AUTO_INCREMENT PRIMARY KEY,
    ваша_таблица_id INT,
    измененный_столбец varchar(255),
    старое_значение varchar(255),
    новое_значение varchar(255),
    изменено TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Так, каждое обновление фиксируется в отдельной таблице, не затрагивая временную метку основной таблицы:

SQL
Скопировать код
START TRANSACTION;

UPDATE ваша_таблица
SET столбец1 = 'новое_значение'
WHERE id = целевой_идентификатор_строки;

INSERT INTO ваша_таблица_аудит (ваша_таблица_id, измененный_столбец, старое_значение, новое_значение)
VALUES (целевой_идентификатор_строки, 'столбец1', 'старое_значение', 'новое_значение');

COMMIT;

Полезные материалы

  1. Руководство по MySQL 8.0: Автоматическая инициализация и обновление TIMESTAMP и DATETIME
  2. SQL Server | Microsoft Learn: Установление значений по умолчанию для столбцов
  3. Документация PostgreSQL о функциях триггеров
  4. Oracle SQL Reference: Справочник форматирования моделей
  5. Zlib: Кросс-платформенный упрощенный оберточный класс для C++ на Stack Overflow
  6. Управление часовыми поясами в MySQL: Установка часового пояса на UTC – обсуждение на Stack Overflow