URL: https://www.overclockers.at/coding-stuff/massen-php-substr-und-mysql-insert_245944/page_1 - zur Vollversion wechseln!
als folgefrage zu meinem CSV problemthread:
stellt euch vor, ihr müsst einen string in rund 90 (verschieden große) teile zerlegen und diese dann in eine MySQL tabelle schreiben.
ich würd jetzt hergehen und den string mit 90 "substr" in 90 variablen zersetzen und diese 90 variablen danach in ein insert packen. und das dreimal für je drei verschiedene dateien.
...gibts da irgendwelche eleganteren, advanced methoden mit weniger schreibaufwand?
die tabelle würde jedesmal truncated werden, also gibts vielleicht ja irgendwelche tricks um sie z.b. gleich autoamtisch aus einem array mit den 90 werten zu erstellen?
irgendwas, was weniger nach anfänger aussieht und mich weiterbildet?
danke!
Rede ich eigentlich gegen eine Wand?
Code:$ printf '%20s%20s%20s%20s\n' 1 2 3 4 > data_input $ printf '%20s%20s%20s%20s\n' blah blub blaer foobar >> data_input
Code:$ cat data_input 1 2 3 4 blah blub blaer foobar
Code:$ cat demo.php #!/usr/bin/env php5 <?php $handle = @fopen("data_input", "r"); if ($handle) { while (($buffer = fgets($handle, 4096)) !== false) { $res = sscanf(trim($buffer), '%20s%20s%20s%20s', $a, $b, $c, $d); print "a=$a b=$b c=$c d=$d\n"; } if (!feof($handle)) { echo "Error: unexpected fgets() fail\n"; } fclose($handle); } ?>
Code:$ ./demo.php a=1 b=2 c=3 d=4 a=blah b=blub c=blaer d=foobar
ja ok die substr kann ich mit sscanf abkürzen, danke.
bleibt noch der insert in die db
Bulk Insert via
INSERT INTO table (a,b) VALUES (1,2), (2,3), (3,4);
Einfach mit prepared Statement: http://stackoverflow.com/a/12960624
Noch cooler:
https://dev.mysql.com/doc/refman/5.7/en/load-data.html
so, ich glaub ich hab jetzt halbwegs was wie ich mir das vorstelle.
hier ein gekürzter beispielstring aus einem der quellfiles:
Code:$string = "01VSPRI ALLE 25.07.201625.07.2016";
Code: PHP$data = array ("version" => array(0,2,'int'), "aktion" => array(2,1,'varchar'), "lieferant" => array(3,5,'varchar'), "angebotsnummer" => array(14,10,'int'), "benutzergruppe" => array(24,9,'varchar'), "angebotstermin" => array(33,10,'varchar'), "angebotsdauer" => array(43,10,'varchar') );
Code: PHP$keys = array_keys($data); $query = "DROP TABLE IF EXISTS flugdaten".date("Ymd")."; CREATE TABLE flugdaten".date("Ymd")." ( id mediumint(8)"; foreach($keys as $key) { $query .= ", $key ".$data[$key][2]."(".$data[$key][1].")"; } $query .= ") ENGINE=MyISAM";
Code: PHP$i=1; $query = "INSERT INTO flugdaten".date("Ymd")." (id,".implode(",",$keys).") VALUES ( $i"; foreach($keys as $key) { // get data from string $value = substr($string,$data[$key][0],$data[$key][1]); $query .= ", '$value'"; } $query .= ")"; $i++;
Hast du einen fortlaufenden Key? Dann währe eine eine Tabelle mit partitionierung einfacher.
Für die Performance könnte es helfen, vor der Schleife ein "BEGIN;" abzusetzen und z.B. alle 100-1000 Schleifendurchläufe ein "COMMIT; BEGIN;" nach der Sleife dann noch ein "COMMIT;". Damit hast du nur eine Schreiboperation alle 100-1000 Einträge anstatt für jeden Eintrag.
danke für den tipp.
performance könnte bei 2mio+ zeilen eine sache werden. ich behalts mir im hinterkopf
Entweder über LOAD DATA INFILE und davor das File anpassen, oder ansonsten würde ich auf alle Fälle mit Prepared Statements arbeiten.
overclockers.at v4.thecommunity
© all rights reserved by overclockers.at 2000-2025