Существует ли наилучшая практика для ведения истории в базе данных?
Я не занимаюсь работой с базами данных, поэтому часто для меня это совершенно незнакомая территория.
У меня есть таблица с кучей записей, которые пользователи могут обновлять. Тем не менее, теперь я хочу сохранить историю своих изменений на случай, если они захотят откат. Откат в этом случае - это не откат db, а более двух недель спустя, когда они поняли, что совершили ошибку. Различие в том, что я не могу совершить транзакцию, выполняю работу.
Использует ли текущая практика отдельную таблицу или просто флаг в текущей таблице?
Это небольшая база данных, 5 таблиц, каждая с < 6 столбцов, Всего 1000 строк.
Ответы
Ответ 1
Разочарованный ответ - это одно решение - другое - это таблица аудита, в которой записываются изменения, когда и кем. Это действительно вопрос подхода. Если производительность на таблицах приложений критически важна, и они могут расти массово с использованием подхода "активной строки", тогда таблица аудита лучше, так как она отделяет историю от активного материала (и я надеюсь, что исправление ошибок пользователя меньше общие, чем "нормальные" транзакции).
Ответ 2
ОТ ЭТОГО ВОПРОСА
Как сохранить историю обновлений записей в MySQL?
Один простой способ сохранить историю версий - создать в основном идентичную таблицу (например, с суффиксом _version). Обе таблицы будут иметь поле версии, которое для основной таблицы вы увеличиваете для каждого обновления, которое вы делаете. Таблица версий будет содержать составной первичный ключ (id, version).
Всякий раз, когда вы делаете обновление в фактической таблице, вы также INSERT новую строку в таблице версий с дублирующимися данными. Всякий раз, когда вы хотите найти историю версий, все, что вам нужно сделать, это что-то вроде SELECT * FROM content_version WHERE id = CONTENT_ID ORDER BY.
Если вы используете что-то вроде Doctrine ORM, у него есть поведение, которое делает это для вас автоматически через прослушиватели событий. Вы можете проверить это здесь: http://www.doctrine-project.org/documentation/manual/1_2/en/behaviors#core-behaviors:versionable
ИЛИ
Самое легкое решение (в зависимости от ваших конкретных потребностей), вероятно, должно заключаться в добавлении триггера update/insert/delete в вашу таблицу, поэтому вы можете выполнять дополнительное ведение журнала, когда данные вставлены/обновлены/удалены. Таким образом, даже ручные вмешательства на db будут покрыты...
Подробнее о http://dev.mysql.com/doc/refman/5.1/en/triggers.html.
Ответ 3
Вы можете использовать временную метку, чтобы указать, когда была создана запись, и индикатор состояния, указывающий, активна ли запись или нет.
Когда они делают обновление записи, вставьте ее копию в качестве новой записи (триггеры могут сохранять текущие отметки времени), а затем установите для старого статуса записи "Архив", а новый - "Активный". Если вы хотите, вы также можете иметь другие поля аудита, такие как "Last updated timestamp", "Date Archived", "Date Unarchived" (для откат), "Создано пользователем", "Последнее изменение пользователем",.. Если вам нужна полная история аудита, вам потребуется отдельная таблица аудита.
Откат просто выбирает версию и маркирует ее как "Активный", а остальные - "Архив".
Существуют и другие схемы, которые являются более гибкими, но также более сложными, но вам могут и не понадобиться.
Ответ 4
Один из вариантов состоит в том, чтобы все ваши таблицы содержали столбец идентификатора и столбец VersionNo. Затем вместо запуска UPDATES вы вставляете новую запись с одним и тем же идентификатором и с расширением VersionNo.
Затем вы можете создать несколько представлений для каждой таблицы, которая возвращает только последнюю версию каждого идентификатора, чтобы упростить управление запросами.
Ответ 5
Я бы рекомендовал вторую таблицу. Супер простым и простым способом было бы дублирование схемы каждой таблицы, столбца даты и времени и столбца "ModifiedByUserID", в котором будут храниться исходные данные.
Альтернативно, если пользователи не изменяют много записей в одной строке за один раз, вы можете сэкономить место и лучше просмотреть, что происходит, создав схему ниже:
ChangesTable
ChangeID
[TABLE UNIQUE ID]
UserName
Field
OldValue
NewValue
CreatedDate
Ответ 6
Как насчет такого подхода? У меня есть реляционная база данных с некоторыми таблицами и запись сборки с меткой времени в "стеке".
Например: предположим, что я создаю employee table
+ Car table
, а в третьей таблице я буду записывать отношение employee <-> car
каждый раз, когда он изменяется (с датой). Конечно, это должно поддерживаться графическим интерфейсом, из которого я могу выбрать компонент (сотрудник и автомобиль) записи, которая будет заполнять новую таблицу:
first record employee1 <-> car1 : 01/01/2013
then employee1 <-> car2: 01/06/2013
Если я хочу знать историю, я просто спрашиваю эту таблицу. Не нужно обновлять что-либо, что история катится с изменениями.