Что такое timestamp в sql
Перейти к содержимому

Что такое timestamp в sql

  • автор:

Разница между типами данных Timestamp и Datetime в SQL

В SQL Server тип данных DATETIME представляет собой временную отметку, включающую дату и время в формате ГГГГ-ММ-ДД ЧЧ:ММ:СС. Он охватывает период с 1753-01-01 по 9999-12-31 и обеспечивает точность до 3,33 миллисекунд.

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

Пример использования DATETIME :

Скопировать код

-- Исследуем прошлое с помощью SQL �� SELECT CAST('2023-04-01T12:34:56.789' AS DATETIME) AS ExampleDateTime;

Пример работы с ROWVERSION :

Скопировать код

-- И SQL может быть надежным индикатором �� ALTER TABLE MyTable ADD RecordVersion ROWVERSION;

Заметьте, что основная функция TIMESTAMP или ROWVERSION — это поддержание целостности данных путем автоматической генерации уникальных значений. Современные практики предпочитают использовать термин ROWVERSION , поскольку TIMESTAMP постепенно теряет свою актуальность.

Внутреннее устройство Datetime

Функция DATETIME позволяет регистрировать точные даты и время событий. Значение устанавливается пользователем при добавлении или обновлении данных. Это удобно при необходимости фиксации времени создания или последнего изменения записи.

Timestamp или Rowversion: ваш уникальный идентификатор данных!

ROWVERSION (бывший TIMESTAMP ) автоматически назначает каждой измененной или добавленной записи уникальный двоичный номер. SQL Server гарантирует уникальность номеров на уровне всей базы данных с помощью специализированного счетчика.

Управление параллельностью с помощью Timestamp или Rowversion!

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

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

Представьте DATETIME как запись в дневнике (��), точно фиксирующую события. А TIMESTAMP или ROWVERSION — это уникальный серийный номер (��️), присваиваемый каждой отправленной открытке.

Запись в дневнике (��): «28 марта, 10:30 утра – Утренний спуск по лестнице оказался неудачным.» Серийный номер открытки (��️): » ID Открытки № 123456 – Отправлена в 10:30 утра, 28 марта – Понадобился лед.»

DATETIME = Временная запись в вашем дневнике (��) ��: Бережно фиксирует эмоции и впечатления, важные именно для вас.

TIMESTAMP = Уникальный ID открытки (��️) ��️: Дает возможность определить порядок получения и происхождение открыток.

Практический выбор между Datetime и Timestamp/Rowversion

Когда желательно использовать DATETIME :

  • Для отметки времени значимых событий или планирования будущих мероприятий
  • Ведение истории изменений данных
  • В любом контексте, где важно слежение за временем для принятия решений

Сценарии использования TIMESTAMP / ROWVERSION :

  • Отслеживание изменений записей для точной синхронизации данных
  • Создание механизмов разрешения конфликтов при обновлении данных
  • Ведение истории версий каждой записи в базе данных

Рекомендации и распространенные ошибки при работе с Datetime и Timestamp

Будьте внимательны к производительности

ROWVERSION может показаться идеальным решением для любого SQL-проекта, однако избыточность операций обновления может отрицательно повлиять на производительность сервера.

Лучшие практики

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

Будьте осторожны

Не пытайтесь воспринимать ROWVERSION как время; это не время, а уникальное двоичное значение. Не стоит путать ROWVERSION с DATETIME , поскольку они служат различным целям.

Желаю удачи в разработке и кодировании!��‍��

Что такое timestamp в sql

Из всех типов данных в SQL временны́е данные являются наиболее сложными ��. Сложность возникает по нескольким причинам, и вот некоторые из них:

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

Временные данные можно получить одним из следующих способов:

  • скопировать данные из существующего столбца с времéнным типом данных
  • задать дату и время через строковое представление
  • получить временны́е данные путём вызова встроенных функций, возвращающих временной тип данных

Для задания даты и времени используются следующие форматы:

Тип Формат по умолчанию
DATE YYYY-MM-DD
DATETIME YYYY-MM-DD hh:mm:ss
TIMESTAMP YYYY-MM-DD hh:mm:ss
TIME hhh:mm:sss
YEAR YYYY — полный формат
YY или Y — сокращённый формат, который возвращает год в пределах 2000-2069 для значений 0-69 и год в пределах 1970-1999 для значений 70-99

