Я собираюсь поделиться с вами своим дизайном, и он отличается от ваших обоих дизайнов тем, что для каждого типа сущности требуется одна таблица. Я обнаружил, что лучший способ описать любой дизайн базы данных - через ERD, вот мой:
В этом примере у нас есть объект с именем employee . Таблица user содержит записи ваших пользователей, а entity и entity_revision - две таблицы, которые содержат историю изменений для всех типов сущностей, которые будут у вас в системе. Вот как работает этот дизайн:
Два поля entity_id и revision_id
Каждая сущность в вашей системе будет иметь собственный уникальный идентификатор сущности. Ваша сущность может претерпеть изменения, но ее entity_id останется прежним. Вам необходимо сохранить этот идентификатор объекта в таблице сотрудников (как внешний ключ). Вы также должны сохранить тип своей сущности в таблице сущностей (например, «сотрудник»). Теперь что касается revision_id, как видно из его названия, он отслеживает изменения вашей сущности. Лучший способ, который я нашел для этого, - использовать employee_id в качестве вашего revision_id. Это означает, что у вас будут одинаковые идентификаторы ревизий для разных типов сущностей, но для меня это не проблема (я не уверен насчет вашего случая). Единственное важное замечание: комбинация entity_id и revision_id должна быть уникальной.
Там также состояние поля в entity_revision таблице , которая указывает на состояние пересмотра. Он может иметь одно из трех состояний: latest
, obsolete
или deleted
(не полагаясь на дату пересмотра поможет вам многое , чтобы повысить свои запросы).
И последнее замечание о revision_id: я не создавал внешний ключ, соединяющий employee_id с revision_id, потому что мы не хотим изменять таблицу entity_revision для каждого типа сущности, который мы могли бы добавить в будущем.
INSERTION
Для каждого сотрудника , которого вы хотите вставить в базу данных, вы также добавите запись в entity и entity_revision . Эти последние две записи помогут вам отслеживать, кем и когда запись была вставлена в базу данных.
ОБНОВИТЬ
Каждое обновление для существующей записи о сотруднике будет реализовано как две вставки: одна в таблицу сотрудников и одна в entity_revision. Второй поможет узнать, кем и когда была обновлена запись.
УДАЛЕНИЕ
Для удаления сотрудника в entity_revision вставляется запись об удалении и завершение.
Как вы можете видеть в этом дизайне, данные никогда не изменяются или не удаляются из базы данных, и, что более важно, для каждого типа сущности требуется только одна таблица. Лично я считаю этот дизайн действительно гибким и простым в работе. Но я не уверен насчет вас, так как ваши потребности могут быть другими.
[ОБНОВИТЬ]
Имея поддержку разделов в новых версиях MySQL, я считаю, что мой дизайн также обладает одной из лучших характеристик. Можно разделить entity
таблицу с помощью type
поля, а разделить entity_revision
с помощью ее state
поля. Это значительно увеличит количество SELECT
запросов, сохраняя при этом простой и понятный дизайн.