Как сохранить историю обновлений записей в MySQL? - PullRequest
22 голосов
/ 29 марта 2010

Мне нужно создать код на PHP, который позволит мне вести историю обновлений записей в базе данных MySQL, чтобы я мог найти по дате старую ревизию.

Вот пример того, чего я действительно хочу достичь: http://en.wikipedia.org/w/index.php?title=Tunisia&action=history

Данные в основном представляют собой числа, которые мы записываем о компании для составления отчетов и извлечения индексов.

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

Ответы [ 6 ]

17 голосов
/ 29 марта 2010

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

Проверьте http://dev.mysql.com/doc/refman/5.1/en/triggers.html для получения дополнительной информации.

9 голосов
/ 29 марта 2010

Один простой способ сохранить историю версий - создать в основном идентичную таблицу (например, с суффиксом _version). Обе таблицы будут иметь поле версии, которое для основной таблицы вы увеличиваете при каждом обновлении, которое вы делаете. Таблица версий будет иметь составной первичный ключ на (id, version).

Всякий раз, когда вы обновляете фактическую таблицу, вы также ВСТАВЛЯЕТЕ новую строку в таблице версий с дублирующимися данными. Всякий раз, когда вы хотите найти историю версий, все, что вам нужно сделать, это что-то вроде SELECT * FROM content_version WHERE id = CONTENT_ID ORDER BY version.

Если вы используете что-то вроде Doctrine ORM, у него есть поведение, которое делает это для вас автоматически через прослушиватели событий. Вы можете проверить это здесь: http://www.doctrine -project.org / Documentation / manual / 1_2 / en / Practizations # core-поведенцев: версия

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

Существует платформа с открытым исходным кодом (лицензия MIT) для создания веб-приложений на основе баз данных типа CRM и ERP. Вы можете загрузить EPESI с http://epe.si/, который также доступен на SourceFroge: http://sourceforge.net/projects/epesi/

Механизм CRES компании EPESI - Браузер записей - имеет очень эффективную историю записей, а также другие функции, такие как расширенная система разрешений (вплоть до уровня поля) и многое другое.

Один набор записей хранит данные в 10 таблицах и не зависит от базы данных (использует PHPAdoDB). Таблица с именем recordset_data хранит «необработанные» данные, а история изменений хранится в 2 дополнительных таблицах: recordset_edit_history и recordset_edit_history_data .

История редактирования записи имеет следующую структуру:

  • ID (первичный ключ для этой таблицы, индекс)
  • Отредактировано (отметка времени: 2008-05-14 15:18:15)
  • Отредактировано: (идентификатор пользователя)

Запись edit_history_data имеет следующую структуру:

  • edit_id = ID из истории редактирования
  • field = название поля, которое было изменено
  • old_value = значение поля, которое изменилось.

Это очень быстрый и эффективный механизм, в котором хранятся изменения не в записи, а на уровне одного поля.

2 голосов
/ 29 марта 2010

Вы должны использовать дополнительный слой между вашим приложением и БД. Вы можете сделать очень простое самостоятельно (вместо прямого вызова mysql_query вы вызываете созданную вами функцию, которая оборачивает ее и отслеживает обновления), или используете какой-то существующий ORM. В псевдокоде

my_mysql_query($query){
    if($query is an update){
        //Log stuff before query
    }
    $r = mysql_query($query);

    if ($r && $query is an update){
        //Log stuff after query
    }
    return $r;
}

И тогда в вашем приложении вы звоните my_mysql_query вместо mysql_query. Вы можете проверить, является ли таблица той, которую вы хотите отслеживать, и вы можете скопировать строку в копию исходной таблицы.

Если вы используете Doctrine ORM , вы можете использовать прослушивателей событий , чтобы получить то, что вы хотите.

1 голос
/ 29 марта 2010

Если я правильно понимаю, вы сохраняете только «число» в определенной таблице и хотите, чтобы история изменений этого номера?

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

Простой способ сделать это, имея таблицу со следующими полями:

  • ID
  • CompanyID
  • номер
  • Отметка времени

Если вы хотите узнать текущий номер, просто наберите

SELECT * FROM table WHERE companyId = X ORDER BY timestamp DESC LIMIT 1

Если вы хотите увидеть все ревизии, просто сделайте:

SELECT * FROM table WHERE companyId = X
1 голос
/ 29 марта 2010

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

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

! created file
* added data to cell D4 'product descript' D5 'set of pens' E5 '£5.99'
* added data to cell D6 'toaster' E5 '£10'
& changed data in cell D4 'Product Description'

Каждое из этих изменений должно быть сохранено с отметкой времени или когда они были сделаны. Вам также нужно будет разработать собственную схему хранения изменений в данных.

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

...