2010-12-11 7 views
6

私はかなり一般的な設計上の問題があります。Google App Engineのレコードの履歴ログ(監査証跡)を実装する必要があります。履歴ログは構造化されていなければなりません。つまり、すべての変更を自由形式のテキストに結合して文字列フィールドに格納することはできません。Google App Engineのレコード変更の効率的な監査証跡の実装 - デザインパターン

ヒストリモデルには次のオプションがあると考えています。オプション#1のパフォーマンスの問題に気づいた後、オプション#3を実装することにしました。しかし、このソリューションが効率的でスケーラブルであれば、疑問を感じることがあります。たとえば、オプション#3のダイナミックプロパティの数が増えるとパフォーマンスが大幅に低下するリスクはありますか?

各オプションの賛否両論について深い知識を持っているのですか、Google App EngineのDB特性に適用できる他の監査証跡デザインパターンを提案できますか?

  1. 使用古典的なSQL「マスター・ディテール」関係
    • 賛否 SQL背景
    • クリーンでデータベース開発者のために理解するのは簡単
      • :直接履歴レコードの定義とその性質
      • 検索パフォーマンス:履歴による簡単な検索(インデックスを使用できる)
      • トラブルシューティング:管理ツール(_ah/admin)による簡単なアクセス
    • 短所
      • 1対多の関係は、多くの場合、GAE DB
      • にこの方法を実施することが推奨されていませんが、パフォーマンスをお読みください。レコードの過剰な数は、例えば、長い監査証跡を表示するための操作を読んで大きなレコードリストの詳細ペインに表示されます。 BLOBフィールドに
  2. ストア履歴(漬けのpython構造)
    • 賛否
      • 実装がシンプルで柔軟な
      • 読み取り性能:非常に効率的
    • 短所
      • クエリのパフォーマンス:インデックス
      • トラブルシューティングを使用して検索することはできません。汚れた管理DBビューア(_ah /管理者)
      • でデータを検査することはできません:SQL開発者のために受け入れる/理解することはそう簡単ではない(彼らはこれは醜い考える)
  3. Expandoの動的プロパティに履歴を保存します。例えば。フィールドごとにfieldNamehistory_fieldName_nフィールドを作成します(n = <)。N>
    • 賛成論)履歴レコードの数です:トラブルシューティング
    • を実施し、理解するのは簡単 :
      • 簡単な1回の読み出し動作:
      • 読み取りパフォーマンス管理インターフェイスを介してすべての履歴プロパティを読み取ることができますレコードを取得
    • 短所:
      • 検索パフォーマンス:単純に履歴レコードを検索することはできません(彼らは肝炎E別の名前)
      • すぎないクリーン:プロパティの数は、メインのレコードのリストフィールドのいくつかのセットで
  4. ストアの歴史を見て最初は混乱を招くことがあります。例えば。
  5. 読み取り性能SQL開発者のためのわかりやすい:
    • クリーン:歴史のプロパティを直接定義
    • シンプル各fieldNameためfieldName_historyリストフィールド
      • 賛否を作成するレコードを取得するために、1回の読み出し動作
    • 短所:
      • 検索性能:インデックスを用いて検索することができ、O何らかの価値があり、特定の時間に値の組み合わせを持つレコードを検索することができないレコードの場合はnlyです。
      • トラブルシューティング:私はオプション1.読み取りのために行くだろう選択しなければならない場合はリストを検査することは、管理DBビューア

答えて

3

に困難である(以上ない場合)としてのためにパフォーマンスしていますその他のオプション。また、他のすべてのオプションは、特定の状況(小さな変更または非常に大きな変更のセット)で速度の優位性しか持たない。また、x日後に履歴をパージしたり、さまざまなモデルタイプ間でクエリの履歴を作成したりできるような柔軟性(さらに簡単に)を得ることができます。一貫性を保証するために、変更されたエンティティの子として履歴エンティティを作成してください。あなたはこれらのいずれかで終わることができます:

class HistoryEventFieldLevel(db.Model): 
    # parent, you don't have to define this 
    date = db.DateTime() 
    model = db.StringProperty() 
    property = db.StringProperty() # Name of changed property 
    action = db.EnumProperty(['insert', 'update', 'delete']) 
    old = db.PickleProperty() # Old value for field, empty on insert 
    new = db.PickleProperty() # New value for field, empty on delete 

class HistoryEventModelLevel(db.Model): 
    # parent, you don't have to define this 
    date = db.DateTime() 
    model = db.StringProperty() 
    action = db.EnumProperty(['insert', 'update', 'delete']) 
    change = db.PickleProperty() # Dictionary with changed fields as keys and tuples (old value, new value) as values 
関連する問題