views:

2048

answers:

6

I'm working on database designs for a project management system as personal project and I've hit a snag.

I want to implement a ticket system and I want the tickets to look like the tickets in Trac. What structure would I use to replicate this system? (I have not had any success installing trac on any of my systems so I really can't see what it's doing)

Note: I'm not interesting in trying to store or display the ticket at any version. I would only need a history of changes. I don't want to store extra data. Also, I have implemented a feature like this using a serialized array in a text field. I do not want to implement that as a solution ever again.

Edit: I'm looking only for database structures. Triggers/Callbacks are not really a problem.

A: 

I'd say create some kind of event listening class that you ping every time something happens within your system & places a description of the event in a database.

It should store basic who/what/where/when/what info.

sorting through that project-events table should get you the info you want.

Pete Karl II
What does that look like as a database structure?
epochwolf
+2  A: 

Are you after a database mechanism like this?

   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
dacracot
Not really. I'm just looking at how to store the data. Not how to get the data into a table.
epochwolf
Getting the data into a table is functionally the same as storing the data. So what then are you really trying to do?
David Medinets
At work we use something very similar, we use table "history" for modifications in every table, so we keep the name of the affected table, the PK of the affected row(s) and what operation it was (INSERT, DELETE, UPDATE). In a related sub-table the name, previous value and new value of all columns.
Joe Pineda
+3  A: 

I have implemented pure record change data using a "thin" design:

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

You may not want to use "Table" and "Column", but rather "Object" and "Property", and so forth, depending on your design.

This has the advantage of flexibility and simplicity, at the cost of query speed -- clustered indexes on the "Table" and "Column" columns can speed up queries and filters. But if you are going to be viewing the change log online frequently at a Table or object level, you may want to design something flatter.

EDIT: several people have rightly pointed out that with this solution you could not pull together a change set. I forgot this in the table above -- the implementation I worked with also had a "Transaction" table with a datetime, user and other info, and a "TransactionID" column, so the design would look like this:

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

TRANSACTION LOG TABLE:
TransactionID  UserID  TransactionDate
-------------  ------  ---------------
Guy Starbuck
Thank you for your answer. The only problem with that is how would I group the changes into a single change set?
epochwolf
Could you give some examples of queries or application code you would use to construct a history based on this record change table? How would you pull up a particular revision?
Christian Oudard
Thank you, that works :)
epochwolf
A: 

One possible solution is storing a copy of the ticket in a history table with the user that made the change.

However, this will store alot of extra data and require alot of processing to create the view that Trac shows.

epochwolf
A: 

As far as not storing alot of extra data, I can't think of any good ways to do that. You have to store every revision in order to see changes.

Here is one solution I have seen, although I'm not sure if it's the best one. Have a primary key, say id which points to a particular revision. also have ticket_number and revision_date fields. ticket_number does not change when you revise a ticket, but id and revision_date do. Then, depending on the context, you can get a particular revision, or the latest revision of a particular ticket, using groupwise max.

Christian Oudard
I've seen that before. It would probably be perfect for a wiki when you are only viewing one version or comparing two versions. For my purposes much more code is required to see which things changed when as one big view.
epochwolf
+2  A: 

I did something like this. I have a table called LoggableEntity that contains: ID (PK).

Then I have EntityLog table that contains information about changes made to a loggableentity (record): ID (PK), EntityID (FK to LoggableEntity.ID), ChangedBy (username who made a change), ChangedAt (smalldatetime when the change happened), Type (enum: Create, Delete, Update), Details (memo field containing what has changed - might be an XML with serialized details).

Now every table (entity) that I want to be tracked is "derived" from the LoggableEntity table - what it means that for example Customer has FK to LoggableEntity table.

Now my DAL code takes care of populating EntityLog table everytime there is a change made to a customer record. Everytime when it sees that entity class is a loggableentity then it adds new change record into entitylog table.

So here is my table structure:

+------------------+           +------------------+
| LoggableEntity   |           | EntityLog        |
| ---------------- |           | ---------------- |
| (PK) ID          | <--+      | (PK) ID          |
+------------------+    +----- | (FK) LoggableID  |
        ^                      |      ...         |
        |                      +------------------+
+------------------+
| Customer         |
| ---------------- |
| (PK) ID          |
| (FK) LoggableID  |
|      ...         |
+------------------+
David Pokluda
did you use a tool to make the schema diagram?
David Medinets
It depends what you are talking about. When I work on something I usually use SparX Enterprise Architect (http://www.sparxsystems.com/products/ea/index.html). But if you meant to create the schema diagram for this post then no. Just pure ASCII. :-(
David Pokluda