web-dev-qa-db-ja.com

システム設計:毎月非常に大きなCSVインポート

毎月、外部ベンダーからの大きなCSVに依存するWebアプリケーションがあります。大きいと言うと、約6 GB、つまり数百万行を見ています。おそらく、2〜5個のCSV。このウェブアプリでは、ユーザーがデータを入力、修正、フラグ付け/削除することもできます。列の数とデータのクリーン度は、ベンダーの観点からは保証されていません。また、データが重複している可能性があります(Webアプリでは重複するデータを表示できません)。

私はこれに取り組む複数の方法を考えてきました:

  1. これらのCSVを、列ヘッダーと一致するCSVごとのテーブルにロードし、必要なものの「ビュー」を作成します。

このソリューションは、毎月CSVをCSVテーブルにインポートするだけで問題なく機能するため、実装と保守が最も簡単なようです。これは最も効率が悪いようで、データの整合性に関する問題が最も多くなります。また、ビューは複雑なヘラになります。

  1. これらのCSVを毎月独自のスキーマに読み込み、独自のスキーマからWebアプリケーションを構築します。

インポートが毎月行われると、インポートを実行する必要があり、これにより既存のデータが破損する可能性があるため、このソリューションの実装と維持は困難に思われます。それはあなたのウェブアプリがあなた自身のスキーマであり、あなたがそれに「マッピング」できることが最善です。さらに、CSVには古いデータを無効にするデータが含まれるため、更新が困難になります。このルートを使用する場合、Java/C#またはSQLでインポートしますか?ビジネスルールを処理できるように、Java/C#は理にかなっているようですが、遅くなります...

  1. CSVごとにCSVをテーブルにロードし、それに対してSQLクエリを実行するだけで、WebアプリはWebアプリに必要なものと一致するモデルを作成できます。

このソリューションは、ビューソリューションと同じ問題にぶつかりますが、SQLクエリが非常に複雑であり、それらを維持するという頭痛の種があります。外部ベンダーがスキーマを変更すると、SQLクエリが壊れる可能性がありますが、インポートする前にCSVを変更するだけで問題ありません。

次に、次の質問があります。

  1. CSVが入力された行をユーザーが更新した場合、つまり、#2を使用するとします。これは、私が頼りにしていることですが、CSVが入ったときにその更新をどのように保持しますか?

    1. どのようにしてCSVインポートをロールバックできますか? CSVのインポートが1か月間有効であると考えていて、ユーザーが生成した大量のデータがそのCSVにある場合

簡単な解決策はないようで、どちらにしても私は「それを取りなさい」。何か不足していますか?誰でも簡単な解決策を見つけたり、考えたりできますか?

7
user2370642

「CSV」は、彼らがあなたに提供するものにふさわしい言葉ではありません。それは彼らがあなたにそれをあなたに届けるフォーマットであり、非常に弱い保証があります。ほとんどの人は、信頼性がなく欠落しているデータを含む6 GBのCSVファイルを単に「データ」と呼んでいますが、こちらのほうが正確だと思います。一部のデータを提供するサプライヤーがいて、何らかの方法で顧客に提供する責任があります。

これらのCSVを毎月独自のスキーマに読み込み、独自のスキーマからWebアプリケーションを構築します。

これが一番よく見えます。提供されたデータにビジネスロジックを適用して、整合性とパフォーマンスを維持します。サプライヤは非常に弱い保証を提供しており、顧客は強力な保証を提供しています。彼らがあなたに与えるフォーマットは長い文字列です。技術面接で、長い文字列への永続的なアクセスを構築するように依頼された場合、答えはそれを前処理することです。これがあなたの提案です。

あなたは、ユーザーがデータとのインターフェース方法に関する追加の機能を要求することを想定する必要があります。おそらく、元に戻すボタンまたは監査ログが必要です。どちらの場合も、独自の(メタ)データを所有する必要があります。

これを、クリーンな形式または機能的な形式でデータを利用できるようにする場合と比較してください。データベース。次に、自分でデータを所有するか、その形式を使用するかについて同じ決定をしますが、現在、それらの形式ははるかに強力な保証を持っています。

次に、次の質問があります。

これらは良い、難しい質問であり、先ほど述べたように、あなたの会社はユーザーのためにそれらを解決するビジネスをしているようです、そしてもちろん、これらのユースケースはあなた自身のスキーマの使用を確かに奨励します。

