2つの異なるデータベース間でデータを同期する最良の方法


24

構造がまったく異なる2つの大きなデータベース間でデータ同期を実装する必要があります。基本的に、最初のデータベースのさまざまなテーブルにある製品に関するデータを収集し、2番目のデータベースの他のテーブルに再配置する必要があります。

初めて製品を作成することはそれほど複雑ではありません。しかし、私はすべてのデータではなく、各製品に関する特定のデータを更新する方法を探しています。

明らかに、これを難しくするいくつかの問題があります。

  • 選択クエリを除いて、ソースデータベースで何もすることはできません。
  • ターゲットデータベースでは、通常のクエリ(選択、更新、挿入、作成)を実行できますが、既存の構造/テーブルを変更することはできません。
  • ターゲットとソースDBは完全に異なる構造を持ち、テーブルはまったく同じではないため、データを実際に再配置する必要があります-テーブルの比較は機能しません。
  • ターゲットデータベースはMySQLサーバーを使用します。ソースはDB2である場合があります。
  • どこにも「更新時間」フィールドはありません。

そのため、プロセス全体を1つのPython(理想的には)スクリプトで実行する必要があります。

ターゲットデータベースで更新するフィールドに基づいて、各製品のハッシュを作成することを検討します:md5(code + description + supplier +約10の他のフィールド)。同じデータに基づく新しいハッシュが、ソースデータベースから毎日作成されます。パフォーマンスのために、すべてのハッシュを単一のテーブル(項目コード、current_hash、old_hash)に保存します。次に、新しいハッシュが古いハッシュと異なる場合、製品を比較して更新します。

約50万の製品があるので、パフォーマンスが少し心配です。

それは良い方法ですか?


2
彼らも目隠しをしてほしいですか?...今私の問題だということ
キャプテンハイパー

1
@Neow、どうだった?今すぐアドバイスできますか?
エドウィンエヴァンス

4
@EdwinEvans基本的に私は最初のアイデアに留まりましたが、特に制約があったためです。私のスクリプトは、すべてのアイテムのキーデータに基づいてmd5ハッシュを作成します。次に、以前のハッシュと比較します。ハッシュが異なる場合、アイテムのすべてのデータをロードし、すべてを更新します。これが最善の方法かどうかはわかりませんが、夜間に実行され、パフォーマンスはまともです。
ネウ

回答:


9

これは私が過去数年間やってきたこと、または生計を立てていることであり、私の直感は、ソースデータベースから500,000アイテムを読み取り、宛先で同期するのに、考えられるほど時間がかからないことです。 「キー」フィールドの読み取り、MD5ハッシュの計算、およびテーブルとのクロスチェックにかかる時間は、変更されていないアイテムの同期を回避するため、時間を節約できず、実行時間も長くなります。私は単にすべてを読み、すべてを更新したいと思います。その結果、実行時間が長すぎる場合、ETLをマルチスレッド化してランタイムを圧縮します。各スレッドはテーブルのセグメントでのみ動作しますが、並行して動作します。

宛先データベースに主キーインデックスまたは一意のインデックスがあることを確認することが重要です。そうしないと、各更新/挿入によってテーブル全体がロックされる可能性があります。これは、マルチスレッドアプローチを採用している場合は悪いことですが、ジョブが宛先DBテーブルをロックし、そのDBの上にあるアプリケーションに干渉する可能性があるため、シングルスレッドのままであっても重要です。

ソースDBは「DB2である可能性がある」と言います。「可能性がある」と言うとき、それはDBがまだ設計/計画されていることを意味しますか?DB2 9以降には、最終更新時刻の追跡機能が組み込まれており、特定の時点以降に変更されたアイテムのみを照会および取得する機能があります。おそらくこれが、DBが最終更新時刻を示す列を持たないように設計された理由です。たとえば:

SELECT * FROM T1 WHERE ROW CHANGE TIMESTAMP FOR TAB t1 > current timestamp - 1 hours;

上記のクエリのタイムスタンプのカットオフは、同期が実行された最後のタイムスタンプになります。

この場合、問題は解決するはずです。ただし、ソリューションは最終的にDB2に非常に緊密に結び付けられることになり、将来は別のDBプラットフォームに移行して、同期ジョブを再検討する必要がなくなる可能性があります。そのため、製品がDB2に依存していることをすべての適切な人々が知っていることを確認するか、移行を計画している場合、「最終変更タイムスタンプ」列を持つようにDBを再構築することが含まれます。そのフィールドに入力するためにアプリレベルで必要な変更。


mysqlにも同様のソリューションがありますか?
ファーディン・ベーボウディ

5

何らかの種類のデルタ識別子またはフラグに基づいてデータ同期を行うことができれば、データ同期ははるかに高速で高速です。基本的に、ソースデータベースと同期していない場合にのみ、ターゲットデータベースのデータ行を更新する必要があります。

SQLサーバーdbでは、Checksum fnの助けを借りて、デルタベースの識別子を作成することもできます。

このSQLロジックを起動するには、昼夜の特定の時間に呼び出されるSQLベースのジョブを開発する必要があります。dbの使用量が非常に少ない場合は、夜間のSQLジョブとして実行することをお勧めします。ソースとターゲットのdbレコードのデルタが一致しない場合、それらのレコードのみをプルします。ただし、デメリットは、ソースデータ行のチェックサムを毎回計算し、ターゲットデータと比較することです。

ソースdbテーブルに「LastModifiedDate」のような列がある場合、チェックサムアプローチをスキップできます。この方法では、評価は日付ベースの列で実行され、チェックサムアプローチと比較して時間がかかりません。


感謝しますが、ソリューションが機能するかどうかはわかりません。「問題」の部分で編集内容を確認してください。

ソースデータベースには更新された時間フィールドがないため、チェックサムまたはハッシュに基づいて修飾されたデータ行をプルする必要があります。
カラン

ソースがdb2であるため。どのようにデータをそこから引き出すつもりですか?一部のWebサービスまたはAPIを介して.-
カラン

dsnは、odbcドライバーを使用してセットアップされています。Pythonのpyodbcを使用して接続し、クエリを実行できます。
ネウ

PyODBCと呼ばれるツールを使用してリモートDBにクエリを実行できるため、これは良いことです。もう1つできます。製品データを、チェックや検証なしで、ターゲットDBの新しい「ステージングテーブル」にそのままの形式で直接取り込むことができます。このようにして、ステージテーブルの下にあるターゲットdbのライブショットをシングルショットで取得します。その後、2番目のステップで、チェックサム操作を実行し、ターゲットのトランザクションテーブルデータを更新できます。これにより、リアルタイムでソースdbデータを使用したハッシュまたはチェックサム評価ができなくなります。
カラン

1

ハッシュを使用することをお勧めします。この場合、セキュリティは目標ではないため、高速なハッシュ関数を選択してください(md5で十分です)。

ハッシュ計算を複数のスレッド/プロセスに分割する予定がない限り、現在のハッシュ値をデータベースに保存する必要はありません。プロセスが単一のスクリプトである場合、現在のハッシュがメモリに保持され、新しいデータベースのデータを更新した後、古いハッシュとしてデータベースに書き込みます。


-1

いつでも特定の時間に実行されるWindowsサービスを作成する必要があります。このサービスは、ソースデータベースで変更を検出し、その変更を宛先データベースに挿入します。


-1(実際にはダウン投票しませんでしたが、;)Windowsのみの提案。ソフトウェアを開発する際に特定のアーキテクチャに依存しないようにしましょう。それは、ほんの数人だけがあなたのものを使用できることを意味します。唯一の定数が変更であるので、それはあなた自身のために、ユーザーのために維持するために簡単なものを作る程度の任意の特定のプラットフォームに依存しない方が良いです
pythonian29033

1
@manish kumarの「ソースデータベースの変更を見つける」部分が最も難しいものです!
ナルバレックス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.