Ведение истории изменений страницы. Немного похоже на SO для ревизий - PullRequest
10 голосов
/ 14 августа 2010

У меня есть система CMS, которая хранит данные в разных таблицах, например:

Entries Table
+----+-------+------+--------+--------+
| id | title | text | index1 | index2 |
+----+-------+------+--------+--------+

Entries META Table
+----+----------+-------+-------+
| id | entry_id | value | param |
+----+----------+-------+-------+

Files Table
+----+----------+----------+
| id | entry_id | filename |
+----+----------+----------+

Entries-to-Tags Table
+----+----------+--------+
| id | entry_id | tag_id |
+----+----------+--------+

Tags Table
+----+-----+
| id | tag |
+----+-----+

Я пытаюсь внедрить систему ревизий, немного похожую на SO.Если бы я просто делал это для Entries Table, я планировал просто сохранить копию всех изменений в этой таблице в отдельной таблице.Поскольку я должен сделать это как минимум для 4 таблиц (таблица TAGS не должна иметь ревизии), это совсем не похоже на элегантное решение.

Как бы вы, ребята, сделали это?

Обратите внимание, что Мета-таблицы смоделированы в EAV (значение атрибута сущности) .

Заранее спасибо.

Ответы [ 3 ]

8 голосов
/ 18 августа 2010

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

взяв в качестве примера таблицу записей

Entries Table
+----+-------+------+--------+--------+
| id | title | text | index1 | index2 |
+----+-------+------+--------+--------+

становится

entries             entries_data
+----+----------+   +----------+----+--------+------+--------+--------+
| id | revision |   | revision | id |  title | text | index1 | index2 |
+----+----------+   +----------+----+--------+------+--------+--------+

на запрос

select * from entries join entries_data on entries.revision = entries_data.revision;

вместо обновления таблицы records_data вы используете оператор вставки, а затем обновляете редакцию таблицы записей новой редакцией таблицы записей.

Преимущество этой системы заключается в том, что вы можете переходить к другим ревизиям, просто изменяя свойство ревизии в таблице записей. Недостатком является необходимость обновления ваших запросов. В настоящее время я интегрирую это в слой ORM, чтобы разработчики не беспокоились о написании SQL. Еще одна идея, с которой я играю, - создать централизованную таблицу ревизий, которую используют все таблицы данных. Это позволит вам описать состояние базы данных с помощью одного номера ревизии, аналогично тому, как работают номера ревизий Subversion.

6 голосов
/ 14 августа 2010

Посмотрите на этот вопрос: Как контролировать версию записи в базе данных

Почему бы не иметь отдельную историю для каждой таблицы (согласно принятому ответу на связанный вопрос)? Он просто имеет составной первичный ключ PK исходных таблиц и номер редакции. Вам все равно нужно будет где-то хранить данные.

1 голос
/ 26 августа 2010

Для одного из наших проектов мы пошли следующим образом:

Entries Table
+----+-----------+---------+
| id | date_from | date_to |
+----+--------_--+---------+

EntryProperties Table
+----------+-----------+-------+------+--------+--------+
| entry_id | date_from | title | text | index1 | index2 |
+----------+-----------+-------+------+--------+--------+

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

SELECT 
entry_id, title, text, index1, index2
FROM
Entities INNER JOIN EntityProperties
ON Entities.id = EntityProperties.entity_id
AND Entities.date_to IS NULL
AND EntityProperties.date_to IS NULL

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

Общий недостаток любой подобной попытки очевиден - вы должны написать тонны TSQL, в которых не версионные БД будут иметь что-то вроде выберите A присоединиться B .

...