【问题标题】:How to maintain record history on table with one-to-many relationships?如何在具有一对多关系的表上维护记录历史?
【发布时间】:2012-06-26 14:12:54
【问题描述】:

我有一个“服务”表,用于详细说明我们提供的服务。需要记录的数据中有几个小的一对多关系(都具有对 service_id 的外键约束),例如:

service_owners -- user_ids responsible for delivery of service
service_tags -- e.g. IT, Records Management, Finance
customer_categories -- ENUM value
provider_categories -- ENUM value
software_used -- self-explanatory

我遇到的问题是我想保留对服务的更新历史记录,为此我在表上使用了更新触发器,该触发器执行插入到与原始列匹配的历史记录表中。但是,如果对上述数据使用标准化方法,为每个一对多关系使用单独的表和外键,则对这些表的任何更新都不会在服务历史记录中被识别。

有人有什么建议吗?似乎我需要将子密钥存储在服务表中以保持服务历史记录的完整性。分隔文本字段在这里是一种有效的方法吗?或者,当我使用 postgreSQL 时,也许数组也是一种有效的选择?不过这些感觉有点脏!

谢谢。

【问题讨论】:

  • 您的历史表不必进行规范化。为了成为真实的历史记录,它必须包含写入历史记录行时类别中的值。

标签: postgresql database-design one-to-many


【解决方案1】:

如果你的桌子是:

create table T (
    ix int identity primary key,
    val nvarchar(50)
)

你的历史表是:

create table THistory (
    ix int identity primary key,
    val nvarchar(50),
    updateType char(1), -- C=Create, U=Update or D=Delete
    updateTime datetime,
    updateUsername sysname
)

然后你只需要在所有感兴趣的表上放置一个更新触发器。然后,您可以找出任何/所有表在历史上任何时候的状态,以确定当时的关系。

【讨论】:

  • 嗨。这是我考虑过的事情,但这不是需要具有 start_date 和 end_date 列的仅插入子表吗? (然后子表的历史数据开始与活动数据一起存储,从而使表膨胀)。这绝对比服务表本身中的 ENUM 数组或 int 数组列更可取吗?谢谢。
  • 只有一个活动表和一个历史表。历史表不需要任何关系,它们只保存活动表每一行的历史副本。活动表不引用历史表。每当更新活动表时,触发器都会确保历史表获得包含新数据的新行。
  • 我认为Thistory 表中的大部分列都应该设置为NOT NULL。 (当然取决于您的用例!)
【解决方案2】:

我会尽可能避免在任何数据库中使用数组。

出于您在此处所说的确切原因,我不喜欢更新...您会丢失信息,因为它被覆盖了。我的回答很简单……不要更新。不确定您是否可以实现这一点...但如果可以的话,我建议您使用主表本身来存储历史记录(不需要第二组历史记录表)。

在主标题表中添加一个名为“活动”的列。这可以是一个字符或一个位(0 表示关闭,1 表示打开)。然后它有点触发魔法......当执行更新时,您将一行插入到表中,该行与被覆盖的记录相同,状态为“0”(或非活动),然后更新现有行(这进程保持活动记录上的 ID 列相同,新插入的记录是具有新 ID 的非活动记录。

这样就不会丢失任何数据(诚然,您存储了很多行......)并且可以通过选择 active = 0 轻松查看历史记录。

如果您正在处理已经实现的某些内容,那么这里的痛苦是......每个命中该表的现有查询都需要更新以包括对活动列的检查。如果您正在设计一个新系统,那么这个解决方案很容易实现,但如果它是一个长期存在的应用程序,那就很痛苦了。不幸的是,在您可以修改 where 子句之前,现有报告将包括关闭和打开记录(不会引发错误)

【讨论】:

    猜你喜欢
    • 2021-03-13
    • 1970-01-01
    • 2021-09-16
    • 1970-01-01
    • 2015-08-06
    • 1970-01-01
    • 1970-01-01
    • 2013-01-10
    • 1970-01-01
    相关资源
    最近更新 更多