none
Suche nach Programmcode zur einfachen aber zur Laufzeit indexierten Datenabfrage einzelner Werte RRS feed

  • Frage

  • Hallo und Hilferuf an alle Visual-Basic-Programmierer in Visual-Studio

    Ich suche einen Code und kann ihn nicht finden. Stefan und Olaf Helper haben mir schon Code gegeben (noch mal Dank dafür), der funktioniert auch, tut aber nicht, was ich brauche. Der Code erzeugt gespeicherte Prozeduren, die sich nicht mehr zur Laufzeit ändern lassen.

    Meine Anwendung muss zig-100.000 mal zur Laufzeit gezielt einzelne Zellen aus einer Datenbank mit weit über 10.000 (maschinenerzeugten) Daten abfragen, verarbeiten und dann das Ergebnis an anderer Stelle speichern. Aber immer nur eine einzelne Zelle und immer andere Zellen.

    Da helfen weder Tableadapter noch Datareader und auch keine gespeicherten Prozeduren und der ganze andere Schnickschnack, weil alles erst zur Laufzeit erzeugt und geändert werden muss.

    Früher ging Folgendes:

    Vorausgesetzt z.B. eine Arbeitsmappe Excel sei offen.

    Tab1 und Tab2 seien Tabellen daraus.

    a,b seien die Indizes der Arrayvariablen data(a,b)

    c,d seien Indizes für Spalte und Zeile einer Tabelle.

     

    Abruf des Wertes aus Tabelle Tab1 (Indizes a,b,c,d vom Programm vorgegeben):

    data(a,b) = Worksheets("Tab1").Cells(c,d).Value

    Nach Verarbeitung zurückschreiben in Tab2 mit per Programm geänderten Indizes c,d:

    Worksheets("Tab2").Cells(c,d).Value = data(a,b)

    2 einfache Programmzeilen für den gesamten Datenzugriff und die Sache ist erledigt - immer die gleichen Programmzeilen und das Programm berechnet die jeweils zu verwenden Indizes und Ergebnisse. Und sogar die Tabellennamen könnten indiziert sein.

    Beispiel für die Aufgabe aus der Anwendung zur Verdeutlichung:

    Das Programm ruft die Kohortenstärke der 10-jährigen in der Hauptschule ab. Verarbeitung: Berechnung der erwarteten Todesfälle und derer, die ins Gymnasium wechseln. Zurückschreiben der verbleibenden Hauptschüler und der neuen Gymnasiasten bei den 11-jährigen in die Tabellen für Hauptschüler und Gymnasialsten. Das in allen Bildungsschichten, allen noch lebenden Jahrgängen, Schularten, Berufsrisiken und Gesundheitszuständen .... Daher die vielen Einzelzugriffe.

    Frage und Bitte:

    Gibt es so ein einfaches Verfahren (wie oben aus Vba in Excel2000) für das zur Laufzeit indexierte Auslesen und Zurückschreiben von Daten unter Visual Basic in Visual Studio mit einer dienstebasierten sql-Datenbank? (Voraussetzung: Die Datenbank ist offen).

     

    Danke

     

    Spockspockspock


    Fortschritt ist nicht, das Alte abzuschaffen, sondern das schlechte Alte durch etwas besseres zu ersetzen, das gute Alte aber zu erhalten, bis es etwas wirklich besseres gibt.

    Freitag, 7. Juni 2019 15:48

Antworten

  • Hallo Spock...,

    eine relationale Datenbank wie der SQL Server ist für solche Arten der Verarbeitung ungeeignet. Wenn Du eine Vielzahl (Tausende, Millionen) einzelne Werte abrufst, wirst du erschrecken wie langsam das wird. Insgesamt kann man von dem Vorgehen nur abraten.

    Bessere Lösung wäre ein Rechner mit ausreichend Hauptspeicher, in dem man das Datenmodell zu guten Teilen im Hauptspeicher halten kann.

    Für Berechnungen selbst ist Visual Basic suboptimal ausgestattet und man wird einige Zeilen mehr programmieren müssen. Aber will man es verwenden, sollte man soviel wie möglich auf einmal in Arrays oder Auflistungen laden und nur Zwischen- und Endergebnisse zurück schreiben.

    Leichter zugängliche Bibliotheken gibt z. B. für Python, siehe dazu z. B. Pandas (uam. wie NumPy).Das Einbinden eines MSSQL-Treibers ist einfach (hier gerade häufiger eingesetzt). Python als Sprache ist relativ einfach erlernbar und kann wie Visual Basic mehr oder weniger objektorientiert verwendet werden.

    Ein anderer Weg wäre den SQL Server mit R und/oder Hadoop einzusetzen, was jedoch einiges anders ist als "konventionelles" Programmieren und einen höheren Lernaufwand bedeutet. Siehe auch Erweitern Sie die Analysemöglichkeiten der Open Source-Sprachen R und Python (Das mit dem "Maschinenlernen" sollte man nicht zu eng auslegen, auch deren "Intelligenz" ist zunächst nur Datenauswertung).

    Letztendlich bedeutet alles einiges an Investition und eine mehr oder weniger steile Lernkurve. Dafür sollten sich die Ergebnisse am Ende sehen lassen können ;)

    Gruß Elmar

    Dienstag, 11. Juni 2019 18:41
    Beantworter
  • Moin,

    Microsoft hat in diesem Fall alles richtig gemacht, auch jedes andere relationale DBMS wird genau so agieren. Wenn ein Recordset das Ergebnis einer Select-Abfrage ist, aktualisiert es sich nur dadurch, dass man die Select-Abfrage nochmal absetzt. Sprich:

    • Prozess 1 macht Select für ID=XYZ
    • Prozess 2 macht Update für die gleiche ID
    • Wenn Prozess 2 nun den aktuellen Wert haben möchte, muss er die Select-Abfrage noch mal absetzen.

    Und *dieser* Aufwand wird nicht zu vernachlässigen sein, und zwar bei jedem DB-System.

    Was Du anscheinend suchst, ist die Möglichkeit, ein Array im RAM an eine Datenbank so zu knüpfen, dass Änderungen in der Datenbank automatisch im Array nachgeführt werden. Und das ohne, dass man so viel RAM am Start hätte, wie die Datenbank groß ist ;-)

    Das funktioniert natürlich so nicht, denn woher soll der SQL-Client auch wissen, dass sich auf dem Server etwas geändert hat. Was aber geht, sind Trigger: Bei Änderungen an bestimmten Datenbank-Inhalten werden Aktionen ausgelöst, natürlich in erster Linie innerhalb von SQL. Die kann man aber so gestalten, dass die Client-Prozesse mit wenig Aufwand mitkriegen, dass Änderungen gemacht wurden, und dann die aktualisierten Daten vom SQL Server abrufen, sofern notwendig.

    Den größten Vorteil kannst Du erwarten, wie von Elmar angedeutet, wenn Du mit R oder Hadoop Deine BigData-Aufgabe auch mit BigData-Mitteln löst. Das musst Du aber lernen. Willst Du in der relationalen Welt bleiben, so musst Du die Algorithmen so anpassen, dass die Aufteilung der Aufgaben zwischen mehreren Prozessen eben NICHT erfordert, dass zu jedem Zeitpunkt jeweils aktuelle Daten vorliegen.


    Evgenij Smirnov

    http://evgenij.smirnov.de

    Samstag, 15. Juni 2019 12:10

