此问题与我可以在其他一个问题中找到的架构有关here.基本上在我的数据库中,我存储用户,位置,传感器等。所有这些都可以由用户在系统中编辑,并且可以删除。
然而 - 当编辑或删除项目时,我需要存储旧数据;我需要能够在变更之前看到数据是什么。
数据库中还有不可编辑的项目,例如“读数”。他们真的更像是一个日志。读数记录在传感器上,因为它是特定传感器的读数。
如果我生成读数报告,我需要能够在阅读时看到位置或传感器的属性。
基本上我应该能够重建任何时间点的数据。
现在,我之前已经完成了这项工作,并通过在每个可编辑的表中添加以下列来使其运行良好:
valid_from
valid_to
edited_by
如果valid_to = 9999-12-31 23:59:59则那是当前记录。如果valid_to等于valid_from,则删除记录。
但是,我对我需要用来强制执行外键一致性的触发器感到满意。
我可以通过使用“PostgreSQL”数据库的扩展来避免触发器。这提供了一个名为“period”的列类型,它允许您存储两个日期之间的一段时间,然后允许您执行CHECK约束以防止重叠周期。这可能是一个答案。
我想知道是否有另一种方式。
我看到人们提到使用特殊的历史表,但我真的不喜欢几乎每1个表维护2个表的想法(虽然它可能仍然存在)。
也许我可以减少我的初始实现,不打扰检查不是“当前”的记录的一致性 - 也就是说只检查有效的数据是9999-12-31 23:59:59的记录的约束。毕竟,使用历史表的人似乎没有对这些表进行约束检查(出于同样的原因,你需要触发器)。
有没有人对此有任何想法?
PS - 标题还提到了可审计的数据库。在我之前提到的系统中,总是有edited_by字段。这允许跟踪所有更改,以便我们始终可以看到谁更改了记录。不确定可能会有多大差异。
感谢。
答案 0 :(得分:31)
答案 1 :(得分:1)
我之前也遇到过这种情况。根据您试图跟踪的数据量,这可能是令人生畏的。历史表有时易于使用,因为您可以在历史记录表中对记录进行“快照”,然后根据需要在生产表中进行更改。实现起来非常简单,但是根据您拥有的数据量和更改频率,最终可能会得到非常大的历史表。
另一种选择是记录所有允许某人“重播”发生的事情并进行跟踪的更改。每次更改都会记录到一个表或一个字段中(取决于您的需要),以跟踪谁,何时以及更改为什么,即2010年12月31日,Bob将状态从“打开”更改为“已关闭”。
您想要使用哪个系统通常取决于您以后需要如何保留/查看/使用数据。自动报告,人员审核,两者的某种组合等等。
答案 2 :(得分:0)
根据您的预算和/或环境,您可能需要考虑使用Oracle的闪回存档功能。
您可以打开表中行的自动“归档”,然后使用类似
之类的内容在基本表上运行语句SELECT * FROM important_data AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '5' DAY)
Oracle负责在单独的(阴影)表中维护历史记录。您可以对任何表执行此操作,以便您也可以使用连接执行查询。