Autor Beitrag
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: So 24.02.13 12:41 
Moin


ich schreibe gerade an einer Methode, die dafür gedacht ist, die Daten eines Objekts in die dafür passende Tabelle zu schreiben, unter der Beachtung, dass die bereits gegebenen Objekt-Attribute nicht den gleichen Wert aufweisen, wie die entsprechende Datenspalte.

Das heißt, in dem WHERE-Block steht die ID des Objekts als Bedingung und ansonsten soll die Daten-Zeile danach aussehen, wie das Objekt.

Die Frage dabei ist jetzt allerdings, wie ich die Anforderungen möglichst gering halten kann.

Ist es da sinnvoll, erst einmal die Datenzeile mit dieser ID abzurufen und dann nur die Daten an den SQL-Server zu senden, die am Ende geändert werden sollen, oder ist es effektiver, die gesamten Daten des Objekts direkt an den Server zu senden und dann einfach komplett überschreiben?

Bei der ersten Methode muss die Datenbank zwar einen ganzen Datensatz abrufen, aber eventuell nur wenige Daten wirklich überschreiben.
Bei der zweiten Methode muss die Datenbank nichts abrufen, dafür aber in jedem Fall alle Daten überschreiben.
Oder nehmen sich die beiden Wege nichts?

Wichtig ist vielleicht noch, dass bei den Datensätzen auch Bilder und ähnlich große Daten-Mengen dabei sein können, daher mache ich mir da überhaupt Gedanken. ^^


Beste Grüße ^^
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: So 24.02.13 14:19 
Zitat:
Bei der ersten Methode muss die Datenbank zwar einen ganzen Datensatz abrufen, aber eventuell nur wenige Daten wirklich überschreiben.


Aber du muss die Daten dahin transportieren wo du denn Vergleich auf Änderung machst und du musst dafür sorgen das sich der Dateninhalt zwischen prüfen und tatsächlichem schreiben nicht mehr ändert. Es ist in solchen Fällen oft hilfreich ein berechnetes Feld zu hinterlegen (Timestamp, GUID, Counter der letzten Änderung, Hash der Daten etc.) gegen das man beim update leicht prüfen kann unabhängig davon wie groß ein Datensatz wirklich ist. Je nach Änderungswahrscheinlichkeit der Daten musst du dann entscheiden ob testen oder plattes überschreiben sinnvoller ist. Hängt vollständig davon ab wie wahrscheinlich es ist das sich die Daten in der DB zwischenzeitlich geändert haben.
Palladin007 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: So 24.02.13 15:10 
Zitat:
Aber du muss die Daten dahin transportieren wo du denn Vergleich auf Änderung machst und du musst dafür sorgen das sich der Dateninhalt zwischen prüfen und tatsächlichem schreiben nicht mehr ändert.


Stimmt, daran hab ich nicht gedacht ...

Aber dass sich die Daten zwischenzeitlich ändern, ist denke ich mal eher unwahrscheinlich.

Die Software soll dazu dienen, private Medien-Dateien zu verwalten und die Datenbank liegt daher auch lokal auf dem Rechner. Andere Clients greifen also gar nicht darauf zu und zwei parallele Zugriffe auf den selben Datensatz würden dann beispielsweise nur vorkommen, wenn die Anzahl, wie oft ein Titel gespielt wird, sich zu selben Zeit ändert. Aber ich denke mal, das löse ich so, dass das Counter-Update erst dann los geschickt wird, wenn das Objekt, welches den betreffenden Titel beschreibt, in keiner weiteren Datenbank-Verbindung verarbeitet wird.
Ganz sicher ist das nicht, da prinzipiell zwei Objekte den selben Datensatz beschreiben können, aber da ja nur ein Client darauf zugreifen kann, wird das nicht mehr so das Problem sein, denke ich.



Zitat:
Es ist in solchen Fällen oft hilfreich ein berechnetes Feld zu hinterlegen (Timestamp, GUID, Counter der letzten Änderung, Hash der Daten etc.) gegen das man beim update leicht prüfen kann unabhängig davon wie groß ein Datensatz wirklich ist.


Meinst du damit, dass ich dann z.B. ein TimeStamp-Feld anlege, das die letzte Änderung des Datensatzes beinhaltet und das Gegenstück innerhalb des Objektes wird immer aktualisiert, wenn eine Eigenschaft geändert wird?
Das bringt mich auch gleich auf die Idee, zu jeder Eigenschaft noch einmal extra Informationen zu speichern, die nur angeben, ob die Eigenschaft nach dem letzten Datenbank-Update geändert wurde, das lässt sich ja einfach mit einer kleinen Klasse lösen, die das Eigenschafts-Objekt und eine Eigenschaft vom Typ boolean beinhaltet.



Meintest du das so, oder ähnlich?

Der Großteil meiner Erfahrungen mit SQL beruht sich leider nur auf die Theorie, das versuche ich ja gerade zu ändern. :D



Grüße ^^
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: So 24.02.13 17:31 
Zitat:
Meinst du damit, dass ich dann z.B. ein TimeStamp-Feld anlege, das die letzte Änderung des Datensatzes beinhaltet und das Gegenstück innerhalb des Objektes wird immer aktualisiert, wenn eine Eigenschaft geändert wird?


So in der Art. Wenn du an einem Einzelplatz System schraubst sollte das ausreichen. Da Timestamps nicht 100% vergleichbar sind und Änderungen auch natürlich zeitgleich oder zumindest fast zeitgleich stattfinden könnten hätte ich normalerweise eher für etwas zufällig generiertem wie einer GUID pladiert der sich eindeutiger vergleichen läßt. In einem verteilten System sollte der Timestamp natürlich auch aus der Datenbank kommen und nicht vom Client.
Palladin007 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: So 24.02.13 17:36 
Ok, dann setze ich das gleich mal um.

Danke für deine Hilfe ^^
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: So 24.02.13 17:43 
user profile iconPalladin007 hat folgendes geschrieben Zum zitierten Posting springen:
Das bringt mich auch gleich auf die Idee, zu jeder Eigenschaft noch einmal extra Informationen zu speichern, die nur angeben, ob die Eigenschaft nach dem letzten Datenbank-Update geändert wurde, das lässt sich ja einfach mit einer kleinen Klasse lösen, die das Eigenschafts-Objekt und eine Eigenschaft vom Typ boolean beinhaltet.
Exakt, das ist die Vorgehensweise von ADO.NET und O/R-Mappern: In jedem Datenobjekt ein Dirty-Flag mitführen, bei Änderungen setzen und beim UPDATE zurücksetzen. Timestamps oder GUIDs in der DB brauchst du nur, wenn du Kollisionen von parallelen Updates tatsächlich erkennen und darauf reagieren willst.

_________________
>λ=
Palladin007 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: So 24.02.13 18:03 
Na dann bin ich ja auf dem richtigen Weg ^^

Ich wollte das nämlich bewusst ohne ADO.Net schaffen, zumindest mit so wenig wie möglich.
Techniken zur Vereinfachung kann ich dann ja immer noch üben, aber bisher sind meine Übungs-Projekte immer im Sand verlaufen, weil ich zu viel Zeit mit ADO.Net verbracht habe, irgendwie finde ich es da einfacher, schlicht SQL-Befehle an die Datenbank zu schicken und die Klassen eigenhändig so untereinander zu verknüpfen, wie es mir passt. ^^