Je crée une application web php qui permet à un utilisateur de télécharger une base de données MS Access (exportation csv) qui est ensuite traduite et migrée dans une base de données MySQL.Comment traduire et migrer des données
La base de données MS Access est constituée d'une table appelée t_product de 100k lignes. Cette table n'est pas bien conçue. À titre d'exemple, la requête suivante:
SELECT part_number, model_number FROM t_product
retournera:
part_number model_number
100 AX1000, AX1001, AX1002
101 CZ10, CZ220, MB100
Comme vous pouvez le voir, les numéros de modèle sont répertoriés sous forme de valeurs séparées par des virgules au lieu de dossiers individuels dans une autre table. Il y a beaucoup d'autres problèmes de cette nature. J'écris un script pour nettoyer ces données avant de les importer dans la base de données mysql. Le script mappera également les colonnes Access existantes à une base de données de conception relationnelle appropriée.
Mon problème est que mon script prend trop de temps à compléter. Voici son code simplifié pour expliquer ce que je fais:
$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...");
}
Le problème ici est que chaque itération en boucle fait un très grand nombre d'appels à la base de données. Pour chaque enregistrement de produit, je dois insérer N numéros de modèle, Y numéros de pièce, X numéros de série etc ...
J'ai commencé une autre approche où j'ai stocké l'ensemble CSV dans un tableau. Je puis écrire une requête par lots comme
$sql = "INSERT INTO t_product (col1, col2, etc...) values ";
foreach($arrParam as $val)
$sql .= " ($val[0], $val[1], $val[2]), "
Mais j'ai rencontré des erreurs de mémoire excessives avec cette approche. J'ai augmenté la limite de mémoire maximale à 64M et je manque toujours de mémoire.
Quelle est la meilleure façon de résoudre ce problème?
Peut-être devrais-je d'abord écrire toutes mes requêtes dans un fichier * .sql, puis importer le fichier * .sql dans la base de données mysql?
La boîte à outils de migration optimisera également ses requêtes pour accélérer la traduction en bloc. –