Как спроектировать базу данных SQL с отменой повторения? - PullRequest
10 голосов
/ 26 марта 2011

Я пытаюсь выяснить, как спроектировать таблицы БД, чтобы разрешить отмену-повтор.

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

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

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

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

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

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

Спасибо за вашу помощь.

Ответы [ 3 ]

6 голосов
/ 26 марта 2011

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

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

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

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

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

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

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

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

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

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

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

4 голосов
/ 26 марта 2011

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

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

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

2 голосов
/ 26 марта 2011

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

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

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

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

...