2

我有一个带有主键 @productid (bigint)、产品编号 (int) 和版本 (int) 的产品表

每当有人仅更改产品记录时,我计划在数据库中插入具有相同产品号和版本号 + 1 的新行。这将为我提供记录所需的历史跟踪,因为我可以看到版本随时间变化。

/* Selecting the current version is simple */
Select top 1 *
from products
where productnumber = @productnumber
order by version desc  

但是,我的问题来自外键一对多或多对多关系表。该表指出了许多其他也需要跟踪的(即带有日期范围、产品类别等的产品定价)。

/* Product categories, pricing */ 
 /* Should I use @productnumber here? How do I track changes to these records? */

select name
from productcategories
where productid = @productid

select price
from productpricing
 where productid = @productid and
       StartDate > @StartDate and
       EndDate <@Enddate

因此,现在任何时候有版本更改,我都计划重新插入新的类别和定价记录,并使用生成的新主键产品 ID。这将导致大量重复,尤其是在没有更改的情况下制作这些记录。

问题也随之而来 - 如果删除了一个类别但产品记录没有更改会发生什么?我想看看是谁删除了这个类别。本质上,需要对每张表进行全面审计。

我见过一些不同的例子,但它们中的大多数似乎只处理一个表中的记录,而不是一对多或多对多关系的一部分的记录。我希望这可以在不需要额外表格的情况下完成。

有没有更好的方法或做法?这会是一场表演噩梦吗?

4

1 回答 1

3

如果您使用的是较新版本的 SQL Server,您可以查看临时表,因为这可能是您的最佳选择。

如果您需要支持旧版本,我首选的方法是创建一个包含新 PK 列、更改标志(I、U、D)、修改日期、进行更改的用户以及来自主表。然后我索引与非历史表的 PK 相关的列。如果您不将逻辑放入其中,触发器不会对性能产生太大影响。示例(伪代码):

Table: Car
Column: CarID INT IDENTITY(1,1) Primary Key
Column: Name varchar

Table: Car_hist
Column: Car_histID INT IDENTITY(1,1) Primary Key
Column: Change char(1)
Column: DateOfChange DateTime2
Column: ChangedByUser (varchar or int)
Column: CarID <-add a unique non-clustered index
Column: Name varchar

您可以在 SQL 中编写一个生成器,该生成器生成创建历史表、索引等的脚本。如果您有一致的表设计实践,这将很有帮助。

现在的原因是:我很少需要查询历史表,但是当我这样做时,几乎总是需要一条记录来查看发生了什么以及谁更改了它。这种方法可以让您快速从父表的 PK 值的历史中进行选择,并将其作为历史更改日志轻松读取(谁更改了什么以及何时更改)。我看不出你怎么能在你的设计中做到这一点。如果你真的很聪明,你可以找到或编写一个为你区分行的网格,你可以快速看到发生了什么变化。

于 2018-08-17T12:45:14.857 回答