AndreD: Lösungsansätze: CSV-Import in DB

Beitrag lesen

Hallo zusammen,

Ich habe mir verschiedene Lösungsansätze für ein CSV-Imports in eine Datenbank erdacht. Meine Bitte wäre das mir jemand bei der Entscheidung hilft wie man das letztendlich am besten angehe.

Voraussetzungen:
---------------------------------------------------------------------

Umgesetzt wird das Ganze mit PHP & MySQL, im Moment nur für Projekte bei denen weniger als 1000 Datensätze einzulesen sind, aber die Lösung soll auf Dauer auch für grössere Projekte performant sein.

Es wird vorausgesetzt es sich um eine aus Excel exportierte CSV-Datei handelt, d.h. der Aufbau der CSV-Datei (Trennzeichen ist der Semikolon, Zeilenumbruch als \r\n, Werte sind nicht von Anführungszeichen eingeschlossen) ist bekannt.

Die Feldnamen sind ebenfalls festgelegt, die MySQL-Tabelle wird einmalig angelegt und bleibt bis auf weiteres unverändert.

Die CSV-Datei ist entscheidend! Der Inhalt der CSV-Datei soll später 1:1 in der Tabelle stehen. D.h. bereits vorhandene Datensätze bleiben unberührt oder werden entsprechend geändert, neue Datensätze werden angelegt und nicht mehr vorhandene werden gelöscht.

[1] Schnelle Lösung per MySQL
---------------------------------------------------------------------
-> User wählt eine lokale CSV-Datei über ein Upload-Formular aus und sendet dieses an den Server. Check auf Dateiendung *.csv und Mime-Type "text/comma-separated-values" möglich wobei mein Browser in dem Fall leider "application/octet-stream" übermittelt.

-> Ein PHP-Script kopiert die Datei in ein festgelegtes Verzeichnis (Falls dies nicht existiert wird es angelegt). Besser wäre es vielleicht es wird stattdessen die temporär angelegte Datei beim SQL-Statement verwendet (mit LOAD LOCAL DATA)?

-> Ist die Datei vorhanden wird die festgelegte Tabelle per delete komplett geleert (an der Stelle könnte möglicherweise erst ein Backup auf eine andere Tabelle erfolgen, macht das Sinn?) und das File per SQL-Statement "LOAD [LOCAL] DATA INFILE '" . $file . "' INTO TABLE ..." in die Tabelle geschrieben.

Das ganze wäre wohl in einer halben Stunde umgesetzt und würde, denke ich auch ganz ordentlich laufen. Ich bin mir jetzt halt nicht sicher ob das eine gescheite Lösung ist oder ob doch nicht irgendwo der Wurm drin ist?

[2] Alternative Lösung mit Arrays
---------------------------------------------------------------------
-> User behandelt CSV-Datei wie in [1]

-> Von der CSV-Datei wird ein mehrdimensionales Array als Abbild erzeugt und mit einem aus der DB erzeugten mehrdimensionalen Array verglichen. Evt. mit array_diff()?

Vorteil wäre dabei das dabei nur die wirklich geänderten Datensätze auch per SQL-Statement UPDATE bzw. DELETE bearbeitet würden.
Bei grösseren Datenmengen wäre diese Lösung wahrscheinlich aber langsamer als [1], da es sich bei [1] um reine DB-Operationen handelt und hier aber erst per PHP die Array erzeugt und verglichen werden müssen.

[3] Alternative Lösung mit einzelnen SQL-Statements
---------------------------------------------------------------------

-> User behandelt CSV-Datei wie in [1]

-> Für jede Zeile in der CSV-Datei wird in der Datenbank nach dem entsprechenden Eintrag gesucht. Zur Identifikation dient die ID des Datensatzes.

-> Das Script entscheidet zwischen 3 mögliche Operationen:
   a) Datensatz ist in CSV vorhanden, nicht in DB = Anlegen
   b) Datensatz ist in CSV vorhanden, dito in DB = Update
   c) Datensatz ist nicht in CSV, wohl aber in DB = Löschen

Meiner Meinung nach spricht vom Aufwand und der Performance alles für 1., aber mir ists schon fast zu simpel und ein wenig Holzhammer-Mässig :-) Bei Lösung [2] und [3] bekommt man halt von der DB entsprechende Rückgabewerte wieviel Datensätze angelegt, bearbeitet und gelöscht wurden, das geht halt bei [1] nicht.

Danke mal & Gruss AndreD