4

著者から毎日新しい本を手渡されると想像してみてください。本は進行中の作業です。彼は自分が何を変更または追加したかを教えてくれません。

あなたの仕事は、変更と追加を特定し、これらのみを出版社 (毎日本全体を読む時間がない) に渡すことです。

この問題を解決するために、本は 100 万行の ASCII テキストで構成され、拡大しています (実際には MySQL バックアップ ファイル)。

私の現在のアイデアは、各行 (1k 文字) の安全なハッシュ (たとえば SHA256) を作成し、それを HD に保存することです。ハッシュは 32 バイトしかないため、ファイルは 32MB しかありません。

次に、明日次のファイルを取得すると、1 行ずつ調べて、各行の新しいハッシュを作成し、それを前日のハッシュと比較します。

プロセスが終了すると、翌日のためにハッシュ ファイルが上書きされます。

比較は、文字列比較 ( > < オペランド) の二分探索法を使用します。これにより、平均 4 回の反復で結果が返されます。

私はまだ btree インデックス ソリューションをコーディングしていませんが、これにどのように取り組みますか?

4

6 に答える 6

1

私はdiffを使用します。

自分のプログラムに実装する必要がある場合は、2 つのシーケンスの最長共通サブシーケンスを見つけるアルゴリズムの 1 つを使用し、各ファイルを一連の行として扱います。

于 2008-10-30T00:58:06.417 に答える
0

あなたが説明する解決策は、rsyncアルゴリズムにいくぶん似ています。重要な点の1つは、rsyncは、元のファイルからのオフセットで、ターゲットファイル内の任意の場所にある既存のチャンクを認識しなければならないということです。

ファイルが実際にレコード構造になっている場合は、提案したように少し単純化できます。そうでない場合は、ローリングチェックサムが必要です。

また、再注文を認識する必要がありますか?または挿入/削除/置換のみ?

最も一般的なケースは、次のような完全なrsyncアルゴリズムです。

  • パラメータ定義:

    1. ブロックサイズ512を選択するか、通常1kで問題ありません。
      • 「強力な」チェックサムを選択します。MD4かそこらからのようなもの。64ビットで十分です。
      • 「弱い」ローリングチェックサムを選択します。1バイト先のブロックのチェックサムを取得するために、テールバイトを「減算」し、ヘッドバイトを「追加」できるもの。通常、16ビットのチェックサムは問題なく機能します。
  • 古いファイルの署名:

    1. 古いファイル全体をトラバースし、各ブロックで弱いチェックサムと強いチェックサムの両方を計算します。16ビットと64ビットのチェックサム、およびブロックあたり10バイト、つまりメガバイトあたり20KBを意味する512バイトのブロックを使用します。これは「署名」です
  • 新しいファイルと古いファイルの署名を使用して「パッチ」を作成します。

    1. 古いファイルの署名をロードします。最適なのはハッシュテーブルで、弱いチェックサムをキーとして、強いチェックサムとブロック位置が値です。
      • 新しいファイルの最初のブロックを読み取ります
      • ロードされたブロックの弱いチェックサムを計算する
      • ハッシュテーブルをチェックして、弱いチェックサムが存在するかどうかを確認します。
      • 見つかった場合は、強力なチェックサムを計算し、ハッシュで見つかったものと比較します
      • 両方のチェックサムが一致する場合は、ハッシュ内のブロック参照で「取得」とマークし、ブロックサイズ全体を1つ進めて、手順3に戻ります。
      • 強いチェックサムが一致しなかった場合、または弱いチェックサムがハッシュになかった場合は、弱いチェックサムを「ロール」します。つまり、ブロックの次のバイトを「追加」し、「減算」します。しっぽ。
      • パッチ内の「新しい」バイトのリストに、末尾から「減算された」バイトを追加します
      • 手順4に戻ります
  • 古いファイルにパッチを適用する

    1. 「パッチ」は、チェックサムのロール中にドロップオフした「新しい」バイトのリストと、古いファイルに一致する「取得した」ブロックのリストです。
于 2008-10-30T01:34:10.523 に答える
0

「そして、明日次のファイルを取得すると、1 行ずつ調べて、各行の新しいハッシュを作成し、それを前日のハッシュと比較します。」

わかりました: 100 万行の昨日の値と比較した 100 万行の今日のハッシュ値。

行は挿入または削除されますか? そうでない場合、これはハッシュが異なるかどうかを確認するための単純な並列読み取りのセットです。

追加または削除がある場合は、差分アルゴリズムを使用して変更の範囲を決定する必要があります。

大丈夫です。実装するのはそれほど難しくありません。

その文脈では、以下は意味をなしません。

比較は、文字列比較 ( > < オペランド) の二分探索法を使用します。これにより、平均 4 回の反復で結果が返されます。

ハッシュ値にある種の順序付けはありますか? それとも木構造?

于 2008-10-30T01:20:42.580 に答える
0

100 万行の本は膨大です。1 ページあたりおそらく 30 ~ 50 行あるので、余裕を持って 1 ページあたり 100 行と仮定しましょう。これは本が 10,000 ページであることを意味します。

1 KB の行も、通常よりもはるかに大きくなります。基本的な読みやすさは、1行あたりの文字数がそれほど多くないことを示唆しています。最大 1 KB の行をハッシュするか、ファイルを 1 KB のチャンクにチャンクしますか? スキームの問題の1つは、繰り返される行にはハッシュが繰り返されることです。これらの行の 1 つがいつ追加または削除されたかを特定できませんでした。

おそらく、削除された行についても発行者に通知する必要があります。

Glomek と同様diffに、ファイルで使用します。ファイルを RCS または CVS の管理下に置くと、現在のバージョンのファイルと以前のバージョン間の差分が保存されます。これにより、1 週間または 1 か月にわたって累積差分を提供することもできます。

また、私はおそらく独自の B-Tree インデックス作成を開発することはありません。

于 2008-10-30T01:23:06.817 に答える
0

これは、データ ウェアハウスでの増分読み込みに使用される手法です。ソース システム内で変更されたデータを識別できない状況では、データのスナップショットを取得し、それを最後のスナップショットと比較して違いを識別することができます。この手法は、このテーマに関する Ralph Kimball の本でも言及されており、私が設計に携わったアプリケーションでも使用されています。

このアプローチは誕生日攻撃に対して脆弱であるため、非常に広いキーを持つハッシュ アルゴリズムが必要です。MD5 または SHA ファミリのいずれかが適しています。また、欠落している自然キーを探す差分を通過する後処理がなければ、削除を検出することもできません。この計算では、実際にはテーブル構造を認識する必要があります。

于 2008-10-30T08:44:40.047 に答える
0

スキームの問題の1つは、繰り返される行にはハッシュが繰り返されることです。これらの行の 1 つがいつ追加または削除されたかを特定できませんでした

非常に良い点ですが、問題ではありません。繰り返される行は重複であり、すべての重複は処理の次の段階で削除されます。はい、あなたは正しいですが、それは問題ではありません。

「差分」リンクをクリックすると、アプリケーションと思われるものの説明が記載されたページに移動しますか? ダウンロード リンクはありません。どの言語のコードもありません。何が足りないのでしょうか。

バイトレベルの粒度について話している人もいます。これは必要ありません。行内の変更が行全体に影響するため、行の何かが変更された場合、行全体 (レコード) を再処理する必要があるため、行レベルの粒度のみが必要です。

したがって、それぞれ約 100 万行の 2 つのファイル (今日のスナップショットと昨日のスナップショット) で、約 1000 文字 (バイナリなし) の行を比較しています。

したがって、SHA256 のような安全なハッシュを使用すると (MD5 には衝突があり、比較すると遅い)、HO ラップトップで約 30MB/秒を処理できます。もちろん、サーバーはそれをはるかに高速に噛み砕きます。

したがって、ファイルが約 1GB の場合、すべてのハッシュを作成するには約 33 秒かかり、Windows ページ メモリを使用して 1Gb ファイルを読み取るには約 30 秒かかります。恐ろしくない

これで、各ファイルの行を表すハッシュの 2 つの配列ができました。それらを並べ替えると、バイナリ検索を使用できるようになるため、新しいファイル ハッシュを反復処理して、古いファイル ハッシュで一致するものを探します。見つからない場合は、その行が変更ファイルに追加されます。

行の本 (従来のデータベース) はあらゆる面で未知であることに注意してください。行の順序、変更の場所、変更の種類を保証するものではありません。

ページごとに先読みするという提案は適切ですが、最初の変更までは 2 つのファイルが同じ順序であると想定しています。これは想定できません。行 (行) の順序は任意です。また、任意のブロックサイズを選択すると、行の粒度に違反します。このタスクでは、行は不変です。

ファイル比較キャプチャ: この方法は、スナップショット差分法とも呼ばれます。この方法は、データ ウェアハウスにとって重要なファイルのビフォア イメージとアフター イメージを保持することで機能します。レコードを比較して変更を見つけ、レコード キーを比較して挿入と削除を見つけます。この手法は、通常、トリガーが存在せず、トランザクション ログが存在しないか独自の形式であるレガシー システムの場合に最も適しています。ほとんどのレガシー データベースには、データをファイルにダンプするための何らかのメカニズムがあるため、この手法では定期的なスナップショットを作成し、結果を比較して変更レコードを生成します。確かに、静的キャプチャのすべての問題がここにあります。情報の行全体を比較するという課題と、キーの識別と照合により、複雑さが増します。この手法は本質的に複雑であり、通常は望ましくありませんが、場合によっては、これが唯一の解決策になることがあります。

これはここで最も重要です。テラバイトのデータ ウェアハウスの領域に進むにつれて、データ ウェアハウスを毎晩ゼロから再構築する機能は、恐竜のようになります。データ ウェアハウスを更新するための論理的かつ効率的なアプローチには、何らかの形式の増分更新戦略が含まれます。

それで、私は正しい軌道に乗っていると思いますか?btree インデックスは有利ではないでしょうか?

于 2008-10-31T07:47:22.517 に答える