0

他のモデルに加えられた変更を記録するモデルを作成しているので、すべての属性の変更が記録されます。変更レコードテーブルを構造化するための最良の方法に関する入力を探しています。

たとえばUser、属性を持つモデルがありnameます。Changeそのユーザーの名前がからBobに変更されたときに、レコードをデータベースに保存したいと思いますTed

さらに、ユーザーUserが同時に複数の属性を更新する場合、これらを単一として記録したいと思いChangeます。たとえば、を変更すると、と属性Userの両方がそれぞれからとに変更されます。nameemailBobbob@bobsdomain.comTedted@teddy.com

変更される特定のオブジェクトの属性のセットは任意です。テーブルをどのように構成しますか?

現在、私は次のようなことをしています(簡略化):

Changes:
  user_id:integer
  changed_fields:string
  old_values:text
  new_values:text

上記の例では、これらのレコードは次のようになります。

:changed_fields => "name", 
:old_values => "Bob", 
:new_values => "Ted"

:changed_fields => "name,email", 
:old_values => "Bob,bob@bobsdomain.com", 
:new_values => "Ted,ted@teddy.com"

モデルには、Change特定のフォーマットにマップするために入力/出力を解析する特別なゲッター/セッターメソッドがあります。

この種のものをモデル化するためのより良い方法はありますか?

そうでない場合、値が任意である可能性がある場合、入力/出力の解析を最適に機能させるためにデータベースの値をフォーマットするための最良の方法は何ですか。

DBとしてPostgresを使用し、ORMとしてActiveRecordを使用しています。

4

1 に答える 1

0

古い値と新しい値の両方を保存することは冗長です。代わりに、変更時に新しい値だけを保存し、新しい行が作成されたときに変更レコードも追加するようにすることができます。行がN回変更された場合、変更テーブルにはN + 1レコードが含まれ、必要に応じてそれらの違いを遡及的に見つけることができます。

実際、1つのアプローチは、データのすべてのバージョンを含む1つのテーブルのみを持つことです。行をインプレースで更新する代わりに、新しい行を挿入して編集します。ブール値の「最新」フィールドを使用するか、別のテーブルの外部キーを使用して各行の現在のバージョンを参照するときに、このアプローチを採用しました。

最近は、django-reversionパッケージを使用して、リビジョン追跡を実装しています。単一のテーブルを使用して、追跡されたすべてのテーブルのすべてのバージョンを記録し、各バージョンでの各オブジェクトの状態のJSON表現を保存します。追加のテーブルを使用して変更セット全体を追跡するため、複数のオブジェクトにまたがる変更をバージョン管理できます。

最適なソリューションは、テーブルで効率的に実行できるようにする必要のある操作と、ORMで簡単に操作できるものによって異なります。この回答が、他の設定で機能したいくつかのアプローチを指摘するのに役立つことを願っています。

于 2012-11-13T01:44:47.637 に答える