Битемпоральные таблицы¶
Битемпоральная таблица — это таблица реляционной базы данных, которая поддерживает два независимых измерения времени: время действия (valid time) и время транзакции (transaction time). Такая таблица позволяет хранить и запрашивать историю изменений данных с учётом как того, когда факт был верен в реальности, так и того, когда эта информация была зафиксирована в базе данных. Битемпоральность является расширением концепции темпоральных баз данных, определённых в стандарте SQL:2011.
¶История
Концепция темпоральных баз данных возникла в 1970-х годах как ответ на потребность в хранении исторических данных. Первоначально исследователи выделяли два основных типа времени: время действия (valid time), отражающее период, когда факт был истинным в предметной области, и время транзакции (transaction time), фиксирующее момент, когда информация была записана в базу данных. В 1992 году Ричард Снодграсс (Richard Snodgrass) и его коллеги предложили модель битемпоральных таблиц, объединяющую оба измерения. Эта модель была формализована в рамках проекта TSQL2 (Temporal SQL) в середине 1990-х годов. В 2011 году Международная организация по стандартизации (ISO) включила поддержку темпоральных таблиц в стандарт SQL:2011, что позволило реализовать битемпоральность на уровне ядра СУБД. Первыми коммерческими системами, внедрившими эту функцию, стали IBM DB2 (с версии 10.1, 2012 год) и Oracle Database (с версии 12c, 2013 год). В 2016 году Microsoft SQL Server добавил поддержку системно-версионированных темпоральных таблиц, а затем и битемпоральных в версии 2019.
¶Принцип работы
Битемпоральная таблица содержит два набора столбцов, каждый из которых представляет собой временной интервал:
- Время действия (valid time) — период, в течение которого запись считается истинной в реальном мире. Обычно задаётся двумя столбцами:
valid_fromиvalid_to. Например, для сотрудника это может быть период его работы в компании. - Время транзакции (transaction time) — период, когда запись была актуальна в базе данных. Фиксируется автоматически СУБД и включает столбцы
transaction_fromиtransaction_to. Время транзакции не может быть изменено пользователем и отражает момент вставки или обновления записи.
Каждая строка в битемпоральной таблице представляет собой версию факта, действительную для определённого интервала времени действия и зафиксированную в определённый интервал времени транзакции. При изменении данных (например, обновлении зарплаты сотрудника) старая версия помечается как устаревшая по времени транзакции, а новая версия вставляется с новым временем транзакции. При этом время действия может быть изменено независимо.
¶Пример структуры
Рассмотрим таблицу employee_salary:
| employee_id | salary | valid_from | valid_to | transaction_from | transaction_to |
|---|---|---|---|---|---|
| 101 | 50000 | 2023-01-01 | 2023-06-30 | 2023-01-01 | 9999-12-31 |
| 101 | 55000 | 2023-07-01 | 9999-12-31 | 2023-07-01 | 9999-12-31 |
Здесь первая строка показывает, что с 1 января по 30 июня 2023 года зарплата сотрудника 101 составляла 50 000 рублей, и эта информация была записана 1 января 2023 года. Вторая строка — что с 1 июля 2023 года зарплата повышена до 55 000 рублей, и это изменение зафиксировано 1 июля 2023 года.
¶Классификация
Битемпоральные таблицы можно классифицировать по способу реализации:
- Нативные (native) битемпоральные таблицы — реализованы на уровне ядра СУБД с поддержкой стандарта SQL:2011. Примеры: IBM Db2, Oracle Database, Microsoft SQL Server (начиная с версии 2019).
- Имитированные (simulated) битемпоральные таблицы — реализуются с помощью триггеров, хранимых процедур или прикладного кода. Используются в СУБД, не имеющих встроенной поддержки темпоральности (например, MySQL, PostgreSQL до версии 13).
- Гибридные — сочетают нативную поддержку одного измерения (например, времени транзакции) с ручным управлением другим.
¶Применение
Битемпоральные таблицы используются в областях, где требуется точное восстановление состояния данных на любой момент времени в прошлом, а также учёт задержек и исправлений в записи информации. Основные сценарии:
- Финансовый учёт и аудит — хранение истории изменений балансов, транзакций и курсов валют с возможностью «перемотки» как реального времени, так и времени записи.
- Медицинские информационные системы — ведение истории диагнозов, назначений и результатов анализов, где дата события (время действия) может отличаться от даты ввода в систему (время транзакции).
- Юридические и нормативные системы — отслеживание изменений в законодательстве, контрактах и лицензиях, где важно знать, какой закон действовал в конкретный период и когда он был зафиксирован.
- Кадровый учёт — управление историей трудовых отношений, должностей и зарплат, особенно при ретроактивных изменениях (например, задним числом повышается зарплата).
- Научные исследования — хранение данных наблюдений, где время события и время регистрации могут различаться из-за задержек передачи данных.
¶Преимущества и недостатки
¶Преимущества
- Полная историчность — возможность запросить состояние данных на любой момент времени в прошлом, как по времени действия, так и по времени транзакции.
- Аудит изменений — автоматическая фиксация всех изменений, включая исправления ошибок (например, если оператор ввёл неверную дату, а затем исправил её).
- Поддержка ретроактивных изменений — возможность корректировать данные задним числом без потери предыдущих версий.
- Соответствие стандартам — поддержка SQL:2011 упрощает переносимость между СУБД.
¶Недостатки
- Рост объёма данных — каждая версия строки хранится отдельно, что может привести к значительному увеличению размера базы данных.
- Сложность запросов — для получения актуальных данных требуется явно указывать временные условия, что усложняет SQL-запросы.
- Производительность — операции вставки и обновления требуют дополнительных затрат на управление временными метками и индексами.
- Ограниченная поддержка — не все СУБД имеют нативную реализацию, а имитированные решения могут быть ненадёжными.
¶Критика
Основная критика битемпоральных таблиц связана с их сложностью для практического внедрения. Многие разработчики и администраторы баз данных считают, что управление двумя временными измерениями избыточно для большинства бизнес-задач, и предпочитают использовать простые темпоральные таблицы (только время действия или только время транзакции). Кроме того, стандарт SQL:2011 не полностью покрывает все аспекты битемпоральности, что приводит к различиям в реализации между СУБД. Некоторые исследователи отмечают, что битемпоральные таблицы не решают проблему «времени принятия решения» (decision time), когда важно знать, когда именно факт был признан истинным в организации, а не только когда он был записан.
¶Интересные факты
- Термин «битемпоральный» впервые появился в научной литературе в 1992 году в статье Ричарда Снодграсса «Temporal Databases: A Comprehensive Approach».
- В стандарте SQL:2011 битемпоральные таблицы называются «системно-версионированными темпоральными таблицами с поддержкой времени действия» (system-versioned temporal tables with valid time).
- В некоторых СУБД (например, Oracle) битемпоральные таблицы реализованы через механизм Flashback Data Archive, который автоматически сохраняет историю изменений.
- Битемпоральные таблицы используются в системах управления версиями документов, таких как IBM Content Manager OnDemand, для хранения истории изменений юридически значимых документов.
¶Источники
- Snodgrass, R. T. (1992). Temporal Databases: A Comprehensive Approach. ACM Computing Surveys, 24(4), 421–460.
- ISO/IEC 9075-2:2011 — SQL/Foundation, раздел «Temporal tables».
- Date, C. J. (2003). An Introduction to Database Systems (8th ed.). Addison-Wesley.
- Celko, J. (2014). Joe Celko’s SQL for Smarties: Advanced SQL Programming (5th ed.). Morgan Kaufmann.
- Документация IBM Db2 11.5: «Temporal tables».
- Документация Microsoft SQL Server 2019: «Temporal tables».