Как создать SQL-db с отменой повтора?

Я пытаюсь выяснить, как создавать таблицы БД для Undo-Redo.

Представьте, что у вас есть таблица задач со следующей структурой:

id <int>
title <varchar>
memo <string>
date_added <datetime>
date_due <datetime>

Теперь предположим, что за несколько дней и несколько входов в систему произошло несколько изменений; но пользователь хочет вернуться к одной из версий.

  • Будет ли у вас отдельная таблица, отслеживающая изменения, или - попытаетесь ли вы сохранить изменения в таблице задач (строки "призрак" из-за отсутствия лучшего термина)?
  • Вы будете отслеживать все столбцы или только те, которые меняются каждый раз?

Если это имеет значение, я использую MySQL. Кроме того, если это имеет значение, я хотел бы показать историю (ala Photoshop) и разрешить пользователю переключаться на любую версию.

Бонусный вопрос: вы сохранили бы целую ячейку memo при изменении или попытаетесь ли вы сохранить только дельта? Причина, о которой я прошу, состоит в том, что ячейка memo может быть большой, и только одно слово или символ могут быть изменены в каждой ревизии. Конечно, сохранение дельта потребует разбора, но если отскоки не ожидаются очень часто, не лучше ли экономить место, а не время обработки?

Благодарим вас за помощь.

Ответ 1

Я бы создал таблицу History для вашей таблицы задач. Такая же структура, как задачи + новое поле с именем previousId. Это будет содержать предыдущий идентификатор изменения, поэтому вы можете вернуться вперед через разные изменения (отменить/повторить).

Почему новая таблица истории? По простой причине: не перегружайте таблицу задач теми вещами, для которых она не предназначена.

Как и в пространстве, в Истории вместо Memo используйте двоичный формат и запишите содержимое текста, который вы хотите сохранить. Не пытайтесь обнаружить изменения. Вы столкнетесь с ошибкой кода, который приведет к разочарованию и впустую времени...

Оптимизация: Еще лучше, вы можете хранить только три столбца в таблице "История": 1. taskId (внешний ключ к задачам) 2. data - двоичное поле. Перед сохранением в таблице "История" создайте строку XML, содержащую только те поля, которые были изменены. 3. previousId (поможет сохранить очередь изменений и разрешить навигацию вперед и назад)

Что касается поля данных, создайте XML-строку следующим образом:

<task>
  <title>Title was changed</title>
  <date_added>2011-03-26 01:29:22<date_added>
</task>

В основном это скажет вам, что на этот раз вы изменили только заголовок и поля date_added.

После того, как строка XML будет построена, просто запишите ее, если хотите, и сохраните ее в поле данных таблицы истории.

XML также обеспечит гибкость. Если вы добавляете/удаляете поле в таблице задач, вам также не нужно обновлять таблицу "История". Таким образом, структура таблицы задач и таблицы "История" разделены, поэтому вам не нужно обновлять две таблицы каждый раз.

PS: не забудьте добавить некоторые индексы, чтобы быстро перемещаться по таблице истории. Поля для индексирования: taskId и previousId, поскольку вам понадобятся быстрые запросы к этой таблице.

Надеюсь, что это поможет.

Ответ 2

Когда я делаю подобные вещи с использованием SQL, я всегда использую вторую таблицу для истории изменений. Это предотвращает чрезмерную загрузку основной таблицы с версиями. Обоснование заключается в том, что получение текущей записи происходит почти в 100% случаев, просмотр истории и откат (отмена) очень редки.

Если у вас есть только один UNDO или история, то отслеживание в таблице, вероятно, отлично.

Если вы хотите сохранить дельта или всю ячейку, зависит от ожидаемого роста/использования. Если вам удобно создавать логику для управления дельтами, это сэкономит вам пространство. Если что-то действительно не создает новые версии, которые я бы не начинал с этого, (применяя YAGNI)

Ответ 3

Возможно, вам захочется сжать ревизии в форме дельта, но вы все равно должны иметь текущую версию для быстрого извлечения.

Однако для более старых и новых дельт требуется много обработки, если у вас нет дельта-дельта. Для более старых дельт требуется переработка каждый раз, когда что-то меняется. Таким образом, дельта обычно не дает вам много преимуществ, но имеет большую сложность.

Последнее, что я проверил, несколько лет назад, MediaWiki, программное обеспечение, находящееся за Википедией, хранит полные тексты и предоставляет некоторые средства сжатия более старые версии с gzip для экономии места и выделенной таблицы archive для удаленных версий/страниц.

На их веб-сайте есть ER-схема их макета базы данных, которая может вам пригодиться.