此程序的现有设计是将所有更改写入带有时间戳的changelog表。为了获取项目属性的当前状态,我们JOIN
到更改日志表中,并获取具有最新时间戳的行。
这是跟踪当前值的混乱方式,但我们目前无法轻易更改此更改日志设置。
我打算通过在changelog表中添加“IsMostRecent”位来稍微修改行为。这将允许我简单地拉出具有该位设置的行,而不是MAX()
聚合或递归搜索。
您将采用什么策略来确保始终正确设置该位?或者您是否有一些替代方案,它不会影响日志表的当前使用?
目前我正在考虑一种触发方法,它会将所有其他行关闭,然后将其打开,以便INSERT
上的最新行
答案 0 :(得分: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引用的实体时做到了(上面是我对第一个版本的回忆 - 我没有代码可以处理。)
然而,简单版本导致多个编写器出现问题,因为这可能导致死锁或事务失败;所以它被移动到触发器中。
答案 1 :(得分: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
或者它可以作为合并来完成捕获插入。
答案 2 :(得分:0)
我想到的一件事是创建一个视图来在幕后执行所有混乱的MAX()查询等。然后你应该能够查看视图。这种方式不需要改变你当前的设置,只需将所有混乱移动到一个地方。