查询稀疏交易记录

时间:2018-10-23 19:50:55

标签: sql sql-server

我的数据库架构组织如下:

TransactionTable-系统中每笔交易的一行。

LobTable-系统中该Lob实体的每个历史状态的一行。

所以我可能有事务行1、2、3和4。

在事务1中,使用指向TransactionTable第1行(LobTable第1行和LobTable第2行)的外键创建了2个LobTable行。

在事务2中,修改了LobTable第1行,生成了一个新的LobTable行(LobTable第3行),其中带有指向TransactionTable第2行的外键。

在事务3中,修改了LobTable第2行,生成了一个新的LobTable行(LobTable第4行),并带有对TransactionTable第3行的外键。

在事务4中,LobTable上没有任何更改,因此没有创建新行。

现在我想问一个问题:从事务4开始,LobTable的状态是什么。答案应该是(LobTable第3行,LobTable第4行)。

更相关的是,给定对TransactionTable的查询,我想将其“联接”到LobTable,使Transaction 4联接到LobTable第3和4行,事务3联接到LobTable第3和4行,Transaction 2连接到LobTable第3和2行,而事务1连接到LobTable第1和2行。

在SQL中是否有很好的有效方法来做到这一点?当前,我必须通过回滚过程来运行这整个过程,该过程会将数据从数据库中拉出并找出每个事务的处理方式,这并不是很有效。

另一个更困难的问题:实际情况比这还糟。 LobTable实际上有2个独立的TransactionTable外键,以便以绝对噩梦的方式处理乱序事务处理。有一个主外键,然后是一个外键,它指示什么事务覆盖了该行。

因此,例如,获取一个包含3个事务的TransactionTable:事务1,事务2,最后是事务3,该事务发生在事务2之后,但日期早于事务2。以一个LobTable实体为每个发生的事务都有一行。它将以4行结尾:

LobTable第1行与两个FK中的TransactionTable第1行相关联。

LobTable第2行与其主FK中的TransactionTable第2行相关联,而它的FK中“ TransactionTable第3行”与其“覆盖”相关。重要的是,它最初是由事务2生成的,具有匹配的FK,并具有由事务3覆盖的辅助FK。此行表示Lob实体在被事务3覆盖之前的状态。

LobTable第3行与两个FK中的TransactionTable第3行相关联。

LobTable第4行与两个FK中的TransactionTable第2行相关联。但是,此行是由交易3生成的

现在,鉴于此,是否有一种仅使用SQL以及上面指定的稀疏事务来解决此问题的好方法?应当注意,以上示例是绝对最简单的示例。可能有整个覆盖的链,每行指示哪个事务取代了它,而不是生成它的事务。

我的最终目标是使数据变得稀疏(实际上,我将保持Lob数据的实际稀疏性,但是向密集型架构添加了交叉引用表,因此查询总是很容易的)数据,然后展开此乱序处理(因此上面的事务3还将生成事务4以对事务2进行“更正”,而不涉及事务2中的数据)。但是,我需要能够将旧数据处理成这种新格式,而这种旧模式却给我带来了噩梦。

编辑: 失序的更具体示例: 交易1是创造一辆价值$ 25,000的汽车,并扣除$ 1000的碰撞费。事务2使用户将碰撞免赔额更改为$ 500。交易#3在交易#2之前有一个更改生效日期,并将车辆价值更正为$ 20,000。截至交易#3,该值为$ 20,000,碰撞免赔额为$ 1000。

Transaction表的外观如下:

  • 更改时的Tx#1有效日期为2018年10月23日
  • Tx#2于变更生效于2018年10月30日
  • 更改中的Tx#3,于2018年10月25日生效

Tx#1之后的Vehicle表是什么样的?

Veh#1:

  • 交易Tx#1
  • 被Tx#1覆盖
  • 标识符1
  • 价值$ 25,000
  • 免赔额$ 1,000

Tx#2之后的Vehicle表是什么样的?

Veh#1:

  • 交易Tx#1
  • 被Tx#1覆盖
  • 标识符1
  • 价值$ 25,000
  • 免赔额$ 1,000

Veh#2:

  • 交易Tx#2
  • 被Tx#2覆盖
  • 标识符1
  • 价值$ 25,000
  • 免赔额$ 500

Tx#3之后的Vehicle表是什么样的?

Veh#1:

  • 交易Tx#1
  • 被Tx#1覆盖
  • 标识符1
  • 价值$ 25,000
  • 免赔额$ 1,000

Veh#2:

  • 交易Tx#2
  • 被Tx#3覆盖
  • 标识符1
  • 价值$ 25,000
  • 免赔额$ 500

Veh#3:

  • 交易Tx#3
  • 被Tx#3覆盖
  • 标识符1
  • 价值$ 20,000
  • 免赔额$ 1,000

Veh#4:

  • 交易Tx#2
  • 被Tx#2覆盖
  • 标识符1
  • 价值$ 20,000
  • 免赔额$ 500

1 个答案:

答案 0 :(得分:0)

要回答您的问题的上半部分,我认为处理此问题的最有效方法是使用已建立索引的日期时间列。

任何事务的LobTable状态将是最近的LobTable行,其时间戳等于或小于事务时间戳。

我不能用您用来描述它的抽象术语来关注您的第二个问题。一些具体的样本数据和所需的结果可能有助于使其更加清晰。