Alle Antworten

  • Dazu solltest du dir erst mal über das SQL-Datenmodell im klaren sein, wie denn die Excel-Daten nach SQL-Server importiert werden.

    Dann ergibt sich die Abfrage-/Updaterei fast von selbt.

    Und SQL kann man auch native über Command-Objekte mit ExecuteReader und Execute ausfühen.
    Prozeduren sind da unnötig.

    Meine Awendungen bestehen fast immer ohne Prozeduren, da diese, wie du ja festgestellt hast, eben statisch sind.


    • Bearbeitet bfuerchau Freitag, 7. Juni 2019 17:37
    Freitag, 7. Juni 2019 17:36
  • Hallo bfuerchau,

    ich habe mich vielleicht falsch ausgedrückt. Ich habe keine Exceldaten, weil Excel die Modellierung der Daten in der Menge einfach nicht schafft. Ich brauche die Datenbank ansonsten auch nicht, nur zur Aufbewahrung der Daten. Es ist halt eine riesige Aufgabe, einen ganzen Staat mit allen wirtschaftlichen bevölkerungspolitischen technischen gesellschaftlichen und sonstigen Umständen realistisch zu simulieren.

    Ich suche nur einen Weg, so einfach auf Daten in einer sql-Datenbank zuzugreifen, wie das bei Excel geht (oder zumindest in Office2K ging, s. oben). Daten gezielt rausholen und wieder reinstecken, alles andere macht mein Programm zur Laufzeit, weil es nur aus Formeln ohne jede Vorgabedaten oder Annahmen besteht.

    Falls Du weißt, wie das geht oder wo man es findet, bitte schreib es mir. Danke.

    Schöne Grüße

     

    Spockspockspock

    Fortschritt ist nicht, das Alte abzuschaffen, sondern das schlechte Alte durch etwas besseres zu ersetzen, das gute Alte aber zu erhalten, bis es etwas wirklich besseres gibt.

    Samstag, 8. Juni 2019 06:48
  • Da du nicht angibst, ob du SQL kannst: Dies ist die einzige Möglichkeit.
    http://www.datenbanken-verstehen.de/t-sql-tutorial/

    Je nach Programmiersprache gibt es dann unterschiedliche Methoden.
    Beispiel C#:
    Ich gibt es ADO.Net mit Connection/Command-Objekten sowie die Data-Klassen wie DataSet und DataTable.

    Zur Programmierung?
    - Powershell (etwas komplizierter)
    - Visual Studio (Community Edition ist kostenlos)
    - VisualStudioCode
    - u.s.w.

    Eine Einführung findest du bei den jeweiligen Produkten.

    Insgesamt ist SQL sehr viel mächtiger als die Datenmanipulationen via Excel.

    Sonntag, 9. Juni 2019 06:04
  • Hallo bfuerchau,

    entschuldigung. Nein, ich kann kein SQL, auch kein C (nur rudimentär), Java, Python oder was so sonst noch rumläuft sondern nur sämtliche Basic-Dialekte von C64 bis Visual Basic und natürlich Assembler (aber wer macht das heute noch, ist ja auch wirklich mühsam ...) und ich verwende Visual Studio 2019 Community (reicht, weil ich allein arbeite). Meine letzte Datenbankanwendung war 1985 in Open Access unter DOS 3.1 für IBM XT.

    Basic ist für mich vermutlich auch deshalb die beste Sprache, weil es z.B. in C so gut wie unmöglich ist, ein 8-dimensionales Stringarray, dessen Größe sich zur Laufzeit ändert, ohne dass die Daten verloren gehen dürfen, zu verwalten. In Basic pillepalle-babyleicht.

    Die Datenbank brauche ich auch eigentlich nicht, nur zum Aufbewahren der Zwischenergebnisse, weil ich Zukünfte errechne und nicht Vergangenheit untersuche. Sämtliche Vorgänge finden daher zur Laufzeit im Programm und nicht in der Datenbank statt und müssen nur aufbewahrt werden. Es ist aber viel zu viel, um es im RAM zu halten und am Ende sequenziell abzuspeichern.

    Das Einzige, was ich brauche:

    - Einen relationalen Datenspeicher der Mächtigkeit wie MsSQL-Datenbanken mit direktem Zugriff auf jede einzelne Zelle (Zelle, nicht Zeile),
    - einen Wert einer konkreten, vom Programm zur Laufzeit festgelegten Zelle in eine Variable lesen
    - den Wert einer Variablen zur Laufzeit in eine bestimmte vom Programm festgelegte Zelle zurückschreiben.

    Die Datenbank bleibt zur Laufzeit offen und befindet sich auf der gleichen Maschine wie die Anwendung (Desktop für Windows).

    Gäbe es den Befehl 

    open(mydb.xxx) for random as #1

    noch, bräuchte ich die ganze sql-Datenbank nicht, sondern würde meine Datenverwaltung selber schreiben. Aber der wird neuerdings nicht mehr unterstützt. Alles, was irgendwie einfach und praktisch ist, wird abgeschafft!

    Ich brauche also wirklich nur die 2 Befehlszeilen: eine Zelle in eine Variable lesen und eine Variable in eine Zelle schreiben und zwar programmgesteuert, indexiert und zur Laufzeit.

    Falls Du es weißt, würde ich mir gerne das Lernen von SQL ersparen - wenn nicht, muss ich halt ...

    Vielen Dank und schönen Gruß

    Spockspockspock



    Fortschritt ist nicht, das Alte abzuschaffen, sondern das schlechte Alte durch etwas besseres zu ersetzen, das gute Alte aber zu erhalten, bis es etwas wirklich besseres gibt.


    Sonntag, 9. Juni 2019 10:42
  • Ach ja, übrigens:

    Datenbank einschließlich Design, Normalisierung, Indexverwaltung usw kann ich natürlich schon, ich habe meine Datenspeicher immer selbst geschrieben, nur die Sprache SQL kann ich nicht, hab sie nie gebraucht. Und den entsprechenden Befehl "zum Selbermachen" gibt es nicht mehr.

    Spockspockspock


    Fortschritt ist nicht, das Alte abzuschaffen, sondern das schlechte Alte durch etwas besseres zu ersetzen, das gute Alte aber zu erhalten, bis es etwas wirklich besseres gibt.

    Sonntag, 9. Juni 2019 10:52

  • Das Einzige, was ich brauche:

    - Einen relationalen Datenspeicher der Mächtigkeit wie MsSQL-Datenbanken mit direktem Zugriff auf jede einzelne Zelle (Zelle, nicht Zeile),
    - einen Wert einer konkreten, vom Programm zur Laufzeit festgelegten Zelle in eine Variable lesen
    - den Wert einer Variablen zur Laufzeit in eine bestimmte vom Programm festgelegte Zelle zurückschreiben.

    Es gibt in relationalen Datenbanken keine Zellen. Vielleicht in objektorientierten Datenbanksystemen, aber das würde Deinen Horizont endgültig sprengen.

    In SQL brauchst Du einfach eine Indexspalte (was in Excel die Spaltennummer wäre). Diese kann sich mit dem Typ IDENTITY selber beim Hinzufügen neuer Datensätze inkrementieren, oder Du setzt die Werte explizit.

    Hast Du so etwas am Start, dann sind Deine Anforderungen wie folgt erfüllt:

    SELECT <Spaltenname> FROM <Tabelle> WHERE <Indexspalte>=<vom Programm zur Laufzeit festgelegte Zeilennummer>
    
    UPDATE <Tabelle> SET <Spaltenname>=<Wert> WHERE <Indexspalte>=<vom Programm zur Laufzeit festgelegte Zeilennummer> 

    Das lässt sich in nahezu beliebiger Programmiersprache umsetzen. ADO- oder DAO-Schnittstellen irgendeiner Art gibt's überall.


    Evgenij Smirnov

    http://evgenij.smirnov.de

    Sonntag, 9. Juni 2019 14:53
  • Hallo Evgenij.

    Danke. Das funktioniert aber leider nicht so. Wenn man versucht, den Inhalt der - ich nenn es mal Zelle - einer Variablen zuzuweisen, wird der Befehlsstring zugewiesen und nicht das Ergebnis der Abfrage.

    Wenn man den Befehl in eine Stringvariable speichert und dann mit scalar.execute ausführt, bekommt man den Inhalt der Zelle. Z.B. so

    Dim constring As String = "Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=F:\_100_149_IB2S_aktuell\132_Softwareentwicklung\VBA_Staat\Staat\StaatRoot.mdf;Integrated Security=True"
    Dim Connection As New SqlClient.SqlConnection(constring)
    selcom = "SELECT " & Spalte & " FROM StDATABevoelk WHERE ID = @Zeile"
    Dim Command1 As New SqlClient.SqlCommand(selcom, Connection)
    Wert(0) = Command1.ExecuteScalar().ToString()

    Dann wird daraus aber eine statische gespeicherte Prozedur, die man nicht mehr ändern kann (trotz der Variablen @Zeile). Das heißt, daß für jede einzelne Zelle eine extra Prozedur geschrieben werden müßte, was nicht sehr praktisch ist. Außerdem muß ich nicht nur die Zeile sondern auch die Spalte und den Tabellennamen per Programm festlegen lassen.

    Gibt es irgendeinen Weg, diesen Befehl einfach direkt in der Datenbank auszuführen und den Inhalt einer Variablen zuzuweisen so daß der Abfragestring änderbar bleibt?

    Schöne Grüße

    Spockspockspock



    Fortschritt ist nicht, das Alte abzuschaffen, sondern das schlechte Alte durch etwas besseres zu ersetzen, das gute Alte aber zu erhalten, bis es etwas wirklich besseres gibt.


    Dienstag, 11. Juni 2019 17:59
  • Moin,

    ja, damit definierst Du eine Prozedur:

    selcom = "SELECT " & Spalte & " FROM StDATABevoelk WHERE ID = @Zeile"

    Ich dachte da eher an sowas wie

    selcom = "SELECT " & Spalte & " FROM StDATABevoelk WHERE ID = " & Zeile


    Evgenij Smirnov

    http://evgenij.smirnov.de

    Dienstag, 11. Juni 2019 18:31
  • Hallo Spock...,

    eine relationale Datenbank wie der SQL Server ist für solche Arten der Verarbeitung ungeeignet. Wenn Du eine Vielzahl (Tausende, Millionen) einzelne Werte abrufst, wirst du erschrecken wie langsam das wird. Insgesamt kann man von dem Vorgehen nur abraten.

    Bessere Lösung wäre ein Rechner mit ausreichend Hauptspeicher, in dem man das Datenmodell zu guten Teilen im Hauptspeicher halten kann.

    Für Berechnungen selbst ist Visual Basic suboptimal ausgestattet und man wird einige Zeilen mehr programmieren müssen. Aber will man es verwenden, sollte man soviel wie möglich auf einmal in Arrays oder Auflistungen laden und nur Zwischen- und Endergebnisse zurück schreiben.

    Leichter zugängliche Bibliotheken gibt z. B. für Python, siehe dazu z. B. Pandas (uam. wie NumPy).Das Einbinden eines MSSQL-Treibers ist einfach (hier gerade häufiger eingesetzt). Python als Sprache ist relativ einfach erlernbar und kann wie Visual Basic mehr oder weniger objektorientiert verwendet werden.

    Ein anderer Weg wäre den SQL Server mit R und/oder Hadoop einzusetzen, was jedoch einiges anders ist als "konventionelles" Programmieren und einen höheren Lernaufwand bedeutet. Siehe auch Erweitern Sie die Analysemöglichkeiten der Open Source-Sprachen R und Python (Das mit dem "Maschinenlernen" sollte man nicht zu eng auslegen, auch deren "Intelligenz" ist zunächst nur Datenauswertung).

    Letztendlich bedeutet alles einiges an Investition und eine mehr oder weniger steile Lernkurve. Dafür sollten sich die Ergebnisse am Ende sehen lassen können ;)

    Gruß Elmar

    Dienstag, 11. Juni 2019 18:41
    Beantworter
  • Hallo Evgenij,

    danke erst mal. Ich hab beides ausprobliert. Es führt zum gleichen Ergebnis: Egal, was der Variablen 'Zeile' oder '@Zeile' zugewiesen wird: Es wird immer der Wert der Zeile abgerufen, die im ersten Abruf verwendet wurde, auch wenn die Variable längst geändert ist. Deine 2. Variante hatte ich sogar zuerste, habe dann die 1. ausprobiert, weil es nicht funktioniert hat, den tatsächlichen aktuellen Inhalt der Variable Zeile in weiteren Abfragen zu verwenden.

    Scheinbar hat Microsoft (wie eigentlich immer) alles so fürsorglich automatisiert und auf einen bestimmten Zweck hin ausgerichtet, dass wieder einmal nichts mehr geht, was nicht direkt von Microsoft stammt ... .

    Weißt Du einen Weg, wie man die Abfrage bewegen kann, den aktuellen Inhalt von selcom zu verwenden und nicht den, der bei der ersten Abfrage vorhanden war? Mit using habe ich es schon probiert, das nützt nichts, der alte Inhalt bleibt erhalten, auch wenn er innerhalb von using zugewiesen wurde. Danke für die Geduld.

    Schöne Grüße

    Spockspockspock


    Fortschritt ist nicht, das Alte abzuschaffen, sondern das schlechte Alte durch etwas besseres zu ersetzen, das gute Alte aber zu erhalten, bis es etwas wirklich besseres gibt.



    Samstag, 15. Juni 2019 10:14
  • Hallo Elmar,

    danke für die Hinweise.

    Natürlich verwende ich Arrays - mit bis zu 13 Dimensionen übrigens und das zum Teil mit Strings. Ich glaube schon, daß Visual Basic da ganz gut ist - wobei es ein nicht objektorientiertes Basic ohne visual (wie man es früher hatte) genauso, wenn nicht sogar besser täte. C++ kann das jedenfalls nicht vernünftig, wie mir ein Freund gesagt hat.

    Du hast recht, daß ich eigentlich keinen SQL-Server brauche, weil es keine Datensätze in dem Sinn gibt. Aber ich brauche den wahlfreien direkten Zugriff auf jede einzelne Zelle jeder einzelnen Tabelle jeder einzelnen Teildatenbank.

    Die ständige Zwischenspeicherung ist zur Ausfallsicherheit erforderlich, da die Verarbeitung auch auf schnellen Rechnern erheblich Zeit beansprucht. Da daher bis zu 16 Prozesse multitasking berechnet werden um Laufzeit zu sparen und den Prozessor voll auszunutzen spielt die Zeit für Abfrage und Speicherung eher keine wesentliche Rolle.

    Wenn Du ein (Freeware-)Datenbanksystem weißt, das abrufen, speichern, addieren und subtrahieren in der Zelle besser als ein SQL-Server erledigen kann und sonst nichts können muß, das wäre eine echte Hilfe. (Voraussichtliche Größe der Datenbank ca. 2 TB)

    Schöne Grüße

    Spockspockspock


    Fortschritt ist nicht, das Alte abzuschaffen, sondern das schlechte Alte durch etwas besseres zu ersetzen, das gute Alte aber zu erhalten, bis es etwas wirklich besseres gibt.


    Samstag, 15. Juni 2019 10:43
  • Moin,

    Microsoft hat in diesem Fall alles richtig gemacht, auch jedes andere relationale DBMS wird genau so agieren. Wenn ein Recordset das Ergebnis einer Select-Abfrage ist, aktualisiert es sich nur dadurch, dass man die Select-Abfrage nochmal absetzt. Sprich:

    • Prozess 1 macht Select für ID=XYZ
    • Prozess 2 macht Update für die gleiche ID
    • Wenn Prozess 2 nun den aktuellen Wert haben möchte, muss er die Select-Abfrage noch mal absetzen.

    Und *dieser* Aufwand wird nicht zu vernachlässigen sein, und zwar bei jedem DB-System.

    Was Du anscheinend suchst, ist die Möglichkeit, ein Array im RAM an eine Datenbank so zu knüpfen, dass Änderungen in der Datenbank automatisch im Array nachgeführt werden. Und das ohne, dass man so viel RAM am Start hätte, wie die Datenbank groß ist ;-)

    Das funktioniert natürlich so nicht, denn woher soll der SQL-Client auch wissen, dass sich auf dem Server etwas geändert hat. Was aber geht, sind Trigger: Bei Änderungen an bestimmten Datenbank-Inhalten werden Aktionen ausgelöst, natürlich in erster Linie innerhalb von SQL. Die kann man aber so gestalten, dass die Client-Prozesse mit wenig Aufwand mitkriegen, dass Änderungen gemacht wurden, und dann die aktualisierten Daten vom SQL Server abrufen, sofern notwendig.

    Den größten Vorteil kannst Du erwarten, wie von Elmar angedeutet, wenn Du mit R oder Hadoop Deine BigData-Aufgabe auch mit BigData-Mitteln löst. Das musst Du aber lernen. Willst Du in der relationalen Welt bleiben, so musst Du die Algorithmen so anpassen, dass die Aufteilung der Aufgaben zwischen mehreren Prozessen eben NICHT erfordert, dass zu jedem Zeitpunkt jeweils aktuelle Daten vorliegen.


    Evgenij Smirnov

    http://evgenij.smirnov.de

    Samstag, 15. Juni 2019 12:10
  • Ich denke auch, dass du über dein Datenmodell genau nachdenken musst.
    Die einfachste Variante ist die Verwendung von DataTable-Objekten, die einen Zugriff per

    MyTable.Rows[Line][Column] = MyTable2.Rows[Line2][Column2]

    erlauben. Damit hast du schon mal die Excel-Sheetstruktur.
    Leere Zellen kannst du mit DBNull.Value simulieren, das benötigt aber auch grundsätzlich zusätzliche Abfragen.

    Eine DataTable kann schon mal 16 Mio Zeilen aufnehmen, die Anzahl Spalten liegt an der Anzahl möglicher Spalten je Tabelle.
    Eine DataView ist eine Sicht auf eine DataTable, die das Suchen, Filtern und sortierte Bearbeiten erlaubt.
    Vom Grundgedanken kannst du da schon mal ein Modell mit DataTable's aufbauen.

    In der Datenbank (egal welche), baust du korrespondierende Tabellen auf incl. einer Identity-Spalte!
    Diese kannst du per simplen "Select * from Table" in den Speicher laden.
    Somit lädst du die Tabellen, die du für den Rechnvorgang benötigst (es werden ja wohl nicht alle sein).

    Nun kommt der DataAdapter ins Spiel:
    Je DataTable erstellst du einen DataAdapter auf Basis eines Select-Commands, der die Update/Delete/Insert-Befehle automatisch generiert.

    Während du nun also die Tabellen so verarbeitest wie in Excel (mit obigem Zugriff), entstehen halt Änderungen, neue Zeilen oder Löschungen.
    Wenn dann eine Tabelle fertig kalkuliert ist, reicht ein DataAdapter.Update() um sämtliche aufgelaufene Änderungen incl. Insert/Delete auf die Datenbank zu replizieren.
    Das Ganze natürlich immer unter Transaktionskontrolle.

    Mit komplexeren SQL's brauchst du dich nicht beschäftigen, das erledigt der Adapter.

    Soviel zum Grundprinzip.

    Zusätzlich stehen dir per DataTable aber auch berechnete Spalten sowie Aggregierungen und "iif()"-Formeln zur Verfügung.
    Du kannst per DataTable.Select() und DataView.ToTable() sowie DataTable.Clone() auch neue DataTables erstellen lassen.
    Aus einer neuen DataTable extrahierst du dann die Spalten und Typen und baust einen "Create Table" zusammen um die neue Tabelle in die Datanbank zu laden.
    Dazu erstellst du wieder einen DataAdapter und kannst die neue Tabelle in einem Rutsch in die Datanbank schieben.

    Zu guter letzt, da DataTables nicht threadsave sind, musst du dir einen Weg überlegen, wie du den Zugriff über mehrere Threads synchronisierst. Dazu dient dann die Lock-Anweisung:

    object[] Values;

    Lock (MyTable) {
    Values = MyTable.Row[Line].Items;
    }

    ..Tuwas

    Lock (MyTable) {
    for (int Column = 0; Column < Values.length; Column++)
    MyTable.Row[Line][column] = Values[Column];
    }

    Oder was immer du an Berechnungen benötigst. Auch während des DataAdappter.Update() darf keine Veränderung stattfinden.
    Zusätzlich hast du sogar noch Ereignisse auf der DataTable, um auf Änderungen zu reagieren.

    Welche Datenbank?
    Das kommt drauf an, da 2TB mit SQL-Standard nicht gehen, kann es schon mal was kosten.
    Alternativ geht auch die kostenlose Firebird-DB, die durchaus 8-10.000 Inserts/Sekunde, Abhängig von Typ und Anzahl Spalten) errreicht und auf Grund der Komprimierung von Daten durchaus geringere Größen benötigt.

    Vielleicht gibt dir das einen Ansatz.

    Samstag, 15. Juni 2019 13:51
  • Das kommt drauf an, da 2TB mit SQL-Standard nicht gehen, kann es schon mal was kosten.


    How d'ya figure? Alle kostenpflichtigen Editionen von MSSQL können bis 524PB pro Datenbank, sofern das darunter liegende Betriebssystem das bereitstellen kann. Und die Express kommt ja schon aus anderen Gründen nicht in Farage.

    Evgenij Smirnov

    http://evgenij.smirnov.de

    Samstag, 15. Juni 2019 14:13
  • Ja entschuldige mal wiede, ich meinte auch SQL-Express;-).
    Sonntag, 16. Juni 2019 12:27
  • Hallo Spock...,

    zunächst muss ich mich meinen Vorrednern anschließen: Überdenke dein Vorgehen sehr sorgfältig. Denn sonst besteht enorme Gefahr eines Schiffbruchs.

    Eher unwichtig: C++ ist natürlich dazu in der Lage... nur braucht man meist einige Codezeilen mehr. Wie im übrigen so ziemlich jede moderne Sprache mit Arrays gut umgehen kann.

    Bei den von dir angedeuteten Datenmengen: Auf die eingebauten Datenzugriffsobjekte wie DataSet/DataTable und Co. solltest du verzichten, da sie einen deutlichen (Speicher-)Overhead mit sich bringen. Setze besser auf die Basisklassen, beim SQL Server SqlCommand und SqlDataReader.

    Zu Abruf und Speicherung selbst: Arbeite mit Datenblöcken, die du Threads zuordnen kannst. Anstatt Einzelergebnisse in der Datenbank zu speichern, arbeite nach dem Prinzip wie es Hadoop und Co. tun - siehe z. B. MapReduce: Lade die Datenblöcke, verarbeite sie und speichere Zwischen- bzw. Endergebnisse. Selbst wenn Du bei Visual Basic bleiben möchtest, schau Dir die Konzepte von Hadoop und Co. einmal an, die sind auf "Big Data" hin optimiert.

    Sollte es zum Absturz kommen, mache das Ganze einfach noch einmal - denn so oft sollte es nicht crashen und bei (oft häufigeren) Programmfehlern wird man ohnehin von vorne anfangen müssen.

    So kannst du viele Threads auslasten. Mit hausbackenem async/await alleine kriegt man kaum die volle Leistung. Die TPL kennt einige Klassen, mit denen man mehr aus der Hardware kitzeln kann, siehe u. a.: Datenfluss (Task Parallel Library).

    Bei der skizzierten Vorgehensweise ist die Datenbank am Ende nicht so wichtig. Wenn dir kein Budget für einen ausgewachsenen SQL Server zur Verfügung steht, so gibt es Opensource Alternativen, z. B. PostgreSQL. Aber auch NoSQL Datenbanken können eine Alternative sein, z. B. MongoDb oder  RavenDB (entstammt dem .NET Umfeld, siehe auch Ayendes Blog).

    Zum Abschluss: Versuche das Konzept vorher auszuarbeiten. Sich voreilig ins Programmierabenteuer zu stürzen könnte dich sonst manchen Abend und das Wochenende kosten ;)

    Gruß Elmar

    Sonntag, 16. Juni 2019 16:09
    Beantworter
  • Ja auch das ist korrekt.
    Zu Hadoop ist noch ggf. folgendes zu sagen:
    https://www.computerwoche.de/a/alles-was-sie-ueber-hadoop-wissen-muessen,3060299,2
    Die Vorteile können allerdings erst beim Einsatz mehrerer Server und damit verteilter Abfragen eintreten.
    Bezogen auf dein Datenkonzept lisße sich dies auch mit mehreren SQL-Servern erreichen, wenn die Tabellen nicht direkt in einem Bezug stehen. Bei 2TB kann ich mir das eher nicht vorstellen.

    Aber:

    Die Frage ist doch, ob sich jede Zeile einer Tabelle bei den Berechnungen ändert und somit das gesamte Ergebnis wieder persistiert werden muss oder ob sich nur einzelne Zeilen einer Tabelle ändern.

    Bei letzterem bietet die DataTable trotz Overhead schon einige nicht zu verachtende Vorteile.
    Ich habe auch zu schätzen gelernt, dass man ebenso noch mit dem vorherigen Wert noch rechnen kann.
    Wie gesagt, der TableAdapter schiebt nur die geänderten Zeilen in die Datenbank.

    Wenn sich die Tabellen immer komplett ändern, dann bieten sich tatsächlich Array an.
    Hier gibt es normale starre Array's "int[][].. MyArray" oder auch dynamische Arrays "List<Int> MyArray", die eben auch Add/Remove unterstützen.
    Zuguter letzt gibts da auch noch assoziative Arrays "Dictionary<String, int> MyArray".
    Anstatt int kannst du natürlich jeden Variablentyp verwenden.
    Hilfreich sind dann eigene Zugriffsobjekte, die ein Dictionary kapseln.
    Für deine Multidimensionalen Arrays könnte man sich auch in beliebiger Schachtelungstiefe
    "Dictionary<String, Dictionary<String, int>> MyMDArray" einfallen lassen.

    Für den Update zur Datanbank benötigst du dann LOB-Objekte, denn die obigen Objekte lassen sich alle per Serialisierungen in eine Stringvariable ausgeben und wiederherstellen. Hier kann man auch noch Kompriierungen durchführen.

    Was den Grad der Parallelisierung angeht, so ist die Standard "Parallel.ForEach" eine ganz gute Lösung, da diese Implementierung die Anzahl der möglichen Threads der aktuellen CPU's ausnutzt und nicht mehr Threads erzeugt, als die CPU für echtes parallelcomputing hergibt.

    Mit OpenSource kann man i.d.R. ganz gut fahren, was i.W: den privaten Einsatz (also auch firmenintern) angeht.
    Möchte man eine kommerzielle Software erstellen sind aber so manche Lizenzbestimmungen da sehr restriktiv.


    • Bearbeitet bfuerchau Montag, 17. Juni 2019 05:50
    Montag, 17. Juni 2019 05:48
  • Hallo @ all, die sich bemüht haben. Danke für alles.

    Mein Problem ist offensichtlich anders. Es ändert sich immer nur eine einzelne "Zelle" aus einer einzelnen "Zeile" einer einzelnen "Tabelle" so, daß das Ergebnis sofort gespeichert werden muß, alles andere bleibt im RAM. Datenblöcke werden fast nicht abgerufen - nur bei Texten.

    Es ist halt so, wie es immer ist, seit Windows XP funktioniert von Version zu Version immer weniger, seit Windows 10 faktisch gar nichts mehr. Alles, was praktikabel war, existiert nicht mehr. So ist das, wenn ein Programm zu schlau ist und alles selbst bestimmen will.

    ich habe jetzt gemacht, was ich in solchen Fällen immer mache: Ich habe unter Windows 2000 (meiner Meinung nach die letzte voll funktionsfähige und praktische Version von Windows) meine eigene Datenbankanwendung so geschrieben, wie ich sie brauche (direkte Adressessierung jeder einzelnen "Zelle") und kompiliert. Die binde ich ein und es funktioniert so schnell und problemlos, wie man sich unter Windows 10 gar nicht erst vorstellen kann.

    Hätt ich gleich machen sollen.

    Dennoch: Vielen Dank für die Zeit und die Bemühungen, das war wirklich toll von Euch.

    Spockspockspock


    Fortschritt ist nicht, das Alte abzuschaffen, sondern das schlechte Alte durch etwas besseres zu ersetzen, das gute Alte aber zu erhalten, bis es etwas wirklich besseres gibt.


    Mittwoch, 7. August 2019 13:02
  • Hi,

    ich mein das nicht böse aber auf einem Stand von vor 20 Jahren stehenzubleiben ist kein Problem des Fortschritts sondern ein Problem des Entwicklers.

    Zudem ist mir nicht klar, was dein Problem überhaupt mit dem Betriebssystem zu tun haben sollte (außer evtl., dass Du mit VB 4/5 arbeiten willst, was dann mit modernen OS nicht oder nicht richtig funktioniert)

    Du kannst dir auch unter Windows 10 und VS 2019 (also so das aktuellste, was derzeit bei MSFT im Angebot ist) problemlos eine Anwendung erstellen, die zielgerichtet einzelne "Zellen" einzelner "Zeilen" einzelner "Tabellen" anspricht, aktualisiert, ... Aber das erfordert halt, dass man sich auch auf was neues einlässt und nicht mit "kann ich nicht, will ich nicht" "argumentiert".


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET (2001-2018)
    https://www.asp-solutions.de/ - IT Beratung, Softwareentwicklung, Remotesupport

    Mittwoch, 7. August 2019 13:34
    Moderator
  • Was immer du unter Datenbank verstehst, aber deine Beschreibung deutet eher auf Nicht-SQL hin.
    Aber sei's drum.
    Da du wohl in C++ programmierst hättest du das Ganze ebenso auch auf Windows 10 erreichen können.
    Zum Teil verwende ich noch auf Win 8.1 die VB6-IDE für eine 32-Bit-Anwendung noch so lange, bis die dann auch auf .Net modernisiert ist. Aber auch diese funktioniert problemlos auf Win10 und Server 2016 (2019 hat noch keiner unserer Kunden, aber auch da sehe ich kein Problem).

    Um es mit deinen Worten zu sagen: "Das gute Alte" funktioniert auch heute noch mit den neuen Systemen absolut problemlos.

    Mittwoch, 7. August 2019 18:20
  • Hallo bfuerchau, am Ende treffen wir uns ja doch immer wieder.

    Nein, ich schreibe nicht C sonder Visual Basic. Du hast recht, SQL brauche ich eigentlich so notwendig wie einen Kropf, allerdings das, was man früher als "random" bezeichnet hat, also den wahlfreien Zugriff auf jedes einzelne Datum ohne sequentiell oder ganze Blocks, Datensätze oder Zeilen lesen zu müssen brauche ich schon. Und nachdem der Befehl

    open "xxx.dbx" for random as#x

    nicht mehr unterstützt wird, funktioniert das eben nicht mehr. Warum Microsoft den Befehl eingestampft hat, ist mir nicht verständlich, aber vermutlich kann sich in Redmont keiner vorstellen, daß es noch Entwickler gibt, die wissen, wo ihre Daten stehen und sie nicht erst suchen müssen. Wie ich sagte: Inzwischen ist Windows so schlau, daß man es nicht mehr benutzen kann, sondern sich von ihm benutzen lassen muß. Nur leider ist das nicht immer zielführend.

    Übrigens: Schau Dir mal Visual Studio 2019 an - Schockstarre garantiert, was da alles plötzlich nicht mehr geht. Da haben die nämlich die "Segnungen" von Windows 10 umgesetzt und alles rausgeschmissen, was bisher praktisch war, eben z.B. den ganzen open-Dialog.

    Danke und Schöne Grüße

    SpockSpockSpock


    Fortschritt ist nicht, das Alte abzuschaffen, sondern das schlechte Alte durch etwas besseres zu ersetzen, das gute Alte aber zu erhalten, bis es etwas wirklich besseres gibt.

    Mittwoch, 7. August 2019 19:23

  • Du kannst dir auch unter Windows 10 und VS 2019 (also so das aktuellste, was derzeit bei MSFT im Angebot ist) problemlos eine Anwendung erstellen, die zielgerichtet einzelne "Zellen" einzelner "Zeilen" einzelner "Tabellen" anspricht, aktualisiert, ... Aber das erfordert halt, dass man sich auch auf was neues einlässt und nicht mit "kann ich nicht, will ich nicht" "argumentiert".



    Hallo Stefan,

    genau das war meine Frage am Anfang: Wie geht das von Visual Basic aus, genau nur ein Datum zu lesen oder zu schreiben, allerdings mit der Komplikation, daß das Programm zur Laufzeit den 'Speicherort selbst festlegt, aus dem es abfragen oder in den es schreiben will. Und genau das funktioniert nicht. Jedenfalls konnte mir bisher keiner sagen, wie man vermeidet, daß aus einer Abfrage eine gespeicherte Prozedur wird, die sich nicht mehr ändern läßt, so daß man bei jeder einzelnen programmgesteuerten Abfrage eine neue Prozedur erzeugen muß.

    Ich will einfach nur, daß ich ein einzelnes konkretes Datum, dessen Adresse das Programm immer wieder zur Laufzeit festlegt und die jedesmal eine andere, aber eindeutig und bekannt ist, abrufen oder speichern kann ohne ganze Blocks, Datensätze, Zeilen oder sonst was zu lesen und ohne zig-tausend einzelne gespeicherte Prozeduren zu erzeugen, die dann immer wieder aufgerufen werden.

    Old school, ich weiß, aber halt praktisch im Gegensatz zu dem, was heute Stand der Technik ist. Ein Löffel ist zum Suppeessen halt immer noch das Beste, auch wenn er schon vor Jahrtausenden erfunden wurde.

    Schöne Grüße

    Spockspockspock


    Fortschritt ist nicht, das Alte abzuschaffen, sondern das schlechte Alte durch etwas besseres zu ersetzen, das gute Alte aber zu erhalten, bis es etwas wirklich besseres gibt.

    Mittwoch, 7. August 2019 19:38
  • Wenn du mal mitteilen würdest, welche Datenbank du verwendest und welche Zugriffsmethoden dir zur Verfügung stehen?
    Mit SQL und einer SQL-Tabelle ist das eben genauso einfach.
    Erstelle eine Tabelle mit einem Zeilenfeld als Identity als Primary Key und den Spalten die du benötigst (in der Regel eben Namen und keine Array-Indizes).
    Nun unterstützt .Net eben eine Reihe von Standardfunktionen:
    Erstelle eine Commandobjekt mit "Select * from MyTable".
    Erstelle einen DBDataAdapter, dem du das Select-Command zuweist.
    Erstelle ein CommandBuilder-Objekt mit dem Select-Command und lass dir die Insert/Update/Delete-Befehle generieren. Die generierten Befehle weist du dem Adapter zu.
    Erstelle ein DataTable-Object, dass du durch den Adapter befüllst.
    Nun kannst du die Tabelle mit
    MyTable.Rows[RowIndex][ColumnIndex]
    direkt adressieren.
    Per MyTable.Rows.Count kannst du abfragen, ob du genügend Zeilen hast und kannst dann per MyTable.AddRow eine neue Zeile erstellen und der Rows-Auflistung zufügen.
    Wenn deine Tabelle fertig bearbeitet ist, kannst du einfach per Adapter.Update() alle Zeilen in die Datenbank beamen, dabei werden nur geänderte und hinzugefügte Zeilen berücksichtigt.

    Du kannst natürlioch auch einfach Zeilen per Delete aus der DataTable löschen, was dann per DeleteCommand in die DB repliziert wird.

    Allerdings hast du mit einer DataTable erhebliche mehr Möglichkeiten.
    Du kannst berechnete Spalten mit Formeln hinzufügen. Per DataView kannst du sortieren, Filtern und neue Tabellenextrakte erstellen.
    Du kannst per MyTable.Select auch Aggregate berechnen und mittles Linq kann man sogar noch erheblich mehr rausholen.
    Einziges Manko: Eine Tabelle ist auf 16 Mio. Zeilen, die Anzahl Spalten sind anscheinend unbegrenzt (nun ja, durch den Speicher und die DB letztendlich) beschränkt.
    Per DataSet kann man mehrere Tabellen verwalten und Beziehungen definieren.

    Fazit: Ich finde die Möglichkeiten durch das "gute Neue" schon nicht unerheblich!


    • Bearbeitet bfuerchau Donnerstag, 8. August 2019 08:48
    Donnerstag, 8. August 2019 08:46
  • Für alle, die ein ähnliches Problem haben und auch von den falschen Beschreibungen in der VB Sprachreferenz gequält werden: Um eine eigene Verwaltung für Daten in VB zu schreiben brauchst Du nur folgende Befehle:

    Um eine Variable für den Datensatz zu definieren
    Public Structure Strukturname
       Public Feldname as ...
       Public Feldname as ... usw
    End Structure

    Um ein Textfeld fester Länge zu generieren (hier 25 Zeichen):
        <VBFixedString(25)> Public Feldname 

    Um die Variable für den Datensatz zu generieren:
       Dim Variablenname As Strukturname

    Um die Länge des Datensatzes zu ermitteln:
       satz = Len(Variablenname)

    Um die Datei anzulegen oder eine vorhandene zu öffnen (# ist eine beliebige noch nicht benutzte Dateinummer):
       FileOpen(#, "Dateiname.extention", Mode:=OpenMode.Random, RecordLength:=satz)

    Ein Feld des Datensatzes, das Du ansprechen willst kannst Du wie eine beliebige Variable behandeln und heißt:
       Variablenname.Feldname

    Um den Datensatzzeiger auf einen bestimmten Datensatz zu setzen (# = Dateinummer):
       Seek(#, Datensatznummer)
    Nach einer Operation ist der Datensatzzeiger bereits automatisch um +1 verändert.

    Um einen Datensatz in die Datei zu schreiben (vorher seek!)
       FilePut(#, Sender-Variablenname)

    stellst Du den Datensatzzeiger hinter das Dateiende wird der Datensatz angehängt, ansonsten wird der vorhandene überschrieben.

    oder zu lesen

       FileGet(#, Empfänger-Variablenname)

    Um die Datei zu schließen:
       FileClose(#)

    Thats all. Die Behandlung der Daten erfolgt im Programm.
    Datensatznummer und Dateinummer sind Singlevariablen, Du kannst also je 2 Mrd. Datensätze in 2 Mrd. Dateien verwalten ... Das gute Alte ist also auch nicht so schlecht, vor allem ziemlich einfach zu handhaben, wenn man den Überblick nicht verliert.

    Eignet sich, wenn Du Daten nicht sortieren sondern nur verwahren und bei Bedarf wieder aufrufen mußt und aufgrund der Programmstruktur genau weißt, wo Du was findest (dies ist hier mein Problem gewesen, da ich Simulationsergebnisse berechne, die von einer großen Zahl von Entitäten abgerufen und unterschiedlich interpretiert und behandelt werden ohne dass die eine von der anderen etwas weiß. Die Summe der Reaktionen führt zu den neuen Simulationsdaten).

    Der eine oder andere mag jetzt sagen "EDV zu Fuß", stimmt aber nicht. Ist gemeinsam mit Kontrollstrukturen unschlagbar einfach zu handhaben und superschnell ohne jeden Overhead.

    Die Datei ist eine Textdatei, mit der Abweichung, dass jeder einzelne Datensatz direkt ohne Suche gegriffen werden kann, egal wo er steht, und sie ist nur bei Texten aber nicht bei Zahlen im Editor lesbar. Kann aber ganz normal (auch transparent) verschlüsselt werden, wie jede andere Textdatei auch.

    Schöne Grüße und Dank an alle, die sich bemüht haben

    Spockspockspock


    Fortschritt ist nicht, das Alte abzuschaffen, sondern das schlechte Alte durch etwas besseres zu ersetzen, das gute Alte aber zu erhalten, bis es etwas wirklich besseres gibt.

    Dienstag, 12. November 2019 16:52
  • Warum soviel Arbeit?
    Schau dir die ADODB-Bibliothek an (gibts seit Windows98).

    Du erstellst ein ADODB.Recordset, fügst der Feldauflistung die Felder mit Typ zu und öffnest das RS.
    Nun kannst du Zeilen hinzufügen, editieren, löschen, Suchen, Filtern und sortieren.
    Schnelles Positionieren mittels Bookmark oder AbsolutePosition.

    Bestimmte Felder kann man mittels "RS(Field).Properties("Optimize") = true" einen Index verpassen, so dass die Find-Methode eine Zeile schneller findet.

    Du kannst das RS deinen Forms-Objekten als Datasource zuordnen und mittels Editoren bearbeiten lassen.
    Du kannst auch Sheets aus RS befüllen und zurückladen.

    Zu guter letzt gibt es noch RS.Save und Load um ins Filesystem zu schreiben und wieder zu lesen:
    https://www.devguru.com/content/technologies/ADO/recordset-save.html

    Das ist zwar auch schon alt, funktioniert heute immer noch und vor allem sauschnell!

    Dienstag, 12. November 2019 18:01
  • Hallo bfuerchau,

    danke für den Hinweis. Ich kenne das. Aber Data- oder Recordsets helfen mir bei meiner Aufgabe grundsätzlich nicht weiter.

    Ich versuch es zu erklären. Mein Auftag ist, die gesellschaftliche Entwicklung innerhalb eines Staates ausschließlich aufgrund von Formeln ohne jede Prämisse oder Annahme zu simulieren. Dazu gibt es die Systeme, die es in jedem Staat gibt und Regeln nach denen sie funktionieren. Die Gesellschaft ist in Gruppen aufgeteilt, die sich einigermaßen homogen benehmen. Z.B. Bildungsschichten, Einkommensschichten, Krankheiten, Religionsgruppen usw. Die überschneiden sich natürlich mehr oder weniger und schaffen ganz schnell etliche hundert Gruppen. Das erledigt bereits das Programm. Diese Gruppen entnehmen getrennt voneinander Informationen unterschiedlich schnell unterschiedlich gut, bewerten sie unterschiedlich gut und reagieren darauf. Auch das per Programm. Die Folgen dieser Reaktionen verändern die Grunddaten innerhalb der Formeln, die die Regeln der Gesellschaft darstellen.  Auf diese Weise wird zunächst eine virtuelle Gesellschaft errichtet, die einem bestimmten Staat abbildet z.B. Deutschland. Das ist der Startzustand. Nun wird in die Regeln durch eine Entscheidung eingegriffen. Das Programm simuliert nun über z.B. 20 Jahre die Ursprungsgesellschaft und die veränderte Gesellschaft und stellt die entstehenden Unterschiede dar.

    Ziel meines Auftraggebers, ein NGO, ist es, die Folgen politischer Entscheidungen im Vorfeld überprüfbar zu machen und damit die Meinungsherrschaft den Ideologen und Dogmatikern zu entziehen.

    2 Beispiele habe ich zuletzt simuliert, wobei es hier nur um die Schule geht. Frage:

    Bei welcher Klassengröße bringt die Grundschule die besten Ergebnisse, also den insgesamt sinnvollsten Bildungsstand? Überraschendes Ergebnis: 42 Schüler. Überraschender Grund: Je mehr Zeit der Lehrer für den einzelnen Schüler hat, desto mehr fördert er die Unbegabten und die Begabten bleiben hinter ihren Möglichkeiten zurück. Bei nur 20 Schülern schaffen zwar mehr die Schule ohne durchzufallen, aber die Zahl der Begabten, die das Gymnasium und den Hochschulabschluss erreichen, sinkt. Mein Ergebnis: Große Klassen (ca. 40) bringen 20% mehr Master als kleine (ca. 20)

    Die 2. Frage war: Was ist besser für den Bildungsstandard. Wenn gute Schüler aus der Hauptschule herausgenommen und in eine höhere Schule gegeben werden (wie bei uns derzeit), oder wenn alle eine in einem Zug bis zum Doktorgrad durchgehende Schule beginnen und die, die nicht mehr mitkommen, in eine einfachere Schule heruntergestuft werden? Auch klare Antwort: Möglichkeit 2. Grund: Viel mehr Schüler bildungsferner Eltern werden nicht herausgenommen und erreichen das Studium, als Kinder solcher Eltern aus der Hauptschule herausgenommen und auf das Gymnasium geschickt werden.

    Du verstehst, warum ich mit dem ganzen Zeug ob nun ADO oder ODBC oder SQL nicht viel anfangen kann?  Die Gruppen handeln autonom, ziehen Informationen und reagieren darauf und verändern damit die Ausgangsbasis. Die gespeicherten Daten müssen daher bei jedem Zugriff aktuell sein, aber ohne dass es bereits alle wissen, sondern nur die, die schon nachgesehen haben. Ich kann nicht einmal voraussehen, welche Gruppen sich schon gebildet haben und noch bilden und wie sie sich entwickeln. Deshalb brauche ich einen Zugriff, der sich selbst steuert und das ist bei der von mir beschriebenen Methode halt möglich.

    Trotzdem vielen Dank für Deine Hinweise

    Spockspockspock


    Fortschritt ist nicht, das Alte abzuschaffen, sondern das schlechte Alte durch etwas besseres zu ersetzen, das gute Alte aber zu erhalten, bis es etwas wirklich besseres gibt.

    Dienstag, 12. November 2019 20:55
  • Ist gemeinsam mit Kontrollstrukturen unschlagbar einfach zu handhaben und superschnell ohne jeden Overhead.

    Sorry, aber nichts, was VisualBasic tut oder jemals getan hat, ist ohne Overhead oder "superschnell". Dass Du als VB-Programmierer den Overhead nicht in Deinem Quellcode siehst, heißt nicht, dass es ihn zur Ausführungszeit nicht gibt.

    Nur mal interesseshalber und bitte sei ehrlich, niemand hier wird beißen: Wieviele Millionen Zeilen hatte der Datensatz für Deine Schulsimulation, bei welcher Satzlänge, und auf was für einem Datenträger lag die Datei während der Verarbeitung?


    Evgenij Smirnov

    http://evgenij.smirnov.de

    Dienstag, 12. November 2019 22:06
  • Hallo,

    wenn man es im Interpreter laufen läßt hast Du recht aber als Compilat?

    Die Schulsimulation ist relativ einfach und benötigt nur eine niedrige 5-stellige Zahl von Programmzeilen und konnte im RAM laufen. Sie benötigt nämlich auch nur wenige Regeln und Simulatoren, nämlich das Schulsystem, Auftrag und Verhalten von Lehrer und Schüler und einen Jahrgang. Das heißt, daß Bevölkerungsentwicklung, Wirtschaftsentwicklung, Justiz und vieles andere mehr verzichtbar sind und entfallen können, weil es sich auf das Ergebnis nicht auswirken würde. Die Datensätze halte ich durch einen hohen Normalisierungsgrad und starke Aufteilung auf viele Arrays (im RAM) bzw. viele Dateien (auf Datenträger) klein.

    Die Verwendung von Regeln in Form von Formeln reduziert übrigens den Programmieraufwand drastisch, macht aber die Ergebnisse für den Programmierer unvorhersehbar und damit unmanipulierbar. Es kommt eben raus, was eben rauskommt, ohne daß man es beeinflussen kann.

    Die Simulation lief compiliert auf einem i7-3820 gut 2 Stunden für 20 Jahre und Klassenstärken von 15 - 60 Schüler in der 1. Klasse in 1-er-Schritten und einen Schülerjahrgang mit 10.000 Schülern unter Zugrundelegung des bayerischen Schulsystems. Frage war, bei welcher Klassenstärke erreichen die meisten Schüler einen Universitätsabschluß. Ergebnis: Wenn die Klassenstärke über alle Schuljahre so nahe wie möglich an 42 Schülern gehalten wird. (Beginn mit 238 Klassen, die dann reduziert werden um die Klassenstärke aufrecht zu halten)

    Ich hab das als Test verwendet, ob mein Ansatz funktioniert und er tut es offensichtlich. Mehr darf ich dazu allerdings nicht mehr mitteilen, sonst bekomme ich Ärger mit dem Auftraggeber ...

    Schöne Grüße

    Spockspockspock


    Fortschritt ist nicht, das Alte abzuschaffen, sondern das schlechte Alte durch etwas besseres zu ersetzen, das gute Alte aber zu erhalten, bis es etwas wirklich besseres gibt.

    Mittwoch, 13. November 2019 08:40
  • "Wenn die Klassenstärke über alle Schuljahre so nahe wie möglich an 42 Schülern gehalten wird."

    OT:

    Nun ja, da nun mal 42 die Antwort auf die Frage aller Fragen ist, halte ich das Ergebnis eher für eine Trockenübung.
    In NRW nähern sich die Klassen dieser Zahl aber immer weniger schaffen tatsächlich einen sehr guten Abschluss.
    In Bayern entfernen sich die Klassen dieser Zahl aber immer mehr schaffen einen sehr guten Abschluss.

    In NRW heißt es: wir nehmen jeden mit und lassen keinen zurück, also alle auf die Uni.
    In Bayern heißt es: nur die Besten kommen weiter.

    Nach deinen Berechnungen sollte Bayern das Schulsystem NRW's übernehmen.
    Dann käme NRW endlich relativ besser weg;-).

    Mittwoch, 13. November 2019 16:17
  • Hallo,

    daß das auch 42 sind ist reiner Zufall.

    Zu den "sehr guten Abschlüssen". Die Abiture werden immer besser, aber die Studenten immer schlechter. Ich habe "ein bischen Zugang" zur Uni Regensburg. Die Professoren der MINT-Fächer an der Uni Regensburg stellen fest, dass ein erheblicher und immer größer werdender Teil der Abiturienten nicht studienfähig ist. Bayerische 1er-Abiturienten, die in Cambridge oder Oxford studieren wollen, werden dort als studienunfähig abgelehnt. Die Mathematikfakultät braucht  bis zu 2 Semester, um den ach so guten Abiturienten das beizubringen, was zu meiner Zeit ganz selbstverständlich Abiturstoff war. Stetigkeit und Kurverndiskussion, Limes von Funktionen usw - heute alles Sache der Uni. Ausnahme ist einzig das Goethe in Regensburg, wo die Leute schon mit Beginn der Oberstufe zum Frühstudium an der Uni zugelassen werden. Soviel zu den "guten" Abschlüssen. Natürlich wird bei großen Klassen ausgesiebt, es kommen insgesamt weniger durch, aber mehr von den Guten. In kleinen Klassen versacken eben auch viele Talente durch Unterforderung, weil "jeder mitgenommen wird. Das ist mein Simulationsergebnis und stimmt mit der Praxis an der Uni überein.

    Schöne Grüße

    Spockspockspock


    Fortschritt ist nicht, das Alte abzuschaffen, sondern das schlechte Alte durch etwas besseres zu ersetzen, das gute Alte aber zu erhalten, bis es etwas wirklich besseres gibt.

    Mittwoch, 13. November 2019 17:38
  • Ich glaube da können wir ewig drüber diskutieren.
    In NRW haben die Lehrer überhaupt keine Zeit mehr um bei großen Klassen noch zu Sieben.
    Da wird dann per Beschluss der Klassendurchschnitt auch schon mal um 1 Note angehoben.
    Daher gibt es auch bei uns halt immer mehr 1er die außer Wisch+Click nicht mehr viel können.

    Und was ist sieben mal sieben?
    :
    :
    :
    Ganz feiner Sand!

    Mittwoch, 13. November 2019 18:26
  • Alles klar, hast Recht, kann man relativ lang diskutieren. Hab auch noch einen:

    Frau eines Mathematikers kriegt ein Kind. Die Hebamme gibt es zuerst ihm. Fragt sie: Ist es ein Junge oder ein Mädchen? Darauf der Mathematiker völlig zurecht: Die Behauptung ist wahr.

    Schönen Abend

    Spockspockspock


    Fortschritt ist nicht, das Alte abzuschaffen, sondern das schlechte Alte durch etwas besseres zu ersetzen, das gute Alte aber zu erhalten, bis es etwas wirklich besseres gibt.

    Mittwoch, 13. November 2019 20:31
  • Das ist halt der Unterschied zwischen sprachlicher und mathematischer Logik;-).
    Aber das Ergbins stimmt.

    Frei übersetzt heißt das:
    Ist eine Aussage wahr oder falsch? Antwort Ja.

    Das ist immer das schöne bei Gerichtssendungen:
    Bitte antworten Sie auf meine Frage nur mit Ja oder Nein. Die Folge? => Immer schuldig im Sinne der Anklage.

    Mittwoch, 13. November 2019 22:16