Причём, при указании даты допускается использовать любой знак пунктуации в качестве разделительного между частями разделов даты или времени. Также возможно задавать дату вообще без разделительного знака, слитно.

Примеры валидного задания временных значений через строковое представление:

MySQL
SELECT CAST("2022-06-16 16:37:23" AS DATETIME) AS datetime_1, CAST("2014/02/22 16*37*22" AS DATETIME) AS datetime_2, CAST("20220616163723" AS DATETIME) AS datetime_3, CAST("2021-02-12" AS DATE) AS date_1, CAST("160:23:13" AS TIME) AS time_1, CAST("89" AS YEAR) AS year 
datetime_1 datetime_2 datetime_3 date_1 time_1 year
2022-06-16T16:37:23.000Z 2014-02-22T16:37:22.000Z 2022-06-16T16:37:23.000Z 2021-02-12T00:00:00.000Z 160:23:13 1989

В запросе выше для принудительного преобразования строки в дату и время была использована функция CAST . Она необходима, если сервер не ожидает временного значения и, соответственно, автоматически не преобразует строку к нужному типу. С преобразованием типов мы более подробно познакомимся в статье «Функции преобразования типов, CAST».

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

MySQL
SELECT STR_TO_DATE('November 13, 1998', '%M %d, %Y') AS date; 
date
1998-11-13T00:00:00.000Z

Более подробное описание функции STR_TO_DATE и её аргументов можно посмотреть в справочнике.

Для генерации же текущей даты или времени нет необходимости создавать строку для последующего её преобразования в дату, потому что есть встроенные функции для получения данных значений: CURDATE , CURTIME и NOW .

MySQL
SELECT CURDATE(), CURTIME(), NOW(); 

Иногда необходимо получить не всю дату, а только её конкретную часть, например, месяц или год.

Для этого в SQL есть следующие функции:

Функция Описание
YEAR Возвращает год для указанной даты
MONTH Возвращает числовое значение месяца года (от 1 до 12) даты
DAY Возвращает порядковый номер дня в месяце (от 1 до 31)
HOUR Возвращает значение часа (от 0 до 23) для времени
MINUTE Возвращает значение минут (от 0 до 59) для времени

В MySQL есть очень похожие друг на друга типы данных: DATETIME и TIMESTAMP . Они оба направлены на хранение даты и времени, но имеют ряд отличий, определяющих их целевое использование.

Критерий DATETIME TIMESTAMP
Диапазон от 1000-01-01 00:00:00
до 9999-12-31 23:59:59
от 1970-01-01 00:00:00
до 2038-01-19 03:14:07
Часовой пояс Не учитывается
Отображается в таком виде, в котором дата была установлена
Учитывается
При выборках отображается с учётом текущего часового пояса сервера БД

Так как люди во всем мире хотят, чтобы полдень примерно соответствовал максимальному подъёму Солнца, то никогда не было задачи использовать универсальное время и мир был разделён на 24 часовых пояса.

В качестве точки отсчёта времени используется UTC (Coordinated Universal Time). Все остальные часовые пояса можно описать количеством часов сдвига от UTC. Для примера, часовой пояс Москвы может быть описан как UTC+3.

Часовой пояс является одной из настроек сервера баз данных и может задаваться:

  • глобально
  • для текущего пользователя
  • для текущей пользовательской сессии
MySQL
SET GLOBAL time_zone = '+03:00'; // глобально SET time_zone = '+03:00'; // для текущего пользователя SET @@session.time_zone = '+03:00'; // для текущей пользовательской сессии 

Соответственно, при изменении временной зоны все значения с типом TIMESTAMP будут выводиться с учётом текущей активной временной зоны.

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

При постановке задачи найти возраст человека по дате его рождения часто возникает соблазн �� вычислить разницу текущего года и года рождения человека:

MySQL
SELECT YEAR(NOW()) - YEAR('2003-07-03 14:10:26'); 

Проблема такого подхода в том, что он не учитывает был ли день рождения у данного человека в этом году или ещё нет. То есть, если на момент запроса уже наступило 3-е июля (07-03), то человек отпраздновал свой день рождения и ему уже 20 лет, иначе ему по-прежнему 19 года. Разница функций YEAR тут будет бесполезна — в обоих случаях она даст 20 лет.

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

