是否可以仅为双时态SQL数据库使用3个时间戳?

dan*_*lhc 5 sql database bi-temporal

在SQL中实现双时态数据库时,通常建议使用以下时间戳:

  • ValidStart
  • ValidEnd
  • TransactionStart
  • TransactionEnd

我以前曾经使用过这种方法几次,但我一直想知道为什么只有3个时间戳,将TransactionEnd保留在外,这不仅仅是一个正确的实现.这里的事务时间范围从TransactionStart到下一个TransactionStart.

是否有强大的论据不仅使用3个时间戳,这将限制数据库的大小?

And*_*snk 4

正如评论中提到的,这是为了简单起见,因为如果没有它,进行某些查询会有些困难。

考虑以下示例。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紧接其后的行的 。

这意味着与特定行相关的数据并不完全保留在该行中,并且这些行形成了彼此的依赖关系,这(当然)是不需要的。此外,确定哪一行是某行的直接后继可能非常困难,这会使查询变得更加复杂