-2

テーブルに間違ったエントリを持つ 2 つの列があります。テーブルのサイズは、数十億のレコードに達します。2 つの列 (c1 と C2) の間でデータを交換したかったのですが、データを小さなチャンクで CSV ファイルにエクスポートし、修正されたエントリでインポートし直すというアプローチが取られました。たとえば、以下はデータセットです

--------
|C1 | C2 |
|3  | 4  |
|4  | 6  |

次に、データをセミコロンで区切られた CSV ファイルにエクスポートします (完全なコマンドは示されていません)。

SELECT C2,C1 FROM TABLE temp INTO OUTFILE /tmp/test.csv 

そのようなコマンドの出力は次のようになります

4;3
6;4

(問題のデータを削除した後) データをインポートし直すと、データは次のように修正されます。

  | C1  C2 |
  | 3   4  |
  | 4   6  |

それは本当に OUTFILE と INFILE 操作の問題だと思います

質問

  1. アプローチは理にかなっていますか?実際のデータは、データ スワップとは別に、一部の列で NULL、int 値も想定しています。
  2. もう 1 つの複雑さは運用データベースにあり、WHERE句を使用する必要があります。テーブル名も動的に取得されます。
  3. ポイント 2 を参照して、クエリに動的性を追加するにはどうすればよいですか。STORED プロシージャまたは SHELL SCRIPT を使用する必要がありますか? STORED プロシージャは、LOAD DATA INFILE 機能をサポートしていないようです。
  4. シェルが残っている場合、再利用できるサンプル スクリプトはありますか? CSV ファイル名、テーブル名、および WHERE 句は実行時に作成する必要があります。
  5. また、エクスポートおよびインポートされるチャンクのサイズは動的に計算されます。
  6. 他のアプローチはありますか?

注 - これは mysql 上の INFOBRIGHT 列ベースのテーブルです。UPDATE クエリはパフォーマンスが低く、ALTER TABLE は INFOBRIGHT でサポートされていません。

4

1 に答える 1

0

このアプローチを使用して一時テーブル「temp_table」を作成し、この手順を使用して、このようなテーブルの名前でどこからでも呼び出すことができます。

change_fields('table_origen'); を呼び出します。

手順は次のように機能します

  1. temp_table のデータを削除します
  2. table_origen から順序を変更して、この temp_table に挿入します
  3. table_origen から削除
  4. temp_table からの情報を table_origen に挿入します

あなたは夢中になることができ、いくつの変数を受け入れたいですか

CREATE DEFINER=`root`@`%` PROCEDURE `change_fields`(IN `tableName` VARCHAR(200))
    LANGUAGE SQL
    NOT DETERMINISTIC
    CONTAINS SQL
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN

    SET @hr1 = CONCAT('Delete from temp_table;');

    PREPARE hrStmt1 FROM @hr1;
    EXECUTE hrStmt1;
    DEALLOCATE PREPARE hrStmt1;
    SET @hr1 = CONCAT('insert into temp_table (C_1, C_2) Select C2, C1 from  `',tableName,'`;');

    PREPARE hrStmt1 FROM @hr1;
    EXECUTE hrStmt1;
    DEALLOCATE PREPARE hrStmt1;

    SET @hr1 = CONCAT('Delete from `',tableName,'`;');

    PREPARE hrStmt1 FROM @hr1;
    EXECUTE hrStmt1;
    DEALLOCATE PREPARE hrStmt1;

    SET @hr1 = CONCAT('insert into `',tableName,'` (C1,C2) select C_1, C_2 from  temp_table;');

    PREPARE hrStmt1 FROM @hr1;
    EXECUTE hrStmt1;
    DEALLOCATE PREPARE hrStmt1;

END;
于 2016-03-21T19:27:52.717 に答える