2012-04-10 4 views
1

定期的に大量のデータをCSVファイルからMySQLデータベースにアップロードする必要があります。私はこれを、bashスクリプトからLOAD DATA INFILEを実行するだけで使用しました。しかし、今では、データは複数のテーブルに分散され、リレーションシップは維持されます。そのような場合の一般的な戦略は何ですか?bashのMySQL関連テーブルの一括挿入

最初に簡単なタスクを考えてみましょう:関係の一対多、2つの表。私は何かを検討

  1. を手動でCSVに識別子を適用する表1
  2. のための最大のidentyfierを得るには、両方のテーブルを挿入する心の内の2つのターゲット表を使用してファイル
  3. を分割
  4. ファイル

最適なソリューションですか? (実際のケースでは、このように多くの多対多リレーションを更新する予定です)

プロセス全体の期間中、テーブル1をbashレベルからロックできますか?あるいは、私はperlやPythonのような中間的なツールを使って、すべてのものを1つのセッションに保つ必要がありますか?

+0

優れた最初の投稿です! Kimballのデータウェアハウスツールキット(本)(http://www.amazon.com/The-Data-Warehouse-Toolkit-Dimensional/dp/)には、Immon(ite)かKimball(ite)か、Kimballのデータウェアハウスツールキット0471200247/ref = sr_1_1?s = books&ie = UTF8&qid = 1334075383&sr = 1-1)は、システムによって生成されるアーティファクトキーを残すと主張しています。または、私にとってうまくいった別のアプローチを試してみてください。独立した '入力'テーブルのセットを保持し、現在のファイルを空の入力テーブルにインポートし、メインテーブルにマージするストアドプロシージャを実行します。がんばろう。 – shellter

+1

awkを使ってデータを前処理/分割し、分割されたファイルにデータをロードするだけです。詳細が必要な場合は、自分で提供する必要があります。 – Kevin

答えて

0

質問にはさまざまな相反する要件があります。この回答は、ロックを維持することに集中しています。

操作全体のテーブルロックを維持するには、SQL Serverへの単一の接続を維持する必要があります。 1つの方法は、mysqlコマンドラインクライアントを1回呼び出すだけで、すべてのものを複数行の複数コマンド入力として渡すことです。基本的にはこのように:ロックが保持されている間(最大識別子のような)データベースからの質問をすることなく、限り、あなたはすべての必要な文を生成することができますように働くだろう

{ echo "LOCK TABLES Table1 WRITE" 
    for i in "${infiles[@]}"; do 
    echo "LOAD DATA LOCAL INFILE '${i}'" 
    done 
} | mysql 

読み取り操作(最大値を求めるような操作)と書き込み操作(一部のファイルの内容の読み込みなど)を混在させるには、サーバーと双方向の通信をしないでください。 bashでこれを達成するのは非常に難しいので、私はそれに反対しています。あなたが質問する必要がなくても、bashパイプによって提供される一方向の接続は危険の源です:もしmysql側で何かがうまくいかない場合、bashは気づきませんし、とにかく次のコマンドを発行します。矛盾したデータをコミットする可能性があります。

これらの理由から、あなたが言及したPerlやPyhonオプションのように、mysqlバインディングが利用できるいくつかのスクリプト言語を示唆したいと思います。

  1. ロックテーブル
  2. 開始トランザクション
  3. が最大のIDのような質問をして、入力のcsvファイルを読む:あなたは、単一のスクリプトで、次のすべてを行う可能性がありますので、これらの言語でCVSファイルを読み込むには、簡単です。
  4. エラーが発生しなかった場合、テーブル
  5. にテーブルレイアウトに
  6. 挿入データと一致するように入力データを調整し、トランザクションをコミット
関連する問題