在sql中随着时间的推移跟踪记录更新的一些最佳实践是什么?

时间:2018-08-17 12:12:54

标签: sql sql-server database database-design sql-server-2017-express

我有一个带有主键@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重新插入新的类别和价格记录。这将导致大量重复,尤其是如果这些记录未做任何更改。

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

我看到了一些不同的示例,但是大多数示例似乎只处理一张表中的一条记录,而不是处理一对多或多对多关系的一部分的记录。我希望可以在不需要其他表的情况下完成此操作。

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

1 个答案:

答案 0 :(得分:3)

如果您正在使用SQL Server的较新版本,则应考虑使用temporal tables,因为这可能是您的最佳选择。

如果您需要支持较旧的版本,我的首选方法是使用一个带有新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值的历史记录中进行选择,并轻松地将其作为历史更改日志(谁更改了内容和时间)进行了读取。我看不到如何在设计中做到这一点。如果您真的很聪明,则可以查找或编写一个为您比较行的网格,您可以快速查看发生了什么变化。

相关问题