web-dev-qa-db-ja.com

MySQLでレコード更新の履歴を保持する方法は?

PHPにコードを作成する必要があります。これにより、MySQLデータベースにレコード更新の履歴を保持できるため、古いリビジョンを日付で見つけることができます。

これが私が実際に達成したい例です: http://en.wikipedia.org/w/index.php?title=Tunisia&action=history

データは主に、レポートを生成し、インデックスを抽出するために会社について記録した数値です。

単純化のためにcodeigniterを使用する予定です。データベースの変更履歴を保持するために同じアプローチを使用するフレームワークまたはオープンソースプロジェクトについてのアイデアを探しています。

23
Proxium

(特定のニーズに応じて)最も簡単な解決策は、おそらくテーブルにon update/insert/deleteトリガーを追加することです。これにより、データが挿入/更新/削除されたときに追加のロギングを実行できます。そうすれば、データベースへの手動の介入もカバーされます...

詳細は http://dev.mysql.com/doc/refman/5.1/en/triggers.html を確認してください。

19
wimvds

バージョン履歴を保持する簡単な方法の1つは、基本的に同一のテーブルを作成することです(例:_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/behaviors#core-behaviors:versionable

11
reko_t

CRMとERPデータベース駆動型Webアプリケーションのタイプ)をビルドするためのオープンソース(MITライセンス)フレームワークがあります。ダウンロードできます[〜#〜] epesi [〜# 〜]from http://epe.si/ SourceFrogeでも利用可能: http://sourceforge.net/projects/epesi/

EPESIのCRUDエンジン-Record Browser-は、非常に効率的なレコード履歴と高度な許可システム(フィールドレベル)など。

単一のレコードセットは最大10のテーブルにデータを格納し、データベースに依存しません(PHPAdoDBを使用)。 recordset_dataと呼ばれるテーブルは「生の」データを保存し、変更の履歴はrecordset_edit_historyrecordset_edit_history_data

レコードのedit_historyの構造は次のとおりです。

  • ID(このテーブルの主キー、インデックス)
  • 編集日(タイムスタンプ:2008-05-14 15:18:15)
  • 編集:(ユーザーID)

レコードのedit_history_dataの構造は次のとおりです。

  • edit_id =編集履歴のID
  • field =変更されたフィールドの名前
  • old_value =変更されたフィールドの値。

これは非常に高速で効率的なエンジンであり、変更をレコードではなく単一のフィールドレベルで保存します。

6
jasiek

アプリケーションとデータベースの間に追加のレイヤーを使用する必要があります。自分で非常にシンプルにするか(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 Listeners を使用して必要なものを取得できます。

2
Nicolò Martini

これは実際の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'

これらの変更はそれぞれ、タイムスタンプを付けて、またはいつ行われたかを保存する必要があります。また、データへの変更を保存するための独自のスキーマを作成する必要があります。

もう1つのより簡単な解決策は、Webページで作業する意思がある場合、必要なすべての機能を提供するWikiエンジンを使用することです。あなたがそれをあなたのニーズにより良く働かせるために時間を費やす必要があるかもしれません、人々は生のウィキではなく、より完成したビューからそれを編集することができます。

1
thecoshman

私が正しく理解していれば、特定のテーブルに「番号」だけを保存していて、その番号の変更履歴が必要ですか。

その数の履歴が含まれるようにデータモデルを記述します。そのため、その数値の最新の値を記録するだけでなく、以前の値も保持します。

これを行う簡単な方法は、次のフィールドを持つテーブルを用意することです。

  • id
  • companyId
  • タイムスタンプ

現在の数を知りたい場合は、

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

すべてのリビジョンを表示したい場合は、次のようにします。

SELECT * FROM table WHERE companyId = X
1
Niels Bom