SMALLDATETIME
SMALLDATETIME — это тип данных в системах управления базами данных (СУБД), предназначенный для хранения даты и времени с точностью до минуты. Относится к категории типов для работы с календарными данными и используется в тех случаях, когда не требуется высокая точность до секунд или долей секунды, что позволяет экономить дисковое пространство и ускорять обработку запросов. Наиболее широкое распространение тип получил в СУБД Microsoft SQL Server и Sybase Adaptive Server Enterprise.
История
Тип данных SMALLDATETIME был введён компанией Sybase в ранних версиях своей СУБД для обеспечения более компактного хранения дат по сравнению с типом DATETIME. Впоследствии, при разработке Microsoft SQL Server (на основе кодовой базы Sybase), этот тип был унаследован и стал стандартным элементом диалекта Transact-SQL (T-SQL). В первых версиях SQL Server (начиная с 4.2 и 6.0) SMALLDATETIME уже присутствовал как один из основных типов для работы с временными метками. С выходом SQL Server 2008 в состав продукта были добавлены более современные типы DATE, TIME, DATETIME2 и DATETIMEOFFSET, однако SMALLDATETIME сохранился в системе для обратной совместимости и продолжает использоваться в унаследованных проектах и при необходимости минимального потребления ресурсов.
Характеристики
Диапазон значений
SMALLDATETIME охватывает даты с 1 января 1900 года по 6 июня 2079 года. Выход за пределы этого диапазона при попытке вставки или обновления данных приводит к ошибке переполнения (overflow error). Данный диапазон значительно уже, чем у типа DATETIME (1753–9999 гг.) или DATETIME2 (0001–9999 гг.), что ограничивает применимость SMALLDATETIME в исторических или долгосрочных архивах.
Точность
Точность SMALLDATETIME составляет одну минуту. Значения секунд и миллисекунд при вводе округляются по правилам математического округления:
- Если значение секунд равно 29,998 секунды или менее, оно округляется вниз до ближайшей целой минуты (секунды и миллисекунды отбрасываются).
- Если значение секунд равно 29,999 секунды или более, оно округляется вверх до следующей минуты.
Например, значение 2024-03-15 14:30:29.998 будет сохранено как 2024-03-15 14:30:00, а 2024-03-15 14:30:29.999 — как 2024-03-15 14:31:00.
Размер хранения
SMALLDATETIME занимает 4 байта в памяти и на диске. Для сравнения: тип DATETIME требует 8 байт, а DATETIME2 с максимальной точностью — до 8 байт. Экономия в 4 байта на каждое значение может быть существенной при работе с таблицами, содержащими миллионы строк.
Внутреннее представление
Внутренне значение SMALLDATETIME хранится в виде двух целых чисел по 2 байта каждое:
- Первое число (2 байта) — количество дней, прошедших с базовой даты 1 января 1900 года.
- Второе число (2 байта) — количество минут, прошедших с полуночи (00:00:00).
Таким образом, дата и время не хранятся в виде строки или числа с плавающей точкой, что обеспечивает быстрые арифметические операции и сравнения.
Синтаксис и использование
Объявление переменной или столбца
В Transact-SQL объявление переменной типа SMALLDATETIME выглядит следующим образом:
``sql DECLARE @MyDate SMALLDATETIME; ``
При создании таблицы:
``sql CREATE TABLE Orders ( OrderID INT PRIMARY KEY, OrderDate SMALLDATETIME ); ``
Вставка значений
Значения могут быть вставлены в виде строковых литералов в формате, зависящем от региональных настроек сервера. Наиболее безопасным и универсальным является формат ГГГГ-ММ-ДДTЧЧ:ММ:СС (ISO 8601) или ГГГГММДД ЧЧ:ММ:СС (независимый от языка):
``sql INSERT INTO Orders (OrderID, OrderDate) VALUES (1, '2024-03-15T14:30:00'); INSERT INTO Orders (OrderID, OrderDate) VALUES (2, '20240315 14:30:00'); ``
Функции для работы с SMALLDATETIME
К типу SMALLDATETIME применимы все стандартные функции Transact-SQL для работы с датой и временем:
GETDATE()— возвращает текущие дату и время в формате DATETIME (может быть неявно преобразован в SMALLDATETIME с потерей секунд).SYSDATETIME()— возвращает более точное значение (DATETIME2), но при присвоении переменной SMALLDATETIME произойдёт округление.DATEADD()— прибавление/вычитание интервала времени.DATEDIFF()— вычисление разницы между двумя датами.YEAR(),MONTH(),DAY()— извлечение компонентов даты.DATEPART()— извлечение любой части даты (год, месяц, день, час, минута).
Пример:
``sql DECLARE @StartDate SMALLDATETIME = '2024-01-01 00:00:00'; SELECT DATEADD(MONTH, 3, @StartDate) AS ThreeMonthsLater; -- Результат: 2024-04-01 00:00:00 ``
Сравнение с другими типами данных
| Тип данных | Размер (байт) | Диапазон дат | Точность |
|---|---|---|---|
| SMALLDATETIME | 4 | 1900-01-01 — 2079-06-06 | 1 минута |
| DATETIME | 8 | 1753-01-01 — 9999-12-31 | 3,33 миллисекунды |
| DATETIME2 | 6–8 | 0001-01-01 — 9999-12-31 | 100 наносекунд |
| DATE | 3 | 0001-01-01 — 9999-12-31 | 1 день |
| TIME | 3–5 | не применимо | 100 наносекунд |
Основные преимущества SMALLDATETIME перед другими типами:
- Экономия места — вдвое меньше, чем DATETIME.
- Скорость обработки — меньший объём данных ускоряет сканирование таблиц и операции сортировки.
- Простота — округление до минут избавляет от необходимости учитывать доли секунд.
Недостатки:
- Ограниченный диапазон — невозможность хранения дат до 1900 года и после 2079 года.
- Низкая точность — потеря информации о секундах и миллисекундах.
- Устаревание — в современных проектах рекомендуется использовать DATETIME2 или DATE+TIME.
Применение
SMALLDATETIME традиционно применяется в следующих сценариях:
- Учёт заказов и транзакций — для фиксации момента оформления заказа, когда точность до минуты является достаточной.
- Логирование событий — в системах, где не требуется хронометраж с точностью до секунды (например, время входа пользователя в систему).
- Биллинговые системы — для хранения дат начала и окончания тарифных периодов.
- Унаследованные базы данных — поддержка совместимости со старыми приложениями, написанными для SQL Server 2000/2005.
- Хранилища данных с высокой кардинальностью — в таблицах фактов с миллиардами строк, где каждый байт на счету.
Ограничения и особенности
- При преобразовании из строки в SMALLDATETIME сервер пытается интерпретировать строку согласно текущему языку сеанса (SET LANGUAGE). Это может привести к ошибкам, если строка записана в неожиданном формате.
- Неявное преобразование из типов с более высокой точностью (DATETIME, DATETIME2) в SMALLDATETIME всегда выполняется с округлением, что может стать источником неявных ошибок в логике приложений.
- В SQL Server тип SMALLDATETIME не поддерживает хранение временной зоны. Для работы с часовыми поясами необходимо использовать DATETIMEOFFSET.
- При использовании в условиях JOIN или WHERE сравнение значений SMALLDATETIME с литералами типа
'2024-03-15'(без времени) может привести к неожиданным результатам, так как литерал без времени интерпретируется как полночь (00:00:00), и строки с ненулевым временем не будут включены в результат.
Интересные факты
- В документации Microsoft SQL Server тип SMALLDATETIME иногда называют «дискретным» из-за того, что он может принимать только значения, кратные одной минуте.
- Несмотря на появление более современных типов, SMALLDATETIME до сих пор используется в шаблонах автоматически генерируемого кода в некоторых версиях Microsoft Dynamics CRM и SharePoint.
- В Sybase ASE тип SMALLDATETIME имеет идентичные характеристики, но может называться «SMALLDATETIME» или «SMALL DATETIME» в зависимости от версии документации.
- В некоторых СУБД, не входящих в семейство T-SQL (например, MySQL, PostgreSQL), аналогом SMALLDATETIME по точности и размеру можно считать тип TIMESTAMP (4 байта) в MySQL, однако его диапазон дат и правила округления отличаются.
Источники
- Microsoft Docs: «smalldatetime (Transact-SQL)» — официальная документация SQL Server.
- Microsoft Docs: «Date and Time Data Types and Functions (Transact-SQL)».
- Sybase Infocenter: «Adaptive Server Enterprise Reference Manual» — описание типов данных.
- Книга: Itzik Ben-Gan, «T-SQL Fundamentals» (Microsoft Press, 2016).
- Статья: «Comparing DATE and DATETIME Data Types in SQL Server» — SQL Shack.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →