关于数据库:SQL历史记录表设计

SQL history table design

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

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

标题:先生。
姓名:乔
电话:555-1234
DOB:1900-10-10

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

我想到使用这样的表:

历史记录-------------------

id
ModifyUser
修改日期
tableName
recordId
旧值
newValue

与此有关的一个问题是,每次编辑都会有多个条目。
我正在考虑使用另一个表将它们分组,但是您仍然遇到相同的问题。

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

有什么想法吗?

谢谢!


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

无论何时进行编辑,您都将旧记录与日期/时间一起插入到历史记录表中。这很容易做到,几乎不需要更改代码(通常只是触发器)。

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

最终,将取决于您要如何使用此数据。如果仅出于审计目的,则此方法非常简单,除了额外的磁盘空间以及对您的主系统几乎没有影响之外,几乎没有负面影响。


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

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

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

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

如果您主要关注查询效率,那么我将为要跟踪的每个表设置一个历史记录表,并向每个历史记录表添加一个用户和时间戳字段。就编辑的交易成本而言,这也应该是有效的。


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

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

样本数据

1
2
3
4
id  user_id  datetime          author  user_title  user_name  user_tele ...
1   1        2012-11-05 11:05  Bob
2   1        2012-11-07 14:54  Tim
3   1        2012-11-12 10:18  Bob