MySQL
SELECT FLOOR(DATEDIFF(NOW(), '2003-07-03 14:10:26') / 365); 

И это решение будет гораздо точнее предыдущего. Но оно не будет абсолютно точным из-за наличия високосных годов, когда в году 366 дней. Хотя погрешность в вычислении возраста для 1 человека из-за наличия високосного года достаточно низкая, в вычислениях на определение, скажем, среднего возраста среди определённого списка людей, погрешность может накапливаться и исказить реальные значения.

И как же тогда корректно определять возраст? Для этого есть готовая встроенная функция — TIMESTAMPDIFF , которая первым аргументом принимает единицу измерения, в которой нужно вернуть разницу между двумя временными значениями.

MySQL
TIMESTAMPDIFF(YEAR, '2003-07-03 14:10:26', NOW()); 

CURRENT_TIMESTAMP (Transact-SQL)

Эта функция возвращает текущую системную метку времени базы данных в виде значения datetime без смещения часового пояса базы данных. CURRENT_TIMESTAMP получает это значение от операционной системы компьютера, на котором выполняется экземпляр SQL Server.

SYSDATETIME и SYSUTCDATE имеют большую точность в долях секунды, чем GETDATE и GETUTCDATE . Функция SYSDATETIMEOFFSET включает смещение часового пояса, заданное в системе. Функции SYSDATETIME , SYSUTCDATETIME и SYSDATETIMEOFFSET могут быть присвоены переменным любого типа даты и времени.

Эта функция ANSI SQL эквивалентна функции GETDATE.

Обзор всех типов данных и функций даты и времени в языке Transact-SQL см. в статье Типы данных и функции даты и времени.

Синтаксис

CURRENT_TIMESTAMP 

Сведения о синтаксисе Transact-SQL для SQL Server 2014 (12.x) и более ранних версиях см . в документации по предыдущим версиям.

Аргументы

Эта функция не имеет аргументов.

Тип возвращаемых данных

datetime

Замечания

Функция CURRENT_TIMESTAMP может использоваться в инструкциях Transact-SQL везде, где допустимо использование выражения datetime.

CURRENT_TIMESTAMP является недетерминированной функцией. Невозможно проиндексировать представления и выражения, ссылающиеся на этот столбец.

Примеры

В этих примерах используются шесть системных функций SQL Server, возвращающих текущие значения даты и времени, для возврата даты, времени или обоих. Значения возвращаются последовательно, поэтому могут различаться на доли секунды. Обратите внимание на то, что возвращаемые значения будут соответствовать фактическим дню и времени выполнения.

А. Получение текущих системных значений даты и времени

SELECT SYSDATETIME() ,SYSDATETIMEOFFSET() ,SYSUTCDATETIME() ,CURRENT_TIMESTAMP ,GETDATE() ,GETUTCDATE(); /* Returned: SYSDATETIME() 2007-04-30 13:10:02.0474381 SYSDATETIMEOFFSET()2007-04-30 13:10:02.0474381 -07:00 SYSUTCDATETIME() 2007-04-30 20:10:02.0474381 CURRENT_TIMESTAMP 2007-04-30 13:10:02.047 GETDATE() 2007-04-30 13:10:02.047 GETUTCDATE() 2007-04-30 20:10:02.047 */ 

B. Получение текущей системной даты

SELECT CONVERT (DATE, SYSDATETIME()) ,CONVERT (DATE, SYSDATETIMEOFFSET()) ,CONVERT (DATE, SYSUTCDATETIME()) ,CONVERT (DATE, CURRENT_TIMESTAMP) ,CONVERT (DATE, GETDATE()) ,CONVERT (DATE, GETUTCDATE()); /* Returned SYSDATETIME() 2007-05-03 SYSDATETIMEOFFSET()2007-05-03 SYSUTCDATETIME() 2007-05-04 CURRENT_TIMESTAMP 2007-05-03 GETDATE() 2007-05-03 GETUTCDATE() 2007-05-04 */ 

C. Получение текущего системного времени

SELECT CONVERT (TIME, SYSDATETIME()) ,CONVERT (TIME, SYSDATETIMEOFFSET()) ,CONVERT (TIME, SYSUTCDATETIME()) ,CONVERT (TIME, CURRENT_TIMESTAMP) ,CONVERT (TIME, GETDATE()) ,CONVERT (TIME, GETUTCDATE()); /* Returned SYSDATETIME() 13:18:45.3490361 SYSDATETIMEOFFSET()13:18:45.3490361 SYSUTCDATETIME() 20:18:45.3490361 CURRENT_TIMESTAMP 13:18:45.3470000 GETDATE() 13:18:45.3470000 GETUTCDATE() 20:18:45.3470000 */ 

Примеры: Azure Synapse Analytics и система платформы аналитики (PDW)

SELECT CURRENT_TIMESTAMP; 

SQL - Урок 13. Функции даты и времени

Функции CURDATE() и NOW() удобно использовать для добавления в базу данных записей, использующих текущее время. В нашем магазине все поставки и продажи используют текущее время. Поэтому для добавления записей о поставах, и продажах удобно использовать функцию CURDATE(). Например, пусть в наш магазин пришел товар, давайте добавим информацию об этом в таблицу Поставка (incoming):

INSERT INTO incoming (id_vendor, date_incoming) VALUES ('2', curdate());
SELECT id_vendor, date_incoming FROM incoming;

Предположим, мы ошиблись при вводе даты для первого поставщика, давайте уменьшим его дату на одни сутки:

SELECT id_vendor, ADDDATE(date_incoming, INTERVAL -1 DAY) FROM incoming WHERE id_vendor=1;

В качестве значения value могут выступать не только дни, но и недели (WEEK), месяцы (MONTH), кварталы (QUARTER) и годы (YEAR). Давайте для пример уменьшим дату поставки для второго поставщика на 1 неделю:

SELECT id_vendor, ADDDATE(date_incoming, INTERVAL -1 WEEK) FROM incoming WHERE id_vendor=2;

В нашей таблице Поставки (incoming) мы использовали для столбца Дата поставки (date_incoming) тип date. Как вы помните из урока 2, этот тип данных предназначен для хранения только даты. А вот если бы мы использовали тип datatime, то у нас отображалась бы не только дата, но и время. Тогда мы могли бы использовать функцию ADDDATE и для времени. В качестве значения value в этом случае могут выступать секунды (SECOND), минуты (MINUTE), часы (HOUR) и их комбинации:
минуты и секунды (MINUTE_SECOND),
часы, минуты и секунды (HOUR_SECOND),
часы и минуты (HOUR_MINUTE),
дни, часы, минуты и секунды (DAY_SECOND),
дни, часы и минуты (DAY_MINUTE),
дни и часы (DAY_HOUR),
года и месяцы (YEAR_MONTH).
Например, давайте к дате 15 апреля 2011 года две минуты первого прибавим 2 часа 45 минут:

SELECT ADDDATE('2011-04-15 00:02:00', INTERVAL '02:45' HOUR_MINUTE);
SELECT SUBDATE('2011-04-15 00:02:00', INTERVAL '23:53' HOUR_MINUTE);
SELECT PERIOD_ADD(201102, 2);

FRAC_SECOND - микросекунды
SECOND - секунды
MINUTE - минуты
HOUR - часы
DAY - дни
WEEK - недели
MONTH - месяцы
QUARTER - кварталы
YEAR - годы

SELECT TIMESTAMPADD(DAY, 2, '2011-04-02');
SELECT TIMEDIFF('2011-04-17 23:50:00', '2011_04-16 14:50:00');
SELECT date_incoming, CURDATE(), DATEDIFF(CURDATE(), date_incoming) FROM incoming WHERE id_vendor=1;
SELECT PERIOD_DIFF(201108, 201001);

FRAC_SECOND - микросекунды
SECOND - секунды
MINUTE - минуты
HOUR - часы
DAY - дни
WEEK - недели
MONTH - месяцы
QUARTER - кварталы
YEAR - годы

SELECT TIMESTAMPDIFF(DAY, '2011-04-02', '2011-04-17') AS days, TIMESTAMPDIFF(HOUR, '2011-04-16 20:14:00', '2011-04-17 23:58:20') AS houres;

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *