Я пытаюсь найти подход для проекта, где пользователь может редактировать записи и иметь возможность видеть прошлые версии этих записей. Вот упрощенная схема примера с использованием списка:
TABLE list (
id int auto_increment primary key,
user_id int,
title varchar(255)
);
TABLE list_tasks (
id int auto_increment primary key,
list_id int,
title varchar(255),
order int,
is_complete tinyint
);
Таким образом, пользователь может войти и внести несколько изменений в список (например, добавить или удалить задачи, изменить порядок задач, отметить некоторые выполненные, переименовать некоторые и т. Д.), А затем сохранить их. На этом этапе я хотел бы создать «версию 2» списка и задач, чтобы они могли просматривать предыдущие версии, но когда они получают доступ к списку, всегда получают последнюю версию.
Существует ли общий подход / шаблон проектирования для работы с данными контроля версий таким образом в базе данных MySQL?
mysql
versioning
GSto
источник
источник
Ответы:
Довольно часто хочется сделать это в БД. Несмотря на то, что вы вносите в него изменения, вы хотите отслеживать изменения для списка элементов.
Одним из способов сделать это может быть изменение структуры, такой как
Когда пользователь сохранит свой список, создайте новую ревизию в
revisions
таблице выше и присвойте это значение элементам списка в,list_tasks
а затем идентификатору ревизии в,lists
чтобы пометить этот идентификатор как «текущую» ревизию. Когда пользователь редактирует элементы, не редактируйте существующие элементы, а вставляйте новые с новым идентификатором ревизии и обновляйтеlist
таблицу этой ревизией, чтобы пометить ее как текущую.Затем для отображения текущих элементов перечислите элементы с идентификатором текущей ревизии, указанным в
lists
таблице. Для просмотра предыдущих версий вы можете получить список предыдущих ревизий списков из таблицы ревизий, а затем перечислить отдельные элементы на основе этого идентификатора.источник
В этом решении используется отдельная таблица аудита. Есть плюсы и минусы. Вы можете предпочесть удалить старые записи из вашей основной таблицы. Улучшение производительности может быть незначительным.
Добавьте следующие поля в каждую проверяемую таблицу:
Вам нужно будет обновлять эти поля каждый раз при изменении данных. CurrentVersion увеличивается на 1 (его можно использовать для блокировки записи, но это уже другой вопрос). IsDeleted обеспечивает «мягкое удаление», поэтому на него можно ссылаться в будущем.
Отдельные таблицы аудита Каждая таблица должна иметь соответствующую версию таблицы _Archive или _History. Это, вероятно, не нужно индексировать таким же образом. Очевидно, что одно поле первичного ключа не будет применяться. Вы должны быть в состоянии сделать составной ключ из поля идентификатора и UpdateDateTime.
Использование триггера (Это будет учитывать изменения, сделанные внутри или вне вашего кода. Вы можете решить, подходит ли это для вашей ситуации.) Или другое кодирование: когда запись добавляется, обновляется или удаляется, копия записи помещается в архив Таблица истории. Все версии и другие поля аудита сохраняются. Это скажет вам, что пользователи сделали и когда. Таблицу можно сравнить с самой собой, чтобы увидеть, когда была изменена запись, или увидеть тенденции.
Я хорошо видел эту работу за последние несколько лет. Я хотел бы услышать о недостатках, которые я, возможно, не рассматриваю.
источник
Я бы посоветовал вам прочитать эту подробную статью.
https://blog.jondh.me.uk/2011/11/relational-database-versioning-strategies/comment-page-1/#comment-373850
Другой подход состоит в том, чтобы иметь столбец version_id в вашей таблице и флаг «current», который указывает, какая строка является текущей. Каждый раз, когда вам нужно обновление, вы можете вставить новую строку и установить для текущей версии флаг 'current' в значение 0 / false, а для новой добавленной строки - 1.
Таким образом, вы можете создать представление, отображающее только те, у которых установлен текущий флаг.
источник