Структура базы данных для отслеживания истории изменений
Я работаю над проектами баз данных для системы управления проектами в качестве личного проекта, и я попал в загвоздку.
Я хочу реализовать систему билетов, и я хочу, чтобы билеты выглядели как билеты в Trac. Какую структуру я использую для репликации этой системы? (У меня не было успеха в установке trac на любой из моих систем, поэтому я действительно не вижу, что он делает)
Примечание: мне не интересно пытаться хранить или отображать билет в любом случае версия. Мне нужна только история изменений. Я не хочу хранить лишние данные. Кроме того, я реализовал такую функцию, используя сериализованный массив в текстовом поле. Я не хочу снова реализовывать это как решение.
Edit: я ищу только структуры базы данных. Триггеры / обратные вызовы на самом деле не проблема.
6 ответов
я реализовал чистые данные изменения записи, используя "тонкий" дизайн:
RecordID Table Column OldValue NewValue
-------- ----- ------ -------- --------
вы можете не использовать "таблицу" и "столбец", а скорее "объект" и "свойство" и т. д., В зависимости от вашего дизайна.
это имеет преимущество гибкости и простоты, за счет скорости запроса-кластеризованные индексы в Столбцах "таблица" и "столбец" могут ускорить запросы и фильтры. Но если вы собираетесь часто просматривать журнал изменений в интернете за столом или уровень объекта, вы можете конструировать что-то более плоское.
редактировать: несколько человек справедливо отметили, что с помощью этого решения вы не можете собрать набор изменений. Я забыл об этом в таблице выше-реализация, с которой я работал, также имела таблицу " транзакция "с datetime, user и другой информацией и столбец" TransactionID", поэтому дизайн будет выглядеть так:
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, что содержит сведения об изменениях, внесенных в loggableentity (записи): удостоверение личности (ПК), значением EntityId (ФК в LoggableEntity.ИД), ChangedBy (имя пользователя, который внес изменение), ChangedAt (типа smalldatetime когда произошло изменение), типа (enum: создание, удаление, обновление), реквизиты (поля Memo, содержащим что изменилось - может быть XML с сериализованным подробная информация.)
теперь каждая таблица (сущность), которую я хочу отслеживать, является "производной" от таблицы LoggableEntity - что означает, что, например, клиент имеет FK для таблицы LoggableEntity.
теперь мой код DAL заботится о заполнении таблицы EntityLog каждый раз, когда происходит изменение записи клиента. Каждый раз, когда он видит, что класс сущности является loggableentity, он добавляет новую запись изменения в таблицу entitylog.
вот мой стол структура:
+------------------+ +------------------+
| LoggableEntity | | EntityLog |
| ---------------- | | ---------------- |
| (PK) ID | <--+ | (PK) ID |
+------------------+ +----- | (FK) LoggableID |
^ | ... |
| +------------------+
+------------------+
| Customer |
| ---------------- |
| (PK) ID |
| (FK) LoggableID |
| ... |
+------------------+
что касается не хранения большого количества дополнительных данных, я не могу придумать никаких хороших способов сделать это. Вы должны сохранить каждую ревизию, чтобы увидеть изменения.
вот одно решение, которое я видел, хотя я не уверен,что это лучший. Имейте первичный ключ, скажем id
что указывает на определенную ревизию. также есть ticket_number
и revision_date
поля. ticket_number
не меняется при пересмотре билет, но id
и revision_date
do. Затем, в зависимости от контекста, вы можете получить определенный ревизия, или последняя редакция конкретного билета, используя groupwise max.
Я бы сказал, создайте какой-то класс прослушивания событий, который вы пингуете каждый раз, когда что-то происходит в вашей системе и помещает описание события в базу данных.
Он должен хранить основную информацию who/what/where/when / what.
сортировка по этой таблице project-events должна дать вам информацию, которую вы хотите.
одним из возможных решений является хранение копии билета в таблице истории с пользователем, который внес изменения.
однако это сохранит много дополнительных данных и потребует много обработки для создания представления, которое показывает Trac.