2010-06-13 55 views
0

J'ai ce fichier txt volumineux (et bizarrement formaté) sur le site Web USDA's. C'est le fichier NUT_DATA.txt.Importation d'un grand fichier délimité dans une table MySQL

Mais le problème c'est qu'il fait presque 27mb! J'ai réussi à importer les quelques autres fichiers plus petits, mais ma méthode utilisait file_get_contents ce qui est logique pourquoi une erreur serait levée si j'essaye d'accrocher 27+ mb de RAM.

Alors, comment puis-je importer ce fichier massif dans ma base de données MySQL sans rencontrer de problème de délai et de RAM? J'ai essayé juste d'obtenir une ligne à la fois du fichier, mais ceci s'est heurté au problème de timeout.

Avec PHP 5.2.0.

Voici l'ancien script (les champs de la DB sont que des chiffres parce que je ne pouvais pas comprendre ce nombre représentait ce nutriment, je trouve ces données document très mal Désolé la laideur du code.):

<? 

    $file = "NUT_DATA.txt"; 

    $data = split("\n", file_get_contents($file)); // split each line 

    $link = mysql_connect("localhost", "username", "password"); 
    mysql_select_db("database", $link); 

    for($i = 0, $e = sizeof($data); $i < $e; $i++) 
    { 
     $sql = "INSERT INTO `USDA` (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17) VALUES("; 
     $row = split("\^", trim($data[$i])); // split each line by carrot 
     for ($j = 0, $k = sizeof($row); $j < $k; $j++) { 
      $val = trim($row[$j], '~'); 
      $val = (empty($val)) ? 0 : $val; 
      $sql .= ((empty($val)) ? 0 : $val) . ','; // this gets rid of those tildas and replaces empty strings with 0s 
     } 
     $sql = rtrim($sql, ',') . ");"; 
     mysql_query($sql) or die(mysql_error()); // query the db 
    } 

    echo "Finished inserting data into database.\n"; 

    mysql_close($link); 

?> 
+0

Je ne sais pas PHP , mais je pense que cela pourrait mieux fonctionner si vous pouviez lire quelques lignes, puis les insérer immédiatement dans la BD puis lire le prochain bloc de lignes jusqu'à EOF ... – Sunny

+0

La meilleure façon de le faire est d'utiliser LOA D DATA (voir http://dev.mysql.com/doc/refman/5.1/en/load-data.html) Bien sûr, ce n'est pas PHP, mais cela ne prendra pas des heures pour le charger. –

+0

Merci à tous, mais c'est un hébergement partagé et je n'ai pas un accès complet à MySQL, ni aucun autre langage de script, sauf PHP. – Tom

Répondre

2

Si vous devez utiliser PHP, vous pouvez lire le fichier ligne par ligne à l'aide fopen et fgets

<? 

$file = "NUT_DATA.txt"; 
$fh = @fopen($file, "r"); // open the file for reading 
$link = mysql_connect("localhost", "username", "password"); 
mysql_select_db("database", $link); 

while(!feof($fh)) 
{ 
    $data = fgets($fh, 4096);  // read line from file 

    $sql = "INSERT INTO `USDA` (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17) VALUES("; 
    $row = split("\^", trim($data)); // split each line by carrot 
    for ($j = 0, $k = sizeof($row); $j < $k; $j++) { 
     $val = trim($row[$j], '~'); 
     $val = (empty($val)) ? 0 : $val; 
     $sql .= ((empty($val)) ? 0 : $val) . ','; // this gets rid of those tildas and replaces empty strings with 0s 
    } 
    $sql = rtrim($sql, ',') . ");"; 
    mysql_query($sql) or die(mysql_error()); // query the db 
} 

echo "Finished inserting data into database.\n"; 

fclose($fh); 

mysql_close($link); 

?> 

Vérifiez les fgets documentation pour plus d'informations

+0

En utilisant ceci, set_time_limit, et en attendant patiemment j'ai réussi à obtenir le fichier entier dans une base de données. Maintenant, je dois juste comprendre ce qui est quoi dans ces données:) – Tom

0

vous pouvez augmenter la quantité de mémoire chaque script peut utiliser en réglant cette valeur dans php.ini:

memory_limit = 64M 

cela dit ceci: vous avez utiliser PHP? d'autres langages de script (comme python) pourraient être plus appropriés pour ce genre de tâches.

+0

PHP est bien pour une tâche comme celle-ci! – mmattax