dan*_*lhc 5 sql database bi-temporal
在SQL中实现双时态数据库时,通常建议使用以下时间戳:
我以前曾经使用过这种方法几次,但我一直想知道为什么只有3个时间戳,将TransactionEnd保留在外,这不仅仅是一个正确的实现.这里的事务时间范围从TransactionStart到下一个TransactionStart.
是否有强大的论据不仅使用3个时间戳,这将限制数据库的大小?
正如评论中提到的,这是为了简单起见,因为如果没有它,进行某些查询会有些困难。
考虑以下示例。John
于 1990 年 1 月 1 日出生于某地点 Location1
,但首次登记出生于 5 号。
数据库表现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|
+----------+--------------+------------+----------+------------+----------+
Run Code Online (Sandbox Code Playgroud)
此时,删除该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|
+----------+--------------+------------+----------+------------+----------+
Run Code Online (Sandbox Code Playgroud)
假设有人想找出“系统认为约翰现在住在哪里”(交易时间),无论他实际住在哪里。可以(粗略地)通过以下方式在 SQL 中查询
Select Location
From Persons
Where Name = John AND trans_from > NOW AND trans_to < NOW
Run Code Online (Sandbox Code Playgroud)
假设交易结束时间被删除
+----------+--------------+------------+----------+------------+
| 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 |
+----------+--------------+------------+----------+------------+
Run Code Online (Sandbox Code Playgroud)
上面的查询当然不再有效,但是在最后一个表中为相同的查询制定逻辑会有些困难。由于trans_to
缺少 ,因此必须从表中的其他行派生。例如,trans_to
第一行的隐式时间(因为它是最旧的条目)是trans_from
第二行的隐式时间,第二行是两行中较新的一个。
因此9999-99-99
,如果该行是最新的,则事务结束时间为 ,或者是trans_from
紧接其后的行的 。
这意味着与特定行相关的数据并不完全保留在该行中,并且这些行形成了彼此的依赖关系,这(当然)是不需要的。此外,确定哪一行是某行的直接后继可能非常困难,这会使查询变得更加复杂