我应该如何在数据库中设置一个表来保存记录的历史记录?

时间:2011-04-11 19:37:30

标签: history relational-database database-design

我正在尝试为ASP.NET MVC站点设置SQL Server数据库,该站点将存储最新信息以及数据所有更改的历史记录。

我网站的信息来自用户上传的XML文件。站点解析XML并将包含的信息写入站点数据库。连续上传中的元素实际上可能表示相同的内容,但某些数据可能已更改。但就像我之前说的那样,我想跟踪每一个版本。

下表显示了我正在考虑采用这种方法的一种方法。我会为每个上传中的每个项目创建重复记录。与之前上传内容相匹配的新项目将分配相同的ID,但每个项目都会分配给唯一的上传ID。

Upload 1: Erik and Sara are added
Upload 2: Erik renamed to Eric, Bill added
Upload 3: Sarah grew 2" taller, Eric was removed.


[PERSONS TABLE]
PersonID     Name    Height    UploadID
1            Erik    71        1
1            Eric    71        2
2            Sarah   70        1
2            Sarah   70        2
2            Sarah   72        3
3            Bill    76        2
3            Bill    76        3


[UPLOADS TABLE]
UploadID    UploadTime
1           3/09/2011
2           4/01/2011
3           4/11/2011

然而,这对我来说似乎不是最佳解决方案,因为有多少信息最终会在数据库中重复出现。有没有更好的方法来解决这个问题,只有每次上传都会保存更改?

1 个答案:

答案 0 :(得分:1)

我认为问题在于您的PERSONS表不再包含有关PERSONS的信息。它还包含有关updload的信息。我要推荐的内容可能不会减少数据库的大小;但它会让它更容易理解和使用。

PERSONS
PersonID, Name, Height
1            Eric    71
2            Sarah   72  
3            Bill    76

UPLOAD
UploadID, UploadTime
1           3/09/2011
2           4/01/2011
3           4/11/2011

PERSONS_EDIT
PersonID, UploadID,      ChangeSQL,                                    ChangeDescription
1          1         "insert into PERSONS(Name, Height) VALUES('Erik', 71)" "Erik added"
1          2         "update PERSONS set name='Eric' where Name='Erik'"    "Changed Erik's name"
....      ...              ......                                            ....

我不认为你可以做很多事情来使你的表更简单或你的数据库更小。如您所见,您的PERSONS_EDIT表将成为您最大的表。您正在使用的数据库可能提供自动执行此操作的机制(某种事务记录或某些事情)但我从未使用过类似的东西,所以我会将它留给Stackoverflow上的其他人提出这样的建议,如果他们存在。如果PERSONS_EDIT表太大,您可以查看删除超过一周/月/年的条目。关于何时这样做的决定取决于你。

进行此更改的其他一些原因,在第一个表中,您必须使用PersonId和UploadID作为个人表的主键。因此,要在您的应用程序中实际获取最新版本的PERSON,您必须执行以下操作:按ID选择人员,然后通过他们的UploadId进行排序并选择具有最大上载ID的那个ID每次您都要做交易一个人。

另一个好处是你不必做一堆花哨的SQL来获取你的编辑历史。只需从PERSONS_EDIT表中选择*。