Как сохранить историю обновлений записей в MySQL?

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

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

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

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

Ответ 1

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

Подробнее о http://dev.mysql.com/doc/refman/5.1/en/triggers.html.

Ответ 2

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

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

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

Ответ 3

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

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

Один набор записей хранит данные в целых 10 таблицах, и это агностик базы данных (использует PHPAdoDB). Таблица с именем recordset_data​​strong > хранит "необработанные" данные, а история изменений хранится в двух дополнительных таблицах: recordset_edit_history и recordset_edit_history_data​​strong > .

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

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

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

  • edit_id = ID из истории изменений
  • field = имя измененного поля
  • old_value = значение измененного поля.

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

Ответ 4

Вам нужно использовать дополнительный слой между вашим приложением и db. Вы можете сделать очень просто самостоятельно (вместо прямого вызова 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, вы можете использовать Event Слушатели, чтобы получить то, что вы хотите.

Ответ 5

Это не регистрация фактических обновлений 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'

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

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

Ответ 6

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

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

Простым способом сделать это является наличие таблицы со следующими полями:

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

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

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

Если вы хотите увидеть все изменения, выполните следующие действия:

SELECT * FROM table WHERE companyId = X