Для этого есть несколько вариантов.Вы можете иметь таблицы аудита, которые в основном отражают базовые таблицы, но также включают дату / время изменения, тип изменения и пользователя.Они могут быть обновлены через триггер.Это решение, как правило, лучше для внутреннего аудита (IMO), а не для решения специфичных для приложения требований.
Второй вариант, как вы описали.Вы можете иметь общую таблицу, которая содержит каждое отдельное изменение с кодом типа, чтобы показать, какой атрибут был изменен.Мне лично не нравится это решение, так как оно предотвращает использование проверочных ограничений для столбцов, а также может предотвращать ограничения внешнего ключа.
Третий вариант (который будет моим первоначальным выбором с предоставленной информацией) будетиметь отдельную таблицу исторических изменений, которая обновляется через приложение и включает в себя PK для каждой таблицы, а также столбцы, которые вы будете отслеживать.Он немного отличается от первого варианта тем, что приложение будет отвечать за обновление таблицы по мере необходимости.Я предпочитаю это первому варианту в вашем случае, потому что у вас действительно есть бизнес-требование, которое вы пытаетесь решить, а не внутреннее техническое требование, такое как аудит.Поместив логику в приложение, вы получаете немного больше гибкости.Может быть, некоторые изменения вы не хотите отслеживать, потому что это обновления обслуживания и т. Д.
С третьим вариантом вы можете либо иметь «текущие» данные в базовой таблице, либо каждый столбец, которыйисторически хранится только в исторической таблице.Затем вам нужно будет просмотреть последнюю строку, чтобы получить текущее состояние объекта.Я предпочитаю это, потому что это позволяет избежать проблемы дубликатов данных в вашей базе данных или необходимости искать несколько таблиц для одних и тех же данных.
Итак, вы можете иметь:
Problem_Ticket (ticket_id, ticket_name)Problem_Ticket_History (ticket_id, change_datetime, описание, комментарий, имя пользователя)
В качестве альтернативы вы можете использовать:
Problem_Ticket (ticket_id, ticket_name) Problem_Ticket_Comments (ticket_id, change_datetime, комментарий, имя пользователя) ticket_at_idchange_datetime, status_id, username)