2012-01-24 11 views
1

アプリケーションレベルのデータ同期の一般的な問題を処理するためのパターン、フレームワークまたはベストプラクティスを探しています。信頼できないデータソースからSQLテーブルへのデータ同期

もっと簡単にするために1つのテーブルだけを例にしましょう。

  • 私は製品カタログの信頼性の低いデータソースを持っています。データが時々利用できないか、不完全または不一致になることがあります。 (手動のデータ入力エラー、ETLエラーなどの問題が発生する可能性があります)

  • ライブシステムで使用中のMysqlテーブルにライブコピーがあります。ウェブサイトを考えてみましょう。

元のデータソースと「同期する」ためにmysqlテーブルを更新するときは、安全性を実装する必要があります。ここでは、安全基準があり、その溶液I示唆:彼らは一時的に=>使用データソースから消えたときに

  • 避けるには、レコードを削除boulean /日付列やアーカイブ/履歴テーブルを「削除」。変更しないでください、だけインクリメントする必要があり、

  • 整合性の問題のためのチェック=>(標準問題、アプローチを議論していない点)

  • :一貫性のない変更は=>のような列ごとにルールを設定するための

  • チェック

    最後の同期をロールバックする機能=>履歴テーブルから復元しますか?バージョンのinc/dateカラムを使用しますか?

私が探しているのは、このような問題を処理するためのベストプラクティスとパターン/ツールです。もしあなたが解決策を指していないのであれば、どの専門分野を探求するかというキーワードの提案に感謝します。

答えて

1

ウェブアナリティクスプロバイダからデータをインポートする際にも同じ問題があります。これらはカタログと同じ問題があります。これは、私たちがやったことです:

  • すべてのインポート/同期が固有のID(AUTO_INCREMENTのint64型)が割り当てられ
  • すべてのテーブルに、元と同じですが、「superseded_idを」追加の列を持っている履歴テーブルを有しています
  • すべてのUPDATEは、変更する前に履歴テーブルに行をコピーします。
  • すべてのDELETEが移動します(すべてのUPDATEが変更されます)。履歴表の行

これは非常に簡単にロールバックを行います

  • は、パフォーマンスに問題がある悪いインポートデータベースについて
  • REPLACE INTO main_table SELECT <everything but superseded_id> FROM history table WHERE superseded_id=<bad import id>
  • DELETE FROM history_table WHERE superseded_id>=<bad import id>

のimport_idを調べ、我々はでこれを行います2番目のデータベースを別のサーバーに置いて、見つかったと思われるメインテーブルを本番データベースに新しいテーブルmain_table_$idにコピーします。$ idは最も高いインポートIDでmain_tabl e SELECT * FROM main_table_$someidへの自明なビューです。今度はビューをSELECT * FROM main_table_$newidに再定義することで、テーブルをアトミックにスウィープすることができます。

+0

は、ロールバックの問題のアプローチに完全に同意します。 –

+0

一部のレコードでデータの整合性に問題がありますか? –

+1

更新/挿入を実行する前に、不正な行(不正な日付、負の数値など)が除外されます(一部のケースでは完全インポートが拒否されます)。たとえば、制約違反、これはかなり頻繁に起こります。その後、完全インポートを拒否します。 –

-1

私はこのすべてに単一の解決策を認識していません。おそらくそれぞれのプロジェクトが非常に異なるからです。

埋め込みバージョンと妥当性の概念これはに頼ることなく、時間をかけて変化に対応するための方法です

データモデルに:しかし、ここで私は過去に使用した2つの技術があります履歴テーブル。それはあなたのクエリを複雑にするので、あなたは控えめにそれを使うべきです。たとえば、代わりにこのモデルでは

PRODUCTS 
Product_ID primary key 
Price 
Description 
AvailableFlag 

、あなたが製品を削除したい場合は、あなたが"delete from product where product_id = ..."を実行し、次のように製品のテーブルを持っていることの

。修正価格はバージョン管理モデルで"update products set price = 1 where product_id = ...."

だろう、あなたが持っている:

PRODUCTS 
product_ID primary key 
valid_from datetime 
valid_until datetime 
deleted_flag 
Price 
Description 
AvailableFlag 

をこのモデルでは、製品を削除すると、update products set valid_until = getdate() where product_id = xxx and valid_until is nullにあなたを必要とし、「=真deleted_flag」で新しい行を挿入します。

価格の変更も同様です。

これは、「ダーティ」データに対してクエリを実行し、誤ってインポートに失敗したアイテムを削除する心配なしにこのテーブルに挿入できることを意味します。また、時間の経過とともにレコードの進化を確認し、簡単にロールバックすることもできます。

は、累積値、あなたが「在庫品の数」のようなものを持っている

ための台帳のようなメカニズムを使用し、それはあなたからの電流量を取るのではなく、量を変更するためのトランザクションを作成するのに役立ちますデータフィード。たとえば、代わりにあなたの製品のテーブルの上にamount_in_stock列を持っていることの

は、「product_stock_transaction」テーブルがあります:1月2日に

product_stock_transactions 
product_id FK  transaction_date  transaction_quantity transaction_source 
1     1 Jan 2012    100     product_feed 
1     2 Jan 2012    -3     stock_adjust_feed 
1     3 Jan 2012    10     product_feed 

を、在庫量は97でした。

このデザインでは、調整とソースを追跡でき、複数のソースからデータを移動するときの管理が簡単です。

どちらのアプローチでも、インポート数とデータ量に応じて大量のデータが作成され、比較的単純なデータセットを取得する複雑なクエリが発生する可能性があります。

パフォーマンス上の懸案事項を前もって計画するのは難しいです。大量のデータを扱う「履歴」と「元帳」の両方が見られることがあります。しかし、Eugenが下記のコメントで述べているように、余りにも大きな元帳を取得した場合は、現在のレベルを要約して古いレコードを削除(またはアーカイブ)することで元帳テーブルをクリーンアップする必要があります。

+0

申し訳ありませんが、このアプローチは信頼性の高いデータソースでのみ機能します。 私が取り組もうとしているのは全く反対です。私が間違った/壊れたデータを受け取ったとき、私はメインデータベースへの感染/感染のリスクを最小限に抑えたい。特に帳簿のようなメカニズムは、1つの不正確なインポートが合計金額を永久に損なうことを確実にします。 –

+0

残念ですが、最初はうまくいく余りにも多くの元帳のようなシステムが見られましたが、1週間後には在庫が不足して1.000.000行を追加する必要があります。 –

+0

はい、方法はありません最初にデータベースに不正なデータを受け入れると、データが破損するのを防ぐことができます。しかし、最初にデータを検証する方法があると仮定すると、元帳は明らかな異常を追跡することができます。つまり、2012年1月1日に株価全体を消去し、追加のトランザクションを作成して修正します。これは、少なくともあなたに組み込みの監査と履歴を与えます。 –

関連する問題