Темпоральные таблицы
Темпоральные таблицы (англ. temporal tables, также таблицы с поддержкой времени, системно-версионированные таблицы) — это механизм реляционных баз данных, предназначенный для автоматического хранения и предоставления доступа к историческим изменениям данных в строках таблицы. В отличие от обычных таблиц, которые хранят только текущее состояние данных, темпоральные таблицы позволяют выполнять запросы к данным на любой момент времени в прошлом, обеспечивая полную историю изменений каждой записи.
Основные принципы
Темпоральные таблицы реализуют концепцию управления данными с учётом времени (temporal data management). В основе лежит идея, что каждая строка данных имеет период актуальности, в течение которого она считается верной. Этот период задаётся двумя служебными столбцами, автоматически управляемыми системой управления базами данных (СУБД):
- Столбец начала периода (SysStartTime, ValidFrom): фиксирует момент времени, когда строка была вставлена или изменена и стала актуальной.
- Столбец окончания периода (SysEndTime, ValidTo): фиксирует момент времени, когда строка перестала быть актуальной (была обновлена или удалена).
Для обычной строки, которая является текущей, значение в столбце окончания периода часто устанавливается как максимально возможное (например, 9999-12-31 23:59:59.9999999). При обновлении или удалении строки СУБД автоматически копирует старую версию строки в отдельную историческую таблицу, устанавливая для неё дату окончания периода, равную времени выполнения операции.
Классификация
В теории баз данных и в стандарте SQL:2011 выделяют два основных типа темпоральных таблиц, которые могут применяться как по отдельности, так и совместно:
Системно-версионированные темпоральные таблицы (System-Versioned Temporal Tables, SVTT)
Управление временными метками полностью автоматизировано СУБД. Пользователь не может напрямую изменять служебные столбцы. Система сама фиксирует время вставки, обновления и удаления строк на основе системных часов сервера. Этот тип наиболее распространён в современных СУБД (Microsoft SQL Server 2016+, PostgreSQL с расширением pg_period, MariaDB 10.3+, Oracle 12c+). Он удобен для аудита, отладки и восстановления данных на определённый момент времени.
Таблицы с временем прикладного уровня (Application-Time Period Tables, Bitemporal Tables)
Управление временными метками осуществляется пользователем или приложением. В таких таблицах время актуальности строки задаётся бизнес-логикой и может не совпадать с реальным временем изменения записи в базе. Например, дата вступления в силу нового тарифа может быть задана на будущее, а дата его окончания — на прошлое. Этот тип требует явного указания периодов при вставке и обновлении данных. Часто используется в системах, где важна дата события, а не дата его регистрации в системе (например, в бухгалтерском учёте, кадровом делопроизводстве).
Битемпоральные таблицы (Bitemporal Tables)
Сочетают оба подхода: системное время (когда факт был зафиксирован в базе) и прикладное время (когда факт был актуален в реальности). Это позволяет, например, узнать, какой тариф действовал для клиента 1 января 2023 года, и при этом увидеть, какой была база данных на 5 января 2023 года (то есть до того, как была исправлена ошибка в дате тарифа). Битемпоральные таблицы реализованы в Oracle Database и частично в IBM Db2.
Устройство и реализация
Архитектурно темпоральная таблица состоит из двух физических таблиц:
- Текущая таблица (Current Table): хранит только актуальные (последние) версии строк. По структуре она идентична обычной таблице, но содержит два дополнительных служебных столбца для периода.
- Историческая таблица (History Table): хранит все предыдущие версии строк, которые были изменены или удалены. Структура исторической таблицы идентична структуре текущей, за исключением того, что в ней не может быть первичного ключа (так как одна и та же строка может иметь несколько исторических версий).
СУБД автоматически управляет перемещением данных между этими таблицами. При выполнении UPDATE или DELETE над строкой в текущей таблице, её старая версия копируется в историческую таблицу, а в текущей таблице остаётся новая версия (или строка удаляется). При INSERT новая строка сразу помещается в текущую таблицу.
Для выполнения запросов к историческим данным используется специальный синтаксис, чаще всего конструкция FOR SYSTEM_TIME AS OF <дата>. Этот синтаксис позволяет СУБД объединять данные из текущей и исторической таблиц, возвращая состояние данных на указанный момент времени.
Применение
Темпоральные таблицы находят широкое применение в различных областях:
- Аудит и комплаенс: Автоматическая фиксация всех изменений данных без необходимости писать триггеры или отдельные процедуры журналирования. Это соответствует требованиям многих регуляторов (например, в финансовом секторе и здравоохранении).
- Анализ данных и отчётность: Возможность строить отчёты, показывающие состояние данных на любой момент времени (например, «сколько сотрудников работало в компании на 1 января каждого года»).
- Восстановление данных после ошибок: Быстрое восстановление случайно изменённых или удалённых записей без использования резервных копий. Можно выполнить запрос к данным на момент до ошибки и вставить их обратно.
- Управление версиями справочников: Хранение истории изменений справочных данных (например, номенклатуры товаров, курсов валют, тарифов).
- Медленно меняющиеся измерения (SCD) в хранилищах данных: Тип 2 (SCD Type 2) может быть реализован с помощью темпоральных таблиц, что упрощает ETL-процессы.
Преимущества и недостатки
Преимущества
- Автоматизация: СУБД сама управляет историей, что снижает вероятность ошибок и упрощает код приложений.
- Прозрачность: Для обычных запросов (
SELECT,INSERT,UPDATE,DELETE) темпоральная таблица ведёт себя как обычная. Исторические данные не видны, пока не используется специальный синтаксис. - Производительность: Исторические данные хранятся отдельно, что не замедляет запросы к текущим данным. Для исторических запросов могут быть созданы отдельные индексы.
- Целостность: Система гарантирует, что временные метки корректны и не могут быть изменены пользователем (для системно-версионированных таблиц).
Недостатки
- Рост объёма данных: Историческая таблица может быстро расти, особенно при частых обновлениях. Требуется планирование управления ёмкостью хранения и политики архивации.
- Ограничения DDL: Некоторые операции изменения схемы таблицы (например, изменение типа данных столбца) могут быть затруднены или требовать временного отключения версионирования.
- Сложность битемпоральных таблиц: Реализация и понимание битемпоральных таблиц требуют более высокой квалификации разработчика.
- Зависимость от СУБД: Реализация темпоральных таблиц может отличаться в разных СУБД, что усложняет миграцию.
Примеры реализации в СУБД
- Microsoft SQL Server (2016+): Реализованы системно-версионированные темпоральные таблицы. Синтаксис:
CREATE TABLE ... WITH (SYSTEM_VERSIONING = ON). - PostgreSQL: Стандартной реализации нет, но существует расширение
pg_period(от 2ndQuadrant) иtemporal_tables. В PostgreSQL 12+ появилась поддержка генерируемых столбцов, что упрощает создание подобных решений. - MariaDB (10.3+): Реализованы системно-версионированные темпоральные таблицы. Синтаксис:
CREATE TABLE ... WITH SYSTEM VERSIONING. - Oracle (12c+): Поддерживаются системно-версионированные и битемпоральные таблицы через механизм Flashback Data Archive (Oracle Total Recall) и использование периодов времени.
- IBM Db2: Поддерживает битемпоральные таблицы с использованием бизнес-времени и системного времени.
Источники
- Стандарт SQL:2011 (ISO/IEC 9075:2011), раздел по темпоральным таблицам.
- Документация Microsoft SQL Server: «Temporal Tables».
- Документация MariaDB: «System-Versioned Tables».
- Документация Oracle Database: «Temporal Validity Support» и «Flashback Data Archive».
- Книга: C. J. Date, Hugh Darwen, Nikos Lorentzos. «Temporal Data and the Relational Model».
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →