维护父子表中的历史数据更改

时间:2018-11-28 06:38:46

标签: sql-server database database-design change-tracking scd2

1名员工有N个地址。如果这两个表中的任何用户进行了任何更改,在这里我都需要维护Employee和Address更改的历史信息。

表员工:

Employee(
EmpID BIGINT PRIMARY KEY IDENTITY(1,1),
Name varchar(200),
EmpNumber varchar(200),
Createddate Datetime2)

地址表:

Address(
AddID BIGINT PRIMARY KEY IDENTITY(1,1),
AddressLine1 varchar(300),
AddressLine2 varchar(300),
EmpID BIGINT NULL,
AddressType varchar(100),
Createddate Datetime2)

上面,EmpID是Employee表的外键

我必须满足的场景:

  1. 我应该能够跟踪任何员工的个人地址(子表记录)记录的更改。
  2. 我应该能够跟踪带有子地址记录的Employee(父表记录)的更改。

我想过以下方法: 假设,最初处于下图所示的状态 enter image description here

解决方案1:

Case:子表更新时 现在,我更新了一个Add0001地址记录,因此我在地址表中插入了一条新记录,使先前的记录变为非活动状态,如下所示: enter image description here

Case:更新父表时 现在,当父表得到更新时,我有了父表的历史记录表,并且我将旧数据移动到历史记录表中,并将当前记录更新到父表中,如下所示: enter image description here

解决方案2:

Case:子表更新时 与解决方案1相同

情况:更新父表时

我们在父表中插入一条新记录,使先前的记录处于非活动状态。在这种情况下,我们将获得一个新的ID和该ID,我们将其作为子表的外键进行更新,如下所示:

enter image description here

这是一起维护父子表历史数据的最佳方法吗? 还是有什么办法可以保留设计,以便我应该能够完全跟踪父级和子级记录数据的更改?

3 个答案:

答案 0 :(得分:1)

如果父数据更改不是那么频繁,那么您也可以在同一表中维护父表的历史记录,并更新子表的外键。

Before Changes to Parent

现在,如果您更改员工姓名并添加新地址,然后在子表(地址)中更新员工ID。

After Changes to Parent

在使用有效时间更改姓名之前,您始终可以获取员工的地址。这样,我们无需创建其他历史记录表。但是获取所有日期比较的历史记录可能并不复杂。

欢迎提出任何建议。

答案 1 :(得分:0)

有很多方法可以解决这类问题,而您所提议的是一种完全有效的方法……至少您似乎被指出了正确的方向。

我建议进行一些更改...

1)摆脱“状态”标志,并使用“开始”和“结束”日期。的     只要有名称,具体名称就无关紧要。

2)开始日期和结束日期列均应定义为“不     NULL”和begin的默认约束应为GETDATE()或     CURRENT_TIMESTAMP。结束日期应默认为“ 99991231”。      请相信我,并消除使结束日期可为空,并为“活动”行赋予NULL结束日期的冲动。 对于所有用户而言,'99991231'是     实际目的,时间的终结。可以用来轻松地     识别当前活动的行。

3)我建议将触发器添加到以下内容:

  • a)防止更新和/或删除。理想情况下,这将是一个插入 只有桌子。
  • b)插入新行时,更新(是的,我知道 “ a)”),“现有”行的结束日期为“新 当前”行的开始日期。这样做,您将获得连续, 无间隙的历史。

希望这会有所帮助。 :)

答案 2 :(得分:0)

您是否可以使用SQL Server 2016引入的Temporal tables and history tables

这使数据专业人员可以将数据历史记录保留在相关表上,因此您无需考虑父母或孩子等。