Announcement

Collapse
No announcement yet.

Joinen von mehreren großen DataTables mit verschiedenen Kriterien

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Joinen von mehreren großen DataTables mit verschiedenen Kriterien

    Hallo miteinander,

    ich arbeite derzeit an einem Konzept, um folgendes Szenario umzusetzen :

    Ich habe 4 DataTables (ausgelesen aus CSVs und HTML-Tabellen), wovon 3 mindestens mehrere 10.000, später sicher auch mehrere 100.000 Zeilen oder mehr enthalten. Nun muss ich diese DataTables miteinander verknüpfen. Am Ende will ich dann möglichst wieder eine DataTable haben, zumindest muss es ganz am Ende in einer Excel-Tabelle landen - dafür habe ich bereits Methoden, um DataTables zu schreiben.

    Dabei gibt es nicht nur die Bedingung, dass mehrere Spalten einer Tabelle mit denen einer anderen übereinstimmen müssen, was soweit ich mich bis jetzt belesen habe, mit "DataRelations" ginge. Es kann auch in einer Zelle ein * stehen, welcher dann wiederum für jeglichen Wert einer Vergleichszelle der anderen Tabelle als "Match" stehen muss. Die meisten verglichenen Werte sind zudem Strings. LINQ-Joins unterstützen leider auch keine AND oder OR-Operationen.

    Das Programm ist jetzt nicht sonderlich zeitkritisch (soll ein einmal wöchentlich erstellter Report werden), aber trotzdem möchte ich den Zeitaufwand zum Verknüpfen der Tabellen möglichst gering halten. Ich hatte jetzt schon überlegt, das ganze durch Verschachtelung von Dictionaries oder anderweitig mit gehashten Werten zu machen. Das würde dann erst einen Durchlauf aller Tabellen zum Erstellen der Dictionaries/Hash-Werte benötigen und dann ein weiteres durchlaufen der "Basis-Tabelle", um währenddessen die Dictionaries zu durchsuchen und die "Ziel-Tabelle" zu erzeugen. Zudem müsste ich mir ein Konzept überlegen, um das ganze möglichst generisch zu machen, damit auch das Hinzufügen neuer Vergleichskriterien relativ einfach geht.

    Irgendwie sind die Ansätze alle ziemlich komplex und wahrscheinlich auch RAM-intensiv. Vielleicht hat hier jemand eine bessere Idee oder kennt in .NET eine Methode, die bereits ähnliche Funktionalitäten bietet, die ich nutzen kann? Mir würde ja z.B. auch die Verwendung von DataRelations reichen, wenn sie anbieten würden, eine Methode zum Vergleichen mit zu übergeben.

    Danke & Grüße,

    Compu

    /edit : Vielleicht reicht mir auch ein Schlagwort o.ä., ich bin dankbar für jeden kleinen Stups in die richtige Richtung, da das ganze Projekt auch noch diese Woche fertig sein soll...
    Zuletzt editiert von Compufreak; 10.11.2011, 14:40.

  • #2
    Update : Habe gerade von einem Kollegen das Schlagwort der "Linq Extensions" bekommen - werde mich mal darüber belesen. Bin weiterhin offen für weitere Ideen.

    Comment


    • #3
      Mh vielleicht wäre es auch eine Idee die Daten in eine DB zu stopfen die sowas von Hause aus kann. Und die kann das wahrscheinlich auch performanter als selbst geschriebener Code.

      Comment


      • #4
        Danke für den Vorschlag, die Idee hatte ich auch schon (Sorry, vergessen zu erwähnen :0) - Ich war nur nicht so sicher, ob ich unsere produktive Oracle-Datenbank, die sowieso schon teilweise recht umfangreiche Queries zu bearbeiten hat, damit einmal die Woche belasten will... Zumal das wahrscheinlich Montags wäre, wo sie eh schon mit neuen Daten befüttert wird und alle auf sie "losrennen", um sich den aktuellen Stand zu holen. Vielleicht ist der Rechenaufwand dafür auch vernachlässigbar klein, ist glaube ich sogar ein Cluster...

        Ich glaube, ich werde mich mal an der verschachtelten Dictionary-Variante probieren und wenn mir das zu nervig oder unperformant wird, doch auf die Oracle-Idee umsteigen.

        Danke & Grüße,
        Compu

        Comment


        • #5
          Wenn ihr Oracle habt könntest Du es auch mit einer Materialized View probieren. Das ist ein View die in einem bestimmten (ich denke auch konfigurierbaren) Zeitraum geupdatet wird. Dann müsstest Du das Query praktisch nur einmal die Woche gegen die DB laufen lassen. Das ganze könnte auch in der Nacht passieren, da ist sowas ja meist weniger kritisch.

          Comment


          • #6
            Das Problem ist, dass der Report auf einem anderen Report basiert - der wird Montags über den Tag generiert und direkt danach muss der Vergleich angefertigt werden. Das Ergebnis wird sowieso als Excel-File hinterlegt, also da würde auch ein normaler View für reichen... Büßt aber an Konfigurationsoptionen ein. Ist leider Gang und Gäbe, dass sich Requirements von einem Tag auf den anderen ändern...

            Ich habe jetzt schonmal einen schön verwirrenden 50-Zeiler geschrieben, der mir aus meinen Schlüsselspalten (natürlich generisch als params übergeben) und der Tabelle ein paar schick verschachtelte Dictionaries macht. Die sind binnen weniger Sekunden(bruchteile) erzeugt. Die Dictionaries bilden im Prinzip nichts anderes als einen Baum ab, der ganz am Ende Zeilen-IDs stehen hat.

            Jetzt muss ich nur noch das Gegenstück basteln, das durch die Basis-Tabelle wandert und in den Dictionaries nach den passenden Schlüsseln sucht. Ich bin guter Dinge, dass das tatsächlich performanter wird als erst 100.000e von Zeilen nach Oracle zu schaufeln (Selbst mit dem tollen Oracle.DataAccess.BulkCopy, was mir schon sehr geholfen hat.)

            Vielen Dank auf jeden Fall für den Input!

            Comment


            • #7
              Hallo Compufreak,

              es muss doch nicht unbedingt der bestehende Datenbankserver sein oder?

              Hast du nicht die Möglichkeit auf einen bestehenden Server SQL-Exress o. ä. zu installieren und diesen dann verwenden?
              Solche Sachen würde ich auch eher einer Datenbank überlassen.

              Gruß
              derOptimist

              Comment


              • #8
                Eine NoSQL Datenbank könnte auch einen Index bauen. Oder auch eine ganze kleine wie SQLite.

                Comment


                • #9
                  Hallo,

                  leider müsste ich für eine Installation erst unsere IT-Abteilung beauftragen, und denen das Vorhaben zu begründen und auf die Umsetzung zu warten würde meinen Zeitrahmen sprengen...

                  Danke & Grüße,

                  Compu

                  Comment


                  • #10
                    Das ist ja der Punkt dafür brauchst Du keine IT Abteilung. RavendDB kannst Du lokal starten, dafür braucht man keinen riesen Server. Ich glaub für SQLite braucht man nicht mal einen Server, die kann man auch einfach per Code im Arbeitsspeicher erzeugen.

                    Siehe hier:
                    http://www.sqlite.org/about.html

                    Comment


                    • #11
                      Wow, das klingt echt nach dem, was ich suche - ich werde mich mal an SQLite versuchen und berichten - danke Dafür gibt's sogar gleich einen ADO.NET-Adapter

                      Comment


                      • #12
                        Ich wollte mich nur mal zurückmelden und bedanken. Ich habe es jetzt tatsächlich mit SQLite gelöst.

                        Stolpersteine dabei waren vor allem :
                        SQLite kann keine FULL OUTER JOINs. Ich musste dazu einen LEFT mit einem RIGHT Join verknüpfen (siehe Wikipedia etc. ).
                        Wenn man die Datenbank auf der Festplatte schreibt, ist das EXTREM langsam. Ich schreibe jetzt direkt in den RAM, mit DataSource :memory:. Auch dort ist es wichtig, in welcher Größe die einzelnen INSERTS erfolgen - ich habe mit einem commit alle 10 Zeilen die beste Performance erreicht. Nachteil dabei ist natürlich die hohe RAM-Auslastung.

                        Comment

                        Working...
                        X