質問

表1:キッチンのシンクも含めてすべて。間違った形式の日付 (最後が年であるため、その列で並べ替えることはできません)、VARCHAR として格納された数値、「番地」列の完全な住所、名列の名と姓、姓列の市区町村、不完全な住所、長年にわたって変更された一連のルール、重複レコード、不完全なレコード、ガベージ レコードなどに基づいて、あるフィールドから別のフィールドにデータを移動することで、前の行を更新します。あなたはそれを名付けます...ああ、もちろん TIMESTAMP 列や PRIMARY KEY 列は表示されません。

表2:この赤ん坊を割った時点で、正常化の希望は消え去った。各エントリに行があり、テーブル 1 の行が更新されます。そのため、明日はない (800MB 相当) のような重複と、Phone1 Phone2 Phone3 Phone4 のような列が表示されます。Phone15 (電話とは呼ばれません。説明のためにこれを使用しています) 外部キーは..まあ推測してください。table1 の行にどのようなデータが含まれていたかによって、候補が 3 つあります。

表3:これ以上悪化する可能性はありますか。そうそう。「外部キーは、ダッシュ、ドット、数字、文字を組み合わせた VARCHAR 列です。これで一致が得られない場合 (一致しないことがよくあります)、同様の製品コードの 2 番目の列が必要です。列内のデータと何の相関関係もない名前を持つ列、および必須の Phone1 Phone2 Phone3 Phone4...電話15.Table1 から複製された列があり、TIMESTAMP 列や PRIMARY KEY 列が表示されていません。

表4:は進行中の作業であり、いつでも変更される可能性があると説明されています。基本的には他のものと同様です。

1m近くの列では、これは大混乱です。幸いなことに、それは私にとって大きな混乱ではありません。残念ながら、そこから各「顧客」の複合レコードを取り出さなければなりません。

最初に、主キーを追加し、すべての日付をソート可能な形式に変換するという、Table1 の 4 つのステップの変換を考案しました。次に、Table1 を取得して他のテーブルから取得してコンポジットを形成できるようになるまで、フィルター処理されたデータを返すクエリをさらに 2 ステップ実行しました。数週間の作業の後、いくつかのトリックを使用してこれを 1 つのステップにまとめました。これで、混乱した場所にアプリを指定して、複合データのきれいなテーブルを取り出すことができるようになりました。幸いなことに、目的のために必要な電話番号は 1 つだけなので、テーブルの正規化は問題ありません。

ただし、ここからが本当の仕事の始まりです。毎日何百人もの従業員が想像もつかない方法でこのデータベースを追加/更新/削除し、私は毎晩新しい行を取得しなければならないからです。

どのテーブルの既存の行も変更される可能性があり、TIMESTAMP ON UPDATE 列がないため、何が起こったのかを知るにはログに頼る必要があります。もちろん、これはバイナリ ログが存在することを前提としていますが、バイナリ ログは存在しません。

コンセプトの導入は鉛の風船のように下がりました。彼らの子供たちが実験的な手術を受けなければならないことを彼らに伝えたほうがよかったかもしれません。それらは決してハイテクではありません...集まらなかったら…

彼らは私の会社が切望しているいくつかの貴重な情報を持っているので、状況は少し微妙です。私は大企業の上級管理職(彼らがどのようなものかご存知でしょう)から「それを実現するように」と命じられました。

夜間の更新を処理するには、別のアプリケーションで bin ログ ファイルを解析し、日中にそのデータベースに対して何が行われたかを把握し、それに応じてテーブルを合成する以外に方法は思いつきません。実際、自分のテーブルに何をすべきかを理解するには、テーブル 1 を見るだけで済みます。他のテーブルは、レコードをフラッシュするためのフィールドを提供するだけです。(MASTER SLAVE を使用しても、混乱したものが複製されるため役に立ちません。)

別の方法は、table1 のすべての行に一意のハッシュを作成し、ハッシュ テーブルを構築することです。次に、毎晩データベース全体を調べて、ハッシュが一致するかどうかを確認しました。存在しない場合は、そのレコードを読み取ってデータベースに存在するかどうかを確認し、存在する場合はデータベース内で更新し、存在しない場合は新しいレコードを作成して INSERT します。これは見苦しく、高速ではありませんが、バイナリ ログ ファイルの解析もきれいとは言えません。

この問題を明確にするためにこれを書きました。多くの場合、それを他の人に話すと、問題が明確になり、解決策がより明確になります。この場合、頭痛がさらに大きくなるだけです。

ご意見をいただければ幸いです。

役に立ちましたか?

解決

私もログ ファイル (バイナリ ログ) について最初に考えました。彼らがどのように物事を行ったかを知ったら、あなたは身震いするでしょう。部分が追加および変更されると、行ごとにログ内に多数のエントリが存在します。とにかく巨大です!今のところ、私はハッシュのアプローチに落ち着きました。いくつかの賢いファイル メモリ ページングを使用すると、これは非常に高速になります。

他のヒント

私は MySQL の専門家ではないので、これは左欄から出てきたものです。

しかし、ログ ファイルが答えになるかもしれないと思います。

ありがたいことに、ログから実際に知る必要があるのは 2 つだけです。

レコード/ROWIDと操作が必要です。

ほとんどの DB (おそらく MySQL だと思います) では、行 ID やレコード ID などの暗黙的な列が各行にあります。これはデータベースで使用される内部行番号です。これは「無料」の主キーです。

次に、操作が必要です。特に、それが行に対する挿入、更新、削除のいずれの操作であるかが重要です。

これらすべての情報を時間順に統合し、それを実行します。

挿入/更新ごとに、元の DB から行を選択し、その行を宛先 DB に挿入/更新します。削除の場合は、行を削除します。

フィールド値は重要ではないだけで、気にする必要はありません。列全体を実行します。

できればバイナリ ログ ファイルを「解析」する必要はありません。MySQL にはすでにそのためのルーチンがあるはずです。必要なのは、それらの使用方法を見つけて理解するだけです (便利な「ダンプ ログ」ユーティリティも使用できるかもしれません) )。

これにより、システムを非常にシンプルに保つことができ、DB の合計サイズではなく、その日の実際のアクティビティにのみ依存するようになります。最後に、後で「よりスマート」にすることで最適化することができます。たとえば、行を挿入し、更新し、その後削除する可能性があります。リプレイではその行を完全に無視できることがわかります。

明らかに、実際にログ ファイルを読み取るには少し難解な知識が必要ですが、残りは簡単なはずです。ログ ファイルにもタイムスタンプが付けられているので、「今日から」の行、または任意の日付範囲で作業することができると思います。

このデータベースにアクセスする既存のコードを使用して、ニーズに合わせて変更することはできないでしょうか?もちろんコードはひどいものに違いありませんが、 かもしれない データベース構造をあなたに代わって処理してください。そうすれば、考古学者を演じるのではなく、自分の仕事を成し遂げることに集中できると思います。

maatkit の mk-table-sync ツールを使用して、ステージング データベースを同期できる場合があります (結局のところ、データベースは非常に小さいだけです)。これにより「混乱が再現」されます

次に、同期後にさまざまなクエリを実行して、レポートできるより適切なテーブルのセットを生成するものを作成できます。

これはパフォーマンス上の問題なく日常的に実行できると思います。

すべてを別のサーバーで実行すると、元のデータベースへの影響を回避できます。

私が確認できる唯一の問題は、一部のテーブルに主キーがない場合です。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top