私は、ユーザーが MS Access データベース (csv エクスポート) をアップロードし、それを変換して MySQL データベースに移行できるようにする php Web アプリケーションを構築しています。
MS Access データベースは、100k 行の t_product と呼ばれる 1 つのテーブルで構成されています。このテーブルはうまく設計されていません。例として、次のクエリを実行します。
SELECT part_number, model_number FROM t_product
戻ります:
part_number model_number
100 AX1000, AX1001, AX1002
101 CZ10, CZ220, MB100
ご覧のとおり、モデル番号は、別のテーブルの個々のレコードではなく、カンマ区切りの値としてリストされています。この性質の問題は他にもたくさんあります。mysql データベースにインポートする前に、このデータを消去するスクリプトを作成しています。このスクリプトは、既存の Access 列を適切なリレーショナル デザイン データベースにもマップします。
私の問題は、スクリプトの完了に時間がかかりすぎることです。私がやっていることを説明するための単純化されたコードは次のとおりです。
$handle = fopen("MSAccess.csv, "r");
// get each row from the csv
while ($data=fgetcsv($handle, 1000, ","))
{
mysql_query("INSERT INTO t_product (col1, col2 etc...) values ($data[0], $data[1], etc...");
$prodId = mysql_last_insert_id();
// using model as an example, there are other columns
// with csv values that need to be broken up
$arrModel = explode(',', $data[2]);
foreach($arrModel as $modelNumber)
mysql_query("INSERT INTO t_model (product_id, col1, col2 etc...) values ($prodId, $modelNumber[0], $modelNumber[1] etc...");
}
ここでの問題は、各 while ループの反復がデータベースに対して膨大な数の呼び出しを行うことです。すべての製品レコードに、N 個のモデル番号、Y 個の部品番号、X 個のシリアル番号などを挿入する必要があります...
CSV 全体を配列に格納する別のアプローチを開始しました。次に、次のような 1 つのバッチ クエリを記述します。
$sql = "INSERT INTO t_product (col1, col2, etc...) values ";
foreach($arrParam as $val)
$sql .= " ($val[0], $val[1], $val[2]), "
しかし、このアプローチでは過剰なメモリ エラーが発生しました。最大メモリ制限を 64M に増やしましたが、まだメモリが不足しています。
この問題に取り組む最善の方法は何ですか?
最初にすべてのクエリを *.sql ファイルに書き込んでから、*.sql ファイルを mysql データベースにインポートする必要がありますか?