Возможно ли использование только 3 временных меток для битемпоральной базы данных SQL?
При реализации битемпоральной базы данных в SQL обычно рекомендуется использовать следующие временные метки:
- ValidStart
- ValidEnd
- TransactionStart
- TransactionEnd
Я использовал этот подход несколько раз прежде, но я всегда задавался вопросом, почему наличие только 3 временных отметок, исключая TransactionEnd, не является столь же правильной реализацией. Здесь диапазон времени транзакции простирается от TransactionStart до следующего TransactionStart.
Есть ли веские аргументы в пользу не только использования 3 временных меток, что ограничит размер базы данных?
2 ответа
Как упомянуто в комментарии, это для простоты, так как несколько труднее сделать определенные запросы без него.
Рассмотрим следующий пример. John
родился в каком-то месте, Location1
, в январе первого 1990 года, но впервые зарегистрирован, чтобы родиться пятым.
Таблица базы данных, Persons
теперь выглядит так:
+----------+--------------+------------+----------+------------+----------+
| Name | Location | valid_from | valid_to | trans_from | trans_to |
+----------+--------------+------------+----------+------------+----------+
| John | Location1 | 01-01-1990 |99-99-9999| 05/01/1990 |99-99-9999|
+----------+--------------+------------+----------+------------+----------+
На этом этапе удаление trans_to
Столбец не вызовет особых проблем, но предположим следующее:
Через несколько лет, скажем, 20, John
переезжает в Location2
и проинформировать чиновников через 20 дней. Это сделает Persons
стол выглядит так
+----------+--------------+------------+----------+------------+----------+
| Name | Location | valid_from | valid_to | trans_from | trans_to |
+----------+--------------+------------+----------+------------+----------+
| John | Location1 | 01-01-1990 |99-99-9999| 05/01/1990 |20-01-2010|
| John | Location1 | 01-01-1990 |01-01-2010| 20/01/2010 |99-99-9999|
| John | Location2 | 01-01-2010 |99-99-9999| 20/01/2010 |99-99-9999|
+----------+--------------+------------+----------+------------+----------+
Предположим, кто-то хотел выяснить, "где система думает, что Джон живет сейчас" (время транзакции), независимо от того, где он на самом деле живет. Это может (примерно) быть запрошено в SQL следующим образом
Select Location
From Persons
Where Name = John AND trans_from > NOW AND trans_to < NOW
Предположим, что время окончания транзакции было удалено
+----------+--------------+------------+----------+------------+
| Name | Location | valid_from | valid_to | trans_from |
+----------+--------------+------------+----------+------------+
| John | Location1 | 01-01-1990 |99-99-9999| 05/01/1990 |
| John | Location1 | 01-01-1990 |01-01-2010| 20/01/2010 |
| John | Location2 | 01-01-2010 |99-99-9999| 20/01/2010 |
+----------+--------------+------------+----------+------------+
Вышеуказанный запрос, конечно, больше не действителен, но сделать логику для того же запроса в последней таблице было бы довольно сложно. Так как trans_to
отсутствует, он должен быть получен из других строк в таблице. Например, неявный trans_to
время для первого ряда (так как его самая старая запись) является trans_from
из второго ряда, который является более новым из двух.
Время окончания транзакции, таким образом, либо 9999-99-99
, если строка самая новая, или это trans_from
из ряда сразу же следуя за ним.
Это означает, что данные, относящиеся к конкретной строке, не полностью хранятся в этой строке, и строки образуют зависимость друг от друга, что (конечно) нежелательно. Кроме того, может быть довольно трудно определить, какая именно строка является непосредственным преемником строки, что может сделать запросы еще более сложными.
Пример использования только одной временной метки вместо двух во временной базе данных 1D:
У меня есть магазин, и я хочу записать, когда пользователь X был в моем магазине.
Если я использую модель с начальным и конечным временем, эта информация может быть записана как
X,1,2
X,3,4
так что пользователь X находился в моем магазине между 1 и 2 и между 3 и 4. Это ясно, просто и кратко.
Если я буду моделировать свои данные, используя только метку времени начала, у меня будет:
X,1
X,2
X,3
X,4
но как я могу интерпретировать эти данные? Х из (1,2) и Х из (3,4)? или Х из (2,3) и Х из (1,4)? или Х из (1,2), (2,3), (3,4)? X из (4,inf) действителен?
Чтобы понять эти данные, мне нужно добавить дополнительные ограничения / логику / информацию к моим данным или коду: возможно, интервалы не перекрываются, возможно, я добавляю идентификатор для объекта и т. Д. Все эти решения работают не во всех случаях, могут быть Трудно поддерживать и другие вопросы.
Например, если я добавлю идентификатор (в данном случае a, b) к каждому элементу, это приведет к:
X,a,1
X,a,2
X,b,3
X,b,4
вместо того, чтобы хранить мои данные в 2 строки, 3 столбца, мои данные будут храниться в 4 строки, 3 столбца. Я не только не пользуюсь этой моделью, но эта модель может быть уменьшена до:
X,a, 1,2
X,b, 3,4
далее сводится к
X, 1,2
X, 3,4