数据库结构跟踪变更历史

时间:2020-03-06 14:48:18  来源:igfitidea点击:

作为个人项目,我正在为项目管理系统进行数据库设计,但遇到了麻烦。

我想实现一个票务系统,并且希望票证看起来像Trac中的票证。我将使用什么结构来复制该系统? (我在任何系统上安装trac都没有成功,所以我真的看不到它在做什么)

注意:我对尝试以任何版本存储或者显示票证都不感兴趣。我只需要更改历史即可。我不想存储额外的数据。另外,我已经在文本字段中使用序列化数组实现了这样的功能。我不想再将其作为解决方案来实现。

编辑:我只在寻找数据库结构。触发器/回调不是真正的问题。

解决方案

我想说,创建一种事件侦听类,每次在系统中发生任何事情时都对它们进行ping操作,并将事件的描述放入数据库中。

它应该存储基本的谁/什么/位置/时间/什么信息。

对该项目事件表进行排序应该可以为我们提供所需的信息。

我们是否在追求这样的数据库机制?

CREATE OR REPLACE TRIGGER history$yourTable
        BEFORE UPDATE ON yourTable
        FOR EACH ROW
        BEGIN
            INSERT INTO
                history
            VALUES
                (
                :old.field1,
                :old.field2,
                :old.field3,
                :old.field4,
                :old.field5,
                :old.field6
                );
        END;
    /
    SHOW ERRORS TRIGGER history$yourTable

我使用"瘦"设计实现了纯记录更改数据:

RecordID  Table  Column  OldValue  NewValue
--------  -----  ------  --------  --------

我们可能不希望使用"表"和"列",而是使用"对象"和"属性",依此类推,具体取决于设计。

这具有灵活性和简单性的优点,但以查询速度为代价-"表"和"列"列上的聚集索引可以加快查询和过滤器的速度。但是,如果我们要经常在表或者对象级别上在线查看更改日志,则可能需要设计一些更扁平的东西。

编辑:几个人正确地指出,使用此解决方案无法将变更集组合在一起。我在上表中忘记了这一点-我使用的实现还有一个带有日期时间,用户和其他信息以及" TransactionID"列的" Transaction"表,因此设计如下所示:

CHANGE LOG TABLE:
RecordID  Table  Column  OldValue  NewValue  TransactionID
--------  -----  ------  --------  --------  -------------

TRANSACTION LOG TABLE:
TransactionID  UserID  TransactionDate
-------------  ------  ---------------

一种可能的解决方案是,与进行更改的用户一起在历史记录表中存储票证的副本。

但是,这将存储大量额外数据,并且需要大量处理才能创建Trac显示的视图。

至于不存储大量额外数据,我想不出任何好的方法来做到这一点。我们必须存储每个修订版才能看到更改。

这是我见过的一种解决方案,尽管我不确定这是否是最好的解决方案。有一个主键,比如说" id",它指向一个特定的修订版。也有ticket_numberrevision_date字段。修改票证时,ticket_number不会更改,但是idrevision_date会更改。然后,根据上下文,我们可以使用groupwise max获得特定修订或者特定票证的最新修订。

我做了这样的事情。我有一个名为LoggableEntity的表,其中包含:ID(PK)。

然后,我有了EntityLog表,其中包含有关对可登录性(记录)进行更改的信息:ID(PK),EntityID(从FK到LoggableEntity.ID),ChangedBy(进行更改的用户名),ChangedAt(更改发生时的smalldatetime),类型(枚举:创建,删除,更新),详细信息(包含更改内容的备注字段可能是带有序列化详细信息的XML)。

现在,我要跟踪的每个表(实体)都是从LoggableEntity表中"派生"的,这意味着例如客户将FK转换为LoggableEntity表。

现在,每次对客户记录进行更改时,我的DAL代码都会处理EntityLog表的填充。每当看到实体类是可登录实体时,就会将新的更改记录添加到实体日志表中。

所以这是我的表结构:

+------------------+           +------------------+
| LoggableEntity   |           | EntityLog        |
| ---------------- |           | ---------------- |
| (PK) ID          | <--+      | (PK) ID          |
+------------------+    +----- | (FK) LoggableID  |
        ^                      |      ...         |
        |                      +------------------+
+------------------+
| Customer         |
| ---------------- |
| (PK) ID          |
| (FK) LoggableID  |
|      ...         |
+------------------+