数据库记录有关n-m关系变化的信息

时间:2014-10-31 07:55:28

标签: sql-server database versioning audit

我有一个(SQL Server)数据库,我正在跟踪表上的更改;客户的要求是能够及时查看任何一点的“图片”,指定所要求的日期。 到目前为止,我所做的是按照Log trigger的想法实现HistoryTable,并使用数据库触发器来存储历史数据。

现在,需求发生了变化,我需要在原始表中添加多对多(n-m)关系。当然,链接数据集(n-m关系)也应该“版本化”,随着时间的推移而变化为原始表。

我的第一个想法是在主表中引用n-m关系和“伪ID”,即:普通(int)字段,而不是主键(不随时间变化)。通过这种方式,我可以随时间更改该ID,例如:

版本1:

Version 1
ID  RelID  Data
5   5      Version 1

Version 2
ID  RelID  Data
5   5      Version 2

Version 3
ID  RelID  Data
5   6      Version 3

在此示例中,n-m关系在版本1和版本2之间没有变化,但在版本3中更改。

这很好,但我的问题是:

  • 每当n-m关系版本发生变化时,如何获得表中唯一的新RelID?
  • 另一种选择:我可以将n-m关系引用到ID和RelID(肯定是唯一的)吗?
  • 有没有比我更聪明的解决方案?

提前感谢您的任何帮助

1 个答案:

答案 0 :(得分:1)

这种情况听起来很容易适应缓慢变化的维度的数据仓库概念。通常,类型2缓慢变化的尺寸被认为是最有用的。这些记录了行的每个版本的开始和结束日期,当前行只为结束日期存储NULL

基本上,您可以在桥接表中添加其他列,以记录该行版本的开始和结束日期。在EndDate为NULL的情况下,您知道这是当前行版本。

所以你的表最终看起来像:

 ID | RelID | StartDate  | EndDate
----+-------+------------+------------
 05 |   06  | 2014-10-01 | NULL
 05 |   05  | 2014-09-10 | 2014-10-01
 05 |   03  | 2014-09-10 | NULL

从这些数据中你可以看出ID 05与RelID 05有关,直到2014-10-01,然后它与RelID 06有关,它仍然与RelID 03相关。

然后,当您需要当前的关系数据时,您可以简单地说

SELECT *
FROM Table
WHERE EndDate IS NULL

如果你回顾历史,你可以说

SELECT *
FROM Table
WHERE @selectionDate BETWEEN StartDate AND COALESCE(EndDate,GETDATE())

在不了解您的数据结构的情况下,我无法判断这是否适合您尝试解决的问题。但通常多对多关系需要在两个实际记录表之间建立桥接表以创建正确的关系,而Type-2缓慢变化的维度是在数据仓库中对行进行版本控制的一种经过验证的方法和相同的概念可以应用于您需要历史版本记录的任何地方。