SQL历史表设计

heb*_*ime 20 sql database database-design

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

示例:
向用户显示编辑记录的页面.

标题:
姓名:Joe
Tele:555-1234
DOB:1900-10-10

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

我想过用这样的表:

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

id
modifiedUser
modifiedDate
tableName
recordId
oldValue
newValue

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

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

有任何想法吗?

谢谢!

E.J*_*nan 16

我建议您为每个要跟踪历史记录的表格,使用相同格式的第二个表格(即tblCustomer和tblCustomer_History)以及日期列.

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

这样可以使您的"真实"表格尽可能小,但可以为您提供所有更改的完整历史记录.

但最终,它将归结为您希望如何使用此数据.如果仅用于审计目的,这种方法很简单,除了额外的磁盘空间以及对主系统的影响很小或没有影响外,几乎没有什么缺点.


Pau*_*ter 13

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

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

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

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

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

  • 我还想指出,许多其他表的一个审计表将成为一个锁定的痛点. (2认同)