Как сохранить все версии сообщений в базе данных MySQL - PullRequest
4 голосов
/ 09 февраля 2012

Популярно сохранять все версии сообщений при редактировании (как в проектах stackexchange), так как мы можем восстановить старые версии. Интересно, как лучше сохранить все версии?

Способ 1. Сохранение всех версий в одной таблице и добавление столбца для заказа или активной версии. Это сделает таблицу слишком длинной.

Способ 2. Создание архивной таблицы для хранения более старых версий.

В обоих методах интересно, как обстоят дела с идентификатором строки, который является основным идентификатором статьи.

Ответы [ 4 ]

9 голосов
/ 09 февраля 2012

«Лучший» способ сохранить историю изменений зависит от ваших конкретных целей / ограничений - и вы их не упомянули.

Но вот некоторые соображения по поводу двух предложенных вами методов:

  • создать одну таблицу для сообщений и одну для истории сообщений, например:

    create table posts (
      id int primary key,
      userid int
    );
    
    create table posthistory (
      postid int,
      revisionid int,
      content varchar(1000),
      foreign key (postid) references posts(id),
      primary key (postid, revisionid)
    );
    

(Очевидно, будет больше столбцов, внешних ключей,и т.д.) Это просто реализовать и легко понять (и легко позволить СУБД поддерживать ссылочную целостность), но, как вы упомянули, может привести к тому, что posthistory будет иметь слишком много строк для поиска достаточно быстро.

Обратите внимание, что postid является внешним ключом в posthistory (и PK posts).

  • Используйте денормализованную схему, где все последние ревизии находятся в одной таблице, а предыдущие ревизиинаходятся в отдельной таблице.Это требует большей логики со стороны программы, то есть when I add a new version, replace the post with the same id in the post table, and also add this to the revision table.

(Это может быть то, что используют сайты SE, основываясь на дампе данных в SE Data Explorer. А может и нет, я не могу сказать.)

Для этого подхода postid также является внешним ключом в таблице posthistory и первичным ключом в posts таблица.

2 голосов
/ 09 февраля 2012

Работа с временными данными является известной проблемой.

Метод 1 просто меняет идентификатор вашей таблицы: в итоге вы получите таблицу, содержащую messageID, version, description, ... с первичным ключом messageID, version. Изменение данных выполняется простым добавлением строки с увеличенной версией. Запросы немного сложнее.

Метод 2 более утомителен, в итоге вы получите таблицу с rowID и вторую таблицу, точно такую ​​же, как в методе 1. Затем при каждом обновлении вам придется помнить о необходимости копирования данные в «резервную таблицу».

Метод 3: ответ, данный Мэттом

На мой взгляд, метод 1 и 3 лучше. Схема проще в 1, но вы можете иметь неверсированные данные для своих сообщений, используя метод 3.

2 голосов
/ 09 февраля 2012

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

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

2 голосов
/ 09 февраля 2012

На мой взгляд, интересным подходом является

  • для определения другой таблицы, например posts_archive (она будет содержать все столбцы таблицы posts + автоинкрементный первичный ключ + опциональнодата ...)
  • для подачи этой таблицы через триггеры после вставки и после обновления, определенные в таблице posts.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...