ruby-on-rails 跟踪更改历史的数据库结构

6rqinv9w  于 2023-10-21  发布在  Ruby
关注(0)|答案(6)|浏览(123)

我正在为一个项目管理系统设计数据库,这是我的个人项目,我遇到了一个障碍。
我想实现一个票系统,我希望票看起来像tickets in Trac。我会用什么样的结构来复制这个系统?(我还没有在我的任何系统上成功安装trac,所以我真的看不到它在做什么)
注意:我对尝试在任何版本存储或显示票证不感兴趣。我只需要一个变化的历史。我不想存储额外的数据。此外,我还在文本字段中使用序列化数组实现了这样一个特性。我不想再把它作为一种解决方案。

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

t40tm48m

t40tm48m1#

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

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

您可能不想使用“表”和“列”,而是“对象”和“属性”等,这取决于您的设计。
这具有灵活性和简单性的优点,但以查询速度为代价--“Table”和“Column”列上的聚集索引可以加快查询和过滤器的速度。但是,如果您打算在表或对象级别上频繁地在线查看更改日志,则可能需要设计更扁平的东西。

编辑:有几个人正确地指出,使用这个解决方案,你不能把一个变更集放在一起。我在上表中忘记了这一点-我使用的实现也有一个“Transaction”表,其中包含日期时间,用户和其他信息,以及一个“transactionID”列,因此设计看起来像这样:

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

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

mqkwyuun2#

您是否在使用这样的数据库机制?

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
yb3bgrhw

yb3bgrhw3#

我做了这样的事。我有一个名为LoggableEntity的表,其中包含:ID(PK)。
然后我有一个logtyLog表,它包含了对loggableentity(记录)所做的更改的信息:ID(PK)、ID(FK到LoggableEntity.ID)、ChangedBy(进行更改的用户名)、ChangedAt(更改发生时的小日期时间)、Type(枚举:创建、删除、更新)、详细信息(包含已更改内容的备注字段-可能是具有序列化详细信息的XML)。
现在,我想要跟踪的每个表(实体)都是从LoggableEntity表“派生”的-这意味着例如Customer有FK到LoggableEntity表。
现在,我的DAL代码负责在每次客户记录发生更改时填充IdentyLog表。每次当它看到实体类是一个可记录的实体时,它就在实体日志表中添加新的更改记录。
这是我的表结构:

┌──────────────────┐           ┌──────────────────┐
│ LoggableEntity   │           │ EntityLog        │
│ ──────────────── │           │ ──────────────── │
│ (PK) ID          │ ◀──┐      │ (PK) ID          │
└──────────────────┘    └───── │ (FK) LoggableID  │
        ▲                      │      ...         │
        │                      └──────────────────┘
┌──────────────────┐
│ Customer         │
│ ──────────────── │
│ (PK) ID          │
│ (FK) LoggableID  │
│      ...         │
└──────────────────┘
bogh5gae

bogh5gae4#

至于不存储大量额外的数据,我想不出任何好的方法来做到这一点。你必须保存每一个版本才能看到修改。
这是我见过的一个解决方案,尽管我不确定它是否是最好的。有一个主键,比如id,它指向一个特定的版本。也有ticket_numberrevision_date字段。修改票证时,ticket_number不会更改,但idrevision_date会更改。然后,根据上下文,您可以使用groupwise max获取特定的修订版或特定票证的最新修订版。

qq24tv8q

qq24tv8q5#

我会说创建某种类型的事件侦听类,每当系统中发生某些事情时,您就ping它,并将事件的描述放入数据库中。
它应该存储基本的谁/什么/在哪里/何时/什么信息。
通过项目-事件表的排序应该可以得到你想要的信息。

yquaqz18

yquaqz186#

一个可能的解决方案是将票证的副本存储在历史表中,其中包含进行更改的用户。
然而,这将存储大量额外的数据,并需要大量的处理来创建Trac显示的视图。

相关问题