2

我有一个“服务”表,用于详细说明我们提供的服务。需要记录的数据中有几个小的一对多关系(都具有对 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 时,也许数组也是一种有效的选择?虽然这些感觉有点脏!

谢谢。

4

2 回答 2

2

如果您的表是:

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
)

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

于 2012-06-26T14:27:35.347 回答
1

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

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

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

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

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

于 2012-06-26T18:26:03.907 回答