关于在数据库中对数据进行版本控制,我已经阅读了关于SO的一些问题(例如this one)。
我喜欢上面提到的一些建议。我有最长的时间想要(需要)修改我的许多桌子,但从来没有绕过它。作为一个只有简单的数据库工作的程序员,我想知道如何才能实现这一目标。
我不是要求SQL语法中的实际解决方案。我最终可以为自己解决这个问题(或者在时机成熟时发布)。我只是要求人们评论他们将如何进行评论以及如果我要“修改”数亿条记录,可能会出现任何潜在的性能问题。或者任何其他建议,只要它基于以下示例。
举个简单的例子:
Person
------------------------------------------------
ID UINT NOT NULL,
PersonID UINT NOT NULL,
Name VARCHAR(200) NOT NULL,
DOB DATE NOT NULL,
Email VARCHAR(100) NOT NULL
Audit
------------------------------------------------
ID UINT NOT NULL,
UserID UINT NOT NULL, -- Who
TableName VARCHAR(50) NOT NULL, -- What
OldRecID UINT NOT NULL, -- Where
NewRecID UINT NOT NULL,
AffectedOn DATE NOT NULL, -- When
Comment VARCHAR(500) NOT NULL -- Why
如果TableName是字符串,我不确定如何将Audit表链接到任何其他表(例如Person)?
另外,假设我有三个GUI来填充:
要完成1和2,查询Person表或Audit表会更好吗?
要完成3,所谓的数据库专家是否只需获取所有记录并将其传递给软件进行处理,或按PersonID和受影响日期分组?这通常是在一个查询中处理还是多次处理?
答案 0 :(得分:46)
多年来我已经完成了各种审计计划,目前我正在实施这样的计划:
Person
------------------------------------------------
ID UINT NOT NULL,
PersonID UINT NOT NULL,
Name VARCHAR(200) NOT NULL,
DOB DATE NOT NULL,
Email VARCHAR(100) NOT NULL
Person_History
------------------------------------------------
ID UINT NOT NULL,
PersonID UINT NOT NULL,
Name VARCHAR(200) NOT NULL,
DOB DATE NOT NULL,
Email VARCHAR(100) NOT NULL
AuditID UINT NOT NULL
Audit
------------------------------------------------
ID UINT NOT NULL,
UserID UINT NOT NULL, -- Who
AffectedOn DATE NOT NULL, -- When
Comment VARCHAR(500) NOT NULL -- Why
当前记录始终位于Person表中。如果有更改,则会创建审计记录,并将旧记录复制到Person_History表中(请注意,ID不会更改,并且可能有多个版本)
审核ID位于* _History表中,因此您可以根据需要将多个记录更改链接到一个审核记录。
编辑:
如果每个基表没有单独的历史记录表,并且想要使用同一个表来保存旧的和“已删除”记录,则必须使用状态标记标记记录。问题是查询当前记录时真的很痛苦 - 相信我,我已经做到了。
答案 1 :(得分:6)
如何正常创建表,在每条记录上都有一个ModifiedDate Colm(如果你愿意,还有ModifiedBy),并通过物化视图进行所有数据访问,该视图按Id对数据进行分组,然后进行HAVING ModifiedDate = MAX(ModifiedDate)?
这样,添加具有相同Id的新记录将从视图中删除旧记录。如果要查询历史记录,请不要查看视图
我总是发现使用相同的Colm维护不同的表是复杂且容易出错的。
答案 2 :(得分:2)
在DJ的帖子中使用每个基表的历史表和Karl关于可能的性能问题的评论后,我做了一些SQL研究,以便找出从一个表到一个表的最快转移方式另一个。
我只想记录我发现的内容:
我认为我必须进行SQL提取以从基表加载记录,然后进行SQL推送以将记录放入历史表中,然后更新基表以插入更改的数据。共3笔交易。
但令我惊讶的是,我意识到您可以使用SELECT INTO语法使用一个SQL语句执行前两个事务。我认为这样做的速度会快一百倍。
然后,这将使我们只需使用基表中的新数据更新记录。
我仍然没有找到一个SQL语句一次完成所有3个事务(我怀疑我会)。
答案 3 :(得分:1)
我喜欢你的审计表,这是一个好的开始。您的审计表存在基数问题,因此我将其作为两个表格填写:
Person
------------------------------------------------
ID UINT NOT NULL,
PersonID UINT NOT NULL,
Name VARCHAR(200) NOT NULL,
DOB DATE NOT NULL,
Email VARCHAR(100) NOT NULL,
AuditID UINT NOT NULL
Audit
------------------------------------------------
ID UINT NOT NULL,
TableName VARCHAR(50) NOT NULL, -- What
TableKey UINT NOT NULL,
CreateDate DATETIME NOT NULL DEFAULT(NOW),
CreateUserID UINT NOT NULL,
ChangeDate DATETIME NOT NULL DEFAULT(NOW),
ChangeUserID UINT NOT NULL
Audit_Item
------------------------------------------------
ID UINT NOT NULL,
AuditID UINT NOT NULL, -- Which audit record
UserID UINT NOT NULL, -- Who
OldRecID UINT NOT NULL, -- Where
NewRecID UINT NOT NULL,
AffectedOn DATE NOT NULL, -- When
Comment VARCHAR(500) NOT NULL -- Why
建议的初始布局有一条审核记录,指向(我假设)两条人员记录。这种设计的挑战是:
WHERE
TableName='Person'