我正在将项目管理系统的数据库设计作为个人项目进行,但遇到了障碍。
我想实现一个票证系统,我希望票证看起来像Trac 中的票证。我将使用什么结构来复制这个系统?(我在我的任何系统上安装 trac 都没有成功,所以我真的看不到它在做什么)
注意:我对尝试存储或显示任何版本的票都不感兴趣。我只需要变化的历史。我不想存储额外的数据。此外,我在文本字段中使用序列化数组实现了这样的功能。我不想再将其作为解决方案实施。
编辑:我只寻找数据库结构。触发器/回调并不是真正的问题。
我正在将项目管理系统的数据库设计作为个人项目进行,但遇到了障碍。
我想实现一个票证系统,我希望票证看起来像Trac 中的票证。我将使用什么结构来复制这个系统?(我在我的任何系统上安装 trac 都没有成功,所以我真的看不到它在做什么)
注意:我对尝试存储或显示任何版本的票都不感兴趣。我只需要变化的历史。我不想存储额外的数据。此外,我在文本字段中使用序列化数组实现了这样的功能。我不想再将其作为解决方案实施。
编辑:我只寻找数据库结构。触发器/回调并不是真正的问题。
我使用“瘦”设计实现了纯记录更改数据:
RecordID Table Column OldValue NewValue
-------- ----- ------ -------- --------
根据您的设计,您可能不想使用“表”和“列”,而是使用“对象”和“属性”等等。
这具有灵活性和简单性的优点,但以查询速度为代价——“表”和“列”列上的聚集索引可以加快查询和过滤器的速度。但是,如果您要经常在线查看表或对象级别的更改日志,您可能需要设计一些更扁平的东西。
编辑:有几个人正确地指出,使用此解决方案,您无法将更改集组合在一起。我在上面的表格中忘记了这一点——我使用的实现还有一个“事务”表,其中包含日期时间、用户和其他信息,以及一个“事务 ID”列,所以设计看起来像这样:
CHANGE LOG TABLE:
RecordID Table Column OldValue NewValue TransactionID
-------- ----- ------ -------- -------- -------------
TRANSACTION LOG TABLE:
TransactionID UserID TransactionDate
------------- ------ ---------------
你追求这样的数据库机制吗?
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
我做了这样的事情。我有一个名为 LoggableEntity 的表,其中包含:ID (PK)。
然后我有 EntityLog 表,其中包含有关对可记录实体(记录)所做更改的信息:ID(PK)、EntityID(FK 到 LoggableEntity.ID)、ChangedBy(进行更改的用户名)、ChangedAt(更改发生时的小日期时间)、类型(枚举:创建、删除、更新)、详细信息(包含已更改内容的备注字段 - 可能是带有序列化详细信息的 XML)。
现在,我要跟踪的每个表(实体)都是从 LoggableEntity 表“派生”的——这意味着例如 Customer 对 LoggableEntity 表具有 FK。
现在,每次对客户记录进行更改时,我的 DAL 代码都会负责填充 EntityLog 表。每次当它看到实体类是一个可记录实体时,它就会将新的更改记录添加到实体日志表中。
所以这是我的表结构:
+------------------+ +------------------+
| LoggableEntity | | EntityLog |
| ---------------- | | ---------------- |
| (PK) ID | <--+ | (PK) ID |
+------------------+ +----- | (FK) LoggableID |
^ | ... |
| +------------------+
+------------------+
| Customer |
| ---------------- |
| (PK) ID |
| (FK) LoggableID |
| ... |
+------------------+
至于不存储大量额外数据,我想不出任何好的方法来做到这一点。您必须存储每个修订版才能查看更改。
这是我见过的一种解决方案,尽管我不确定它是否是最好的。有一个主键,说它id
指向一个特定的版本。也有ticket_number
和revision_date
领域。ticket_number
修改票证时不会更改,而是会id
更改revision_date
。然后,根据上下文,您可以使用groupwise max获取特定修订版或特定票证的最新修订版。
我会说创建某种事件侦听类,每次系统内发生某些事情时您都会 ping 并在数据库中放置对事件的描述。
它应该存储基本的 who/what/where/when/what 信息。
对该项目事件表进行排序应该可以为您提供所需的信息。
一种可能的解决方案是将票证的副本与进行更改的用户一起存储在历史表中。
但是,这将存储大量额外数据并需要大量处理来创建 Trac 显示的视图。