1

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. 我应该能够使用子地址记录跟踪员工(父表记录)的更改。

我想到了以下方式:假设,最初它处于下图所示的状态 在此处输入图像描述

解决方案1:

案例:当子表更新时,我更新了 Add0001 地址记录,因此我在地址表中插入了一条新记录,使之前的记录无效: 在此处输入图像描述

案例:当父表现在更新时,当父表更新时,我有父表的历史表,我将旧数据移动到历史表并将当前记录更新到父表中,如下所示: 在此处输入图像描述

解决方案 2:

案例:当子表更新时与解决方案1中的相同

案例:当父表更新时

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

在此处输入图像描述

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

4

3 回答 3

2

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

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

1)摆脱“状态”标志并使用“开始”和“结束”日期。只要您拥有特定名称,它们就无关紧要。

2) 开始和结束日期列都应定义为“NOT NULL”,并且开始应具有 GETDATE() 或 CURRENT_TIMESTAMP 的默认约束。结束日期应默认为“99991231”。 相信我,并克制将结束日期设为 NULLable 并将“活动”行设为 NULL 结束日期的冲动。“99991231”实际上是时间的尽头。并可用于轻松识别当前活动的行。

3)我建议在以下内容中添加一个触发器:

  • a) 防止更新和/或删除。理想情况下,这将是一个仅插入表。
  • b)当插入新行时,更新(是的,我知道“a)”所说的) “现有当前”行结束日期与“新当前”行开始日期。通过这样做,您将拥有连续的、无间隙的历史记录。

希望这可以帮助。:)

于 2018-11-28T07:22:21.223 回答
1

您可以使用SQL Server 2016 引入的临时表和历史表吗?

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

于 2018-11-28T08:18:03.627 回答
1

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

更改父级之前

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

更改为父级后

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

欢迎任何建议。

于 2018-11-28T09:14:34.953 回答