私の頭の上では、これはバージョン管理の問題のように見えるので、「バージョン管理の大きなデータ」のようなものを調べてください。 1回のGoogleヒット: https://datascience.stackexchange.com/questions/5178/how-to-deal-with-version-control-of-large-amounts-of-binary-data

7
djechlin

これは、要件、つまり"データの入力、修正、フラグ付け/削除"の正確な意味、および前処理と後処理の要件に大きく依存します。編集は行ごとに行われますか?各行がいっぱいになっているか、処理する必要のないブロックがその行にあるか?完全に手動ですか、またはいくつかの自動クリーンアップ/前処理ステップがありますか? 「重複」はどのように検出されますか?行のIDを検出するには、いくつかの基準が必要です。

また、データフローの後に何が来るかについても述べていません。データの修正はそれ自体に終わりはないと思います。したがって、編集後に何が起こるかを考慮する必要もあります。元の形式を使用して、データをCSVファイルに再度書き込む必要がありますか?どこかに保存/アーカイブされますか?または、データはまったく異なる方法で処理されますか?

したがって、これらの全体的な要件を取得したら、必要な編集および処理手順exactlyno less、no moreをサポートするデータモデル/スキーマを作成する必要があります。これはある程度あなたのアプローチ#2かもしれませんが、

  • 異なる月のデータを混同することは問題であると述べたので、それらを統合することは必須ではないので、月ごとにデータを分けてください。マスターテーブルDatapoolに主キー「日付」または「月」、おそらくCSVファイル名を一意の属性として設定し、他のテーブルをマスターテーブルの詳細テーブルとして作成します。

  • ユーザーとプロセスが実際に表示および編集する必要があるデータの一部のみをモデル化します。残りのデータは、たとえば文字列列に保持できます。必要かどうかが(まだ)わからない場合は、詳細のモデリングに時間を費やさないでください。

  • その後、すべてのステップをサポートできることを確認してください。これらの要件を理解しておくと、保持する必要があるデータと無視できるデータを決定するのに役立ちます。

データモデルを作成するときは、データがおそらく望んでいる品質ではないことに注意してください。たとえば、一意である必要があるすべての属性に対してすべての「一意の」制約を設定することができない場合がありますafter編集。

3
Doc Brown

私たちが採用したソリューションは、マッピングを作成することでした。ツールは最初のnデータ行を取得し、ボイラープレートのように見えるものはすべてスキップするため、インポートを処理する人はデータのサンプリングと行ヘッダーを確認してマッピングを制御できます。

「CSV」スキーマは、可能な場合はヘッダー行と列数によって決定されました。 CSVスキーマからアプリケーションスキーマにデータをマップする方法がありました。特別な処理が必要ないくつかの問題に遭遇しました。

  • 必須列のデフォルト値(データはわかっていたが、すべてのレコードで同じであるため提供されなかった場合がありました)
  • カスタム日付形式の認識(注:日付サンプルに2018年1月2日と2018年1月3日が含まれている場合、月と日を検出するのが難しい場合があります)

確かに他にもありますが、私はそのプロジェクトに取り組むことから数年がかりです。

このマッピングはデータベースに保存されたため、将来のデータダンプのヘッダー署名に基づいてマッピングを検索できます。データのフォーマットを処理するのに大いに役立ちました。

処理は、データの読み取りとチャンクでのデータベースへの書き込みで構成されていました。つまり、100行程度で読み取ることを意味します。ノイズを少しでも簡単に除去できるように、それらをコレクションに準備してから、そのチャンクに書き込みます。一度にすべてをメモリに保存する必要なく、データベースに書き込むときにデータのインポートを高速化します。

エラーは、ファイルを参照するデータベースレコードに保持されているCSVに書き込まれたため、マッピングの何が問題だったのかを理解できました(つまり、月と日が逆になっているか、必要な列がまばらに入力されていました)。 CSVには、行番号、特定のエラー、問題の原因となったデータ、および予想されるターゲット列が含まれていました。

あなたにとってより難しい問題は、重複データを検出することです。アプリケーションのデータストアを効率的にクエリ/検索できる限り、いくつかのオプションがあります。

  • 準備された領域に生の入力を書き込み、別のステップとして後処理します
  • 進行しながらデータベースにクエリを実行します。

トレードオフは、データを既知のスキーマに準備するという点で、最初のオプションはデータをより迅速に取り込むことです。実際に使用する準備ができる前にマッピングをトリアージできるようにします。 2番目のオプションでは、1回のパスでデータを準備できますが、処理時間が10倍にもなることがあります。

1
Berin Loritsch