0

该程序的现有设计是将所有更改写入带有时间戳的更改日志表。为了获取项目属性的当前状态,我们JOIN进入更改日志表并获取具有最新时间戳的行。

这是跟踪当前值的一种混乱方式,但我们目前无法轻易更改此更改日志设置。

我打算通过在更改日志表中添加“IsMostRecent”位来稍微修改行为。这将允许我简单地拉出设置了该位的行,而不是MAX()聚合或递归查找。

您将采用什么策略来确保始终正确设置该位?或者您是否建议了一些不影响当前使用记录表的替代方案?

目前我正在考虑一种触发方法,它关闭所有其他行的位,然后为最近一行打开它INSERT

4

3 回答 3

2

我之前通过一个“MostRecentRecorded”表完成了此操作,该表仅包含最近插入的记录(Id 和实体 ID)触发触发器。

有一个额外的列是不对的 - 并且可能会让您陷入交易和阅读现有条目的问题。

在第一个版本中,这是一个简单的案例

BEGIN TRANSACTION 
    INSERT INTO simlog (entityid, logmessage) 
           VALUES     (11, 'test'); 

    UPDATE simlogmostrecent 
    SET    lastid = @@IDENTITY 
    WHERE  simlogentityid = 11 
COMMIT 

确保 MostRecent 表对 SimLog 中的每条记录都有一个条目可以在查询中完成,但是 ISTR 我们在创建 SimLog 所引用的实体期间完成了它(以上是我对第一个版本的回忆 - 我没有手头有代码)。

然而,简单版本会导致多个写入者出现问题,因为可能会导致死锁或事务失败;所以它被移到了触发器中。

于 2013-10-16T16:45:07.713 回答
1

编辑:在理查德哈里森回答之前开始这个答案,承诺:)

我建议另一个结构类似于下面的表:

VersionID  TableName   UniqueVal  LatestPrimaryKey
1          Orders      209        12548
2          Orders      210        12549
3          Orders      211        12605
4          Orders      212        10694

VersionID -- being the tables key
TableName -- just in case you want to roll out to multiple tables
UniqueVal -- is whatever groups multiple rows into a single item with history (eg Order Number or some other value)
LatestPrimaryKey -- is the identity key of the latest row you want to use.

然后你可以简单地JOIN对这个表只返回最新的行。

如果您已经有一个将行插入更改日志表的触发器,则可以对其进行调整:

INSERT INTO [MyChangelogTable]
(Primary, RowUpdateTime)
VALUES (@PrimaryKey, GETDATE())

-- Add onto it:

UPDATE [LatestRowTable]
SET [LatestPrimaryKey] = @PrimaryKey
WHERE [TableName] = 'Orders'
AND [UniqueVal] = @OrderNo

或者,它也可以作为捕获插入的合并来完成。

于 2013-10-16T17:20:55.273 回答
0

想到的一件事是创建一个视图来在幕后执行所有凌乱的 MAX() 查询等。然后你应该能够查询视图。这种方式不必更改您当前的设置,只需将所有杂乱无章的东西移到一个地方。

于 2013-10-16T16:47:19.890 回答