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

时间:2015-04-15 07:55:12

标签: sql database bi-temporal

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

  • ValidStart
  • ValidEnd
  • TransactionStart
  • TransactionEnd

之前我曾经使用过这种方法几次,但我一直想知道为什么只有3个时间戳,将TransactionEnd排除在外,并不是正确的实现。这里的交易时间范围从TransactionStart到下一个TransactionStart。

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

2 个答案:

答案 0 :(得分:3)

正如评论中提到的那样,为简单起见,因为如果没有它,有些难以进行某些查询。

考虑以下示例。 John出生于1990年1月1日的某个地方,Location1,但是第一次注册出生在第五个地方。

数据库表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|
+----------+--------------+------------+----------+------------+----------+

假设某人想要找出"系统认为John现在生活在哪里" (交易时间),无论他实际生活在哪里。这可以(大致)以下列方式在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。< / p>

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

答案 1 :(得分:1)

在1D时态数据库中仅使用一个时间戳而不是两个时间戳的示例:

我有一个商店,我想记录用户X在我店里的时间。

如果我使用具有开始时间和结束时间的模型,则此信息可以记录为

X,1,2
X,3,4

因此用户X在我的商店中介于1和2之间以及3到4之间。这是清晰,简单和简洁的。

如果我只用开始时间作为时间戳来建模我的数据,我会:

X,1
X,2
X,3
X,4

但我如何解释这些数据呢? X来自(1,2),X来自(3,4)?或来自(2,3)的X或来自(1,4)的X? 或者来自(1,2),(2,3),(3,4)的X?来自(4,inf)的X有效吗?

要理解这些数据,我需要在我的数据或代码中添加其他约束/逻辑/信息: 也许间隔是非重叠的,也许我为每个对象添加一个id等。 所有这些解决方案在所有情况下都不起作用,可能难以维护和其他问题。

例如:如果我在每个项目中添加一个id(在这种情况下为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