22

我需要设计一个历史表来跟踪编辑时在特定记录上更改的多个值。

示例:
向用户显示一个页面来编辑记录。

职务:先生
姓名:Joe
电话:555-1234
出生日期:1900-10-10

如果用户更改了这些值中的任何一个,我需要跟踪旧值并记录新值。

我想过使用这样的表格:

历史
---------------

id
modifiedUser
modifiedDate
tableName
recordId
oldValue
newValue

这样做的一个问题是每次编辑都会有多个条目。我正在考虑用另一张桌子对它们进行分组,但您仍然遇到同样的问题。

我也在考虑在历史表中保留该行的副本,但这似乎也没有效率。

有任何想法吗?

谢谢!

4

3 回答 3

18

我建议对于您要跟踪历史记录的每个表,您有第二个具有相同格式的表(即 tblCustomer 和 tblCustomer_History) - 加上一个日期列。

每当进行编辑时,您都会将旧记录与日期/时间一起插入历史记录表。这很容易做到,只需要很少的代码更改(通常只是一个触发器)

这样做的好处是使您的“真实”表尽可能小,但可以为您提供所有更改的完整历史记录。

但是,最终取决于您希望如何使用这些数据。如果仅用于审计目的,则此方法很简单,除了额外的磁盘空间之外几乎没有缺点,并且对您的主系统影响很小或没有影响。

于 2012-12-04T19:43:25.310 回答
14

您应该定义您感兴趣的效率类型:您可以具有存储空间效率,记录历史所需的工作效率(交易成本),或以特定方式查询记录历史的时间效率.

我注意到您在建议的历史表中有一个表名,这意味着打算记录多个表的历史,这将排除在您的历史表中存储记录的精确副本的选项,除非所有表您正在跟踪的将始终具有相同的结构。

如果您分别处理列,即每个历史记录只记录一个列值,则必须设计一种能够准确表示您将遇到的每个列值的多态数据类型。

如果存储空间的效率是您主要关心的问题,那么我会将历史记录分成多个表。这意味着将新的列值表链接到编辑事件表和列定义表。编辑事件表将记录用户和时间戳,列定义表将记录表、列和数据类型。正如@njk 所指出的,您不需要旧的列值,因为您始终可以查询以前的编辑以获取旧值。这种方法有望节省空间的主要原因是假设,一般来说,用户将编辑可用字段的一小部分。

如果查询效率是您主要关心的问题,我将为您正在跟踪的每个表设置一个历史表,并为每个历史表添加一个用户和时间戳字段。这在编辑的交易成本方面也应该是有效的。

于 2012-12-04T19:26:53.190 回答
4

您不需要在历史表中记录新旧值。只需记录最新的值、作者和日期。然后,您可以根据记录的日期获取一些最近user_id的记录。如果您要处理大量数据,这可能不是最好的方法。

用户(id,user_id,日期时间,作者,...)

样本数据

id user_id datetime author user_title user_name user_tele ...
1 1 2012-11-05 11:05 鲍勃
2 1 2012-11-07 14:54 蒂姆
3 1 2012-11-12 10:18 鲍勃
于 2012-12-04T19:06:56.170 回答