在 sql 中随着时间的推移跟踪记录更新的一些最佳实践是什么?
What are some of the best practices for tracking updates to a record over time in sql?
我有一个产品 table,它有一个主键 @productid (bigint)、一个产品编号 (int) 和一个版本 (int)
每当有人仅对产品记录进行更改时,我计划在数据库中插入一个具有相同产品编号和版本号 + 1 的新行。这将为我提供记录所需的历史跟踪因为我可以看到版本随时间变化。
/* Selecting the current version is simple */
Select top 1 *
from products
where productnumber = @productnumber
order by version desc
但是,我的问题出在外键一对多或多对多关系 table 上。此 table 指向许多其他也需要跟踪的内容(即带有日期范围的产品定价、产品类别等)。
/* 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 重新插入新类别和定价记录。这将导致大量重复,特别是如果没有对这些记录进行任何更改。
问题还在于 - 如果删除了类别但产品记录没有更改,会发生什么情况?我想看看谁删除了该类别。本质上,每个 table 都需要进行全面审核。
我见过一些不同的例子,但其中大多数似乎只处理一个 table 中的记录,而不是一对多或多对多关系中的记录.我希望这可以在不需要额外的 tables 的情况下完成。
有没有更好的方法或做法?这会是一场性能噩梦吗?
如果您正在使用较新版本的 SQL 服务器,您可以查看 temporal tables,因为这可能是您的最佳选择。
如果您需要支持旧版本,我的首选方法是让历史记录 table 包含新的 PK 列、更改标志 (I、U、D)、修改日期、创建更改,以及主要 table 中的所有列。然后我索引非历史PK相关的列table。如果您不在其中添加逻辑,触发器不会对性能产生太大影响。
示例(伪代码):
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 中编写一个生成器来生成脚本来创建历史记录 table、索引等。如果您有一个一致的 table 设计实践,它会有所帮助。
现在的原因是:我很少需要查询历史记录 tables,但当我这样做时,几乎总是通过一条记录来查看发生了什么以及谁更改了它。此方法允许您快速从历史记录中 select 父 table 的 PK 值,并将其作为历史更改日志轻松读取(谁更改了什么以及何时更改)。我看不出你如何在你的设计中做到这一点。如果你真的很老练,你可以找到或编写一个网格来为你区分行,你可以很快看到发生了什么变化。
我有一个产品 table,它有一个主键 @productid (bigint)、一个产品编号 (int) 和一个版本 (int)
每当有人仅对产品记录进行更改时,我计划在数据库中插入一个具有相同产品编号和版本号 + 1 的新行。这将为我提供记录所需的历史跟踪因为我可以看到版本随时间变化。
/* Selecting the current version is simple */
Select top 1 *
from products
where productnumber = @productnumber
order by version desc
但是,我的问题出在外键一对多或多对多关系 table 上。此 table 指向许多其他也需要跟踪的内容(即带有日期范围的产品定价、产品类别等)。
/* 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 重新插入新类别和定价记录。这将导致大量重复,特别是如果没有对这些记录进行任何更改。
问题还在于 - 如果删除了类别但产品记录没有更改,会发生什么情况?我想看看谁删除了该类别。本质上,每个 table 都需要进行全面审核。
我见过一些不同的例子,但其中大多数似乎只处理一个 table 中的记录,而不是一对多或多对多关系中的记录.我希望这可以在不需要额外的 tables 的情况下完成。
有没有更好的方法或做法?这会是一场性能噩梦吗?
如果您正在使用较新版本的 SQL 服务器,您可以查看 temporal tables,因为这可能是您的最佳选择。
如果您需要支持旧版本,我的首选方法是让历史记录 table 包含新的 PK 列、更改标志 (I、U、D)、修改日期、创建更改,以及主要 table 中的所有列。然后我索引非历史PK相关的列table。如果您不在其中添加逻辑,触发器不会对性能产生太大影响。 示例(伪代码):
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 中编写一个生成器来生成脚本来创建历史记录 table、索引等。如果您有一个一致的 table 设计实践,它会有所帮助。
现在的原因是:我很少需要查询历史记录 tables,但当我这样做时,几乎总是通过一条记录来查看发生了什么以及谁更改了它。此方法允许您快速从历史记录中 select 父 table 的 PK 值,并将其作为历史更改日志轻松读取(谁更改了什么以及何时更改)。我看不出你如何在你的设计中做到这一点。如果你真的很老练,你可以找到或编写一个网格来为你区分行,你可以很快看到发生了什么变化。