![]() |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Zitat:
Aber woher soll der Fragesteller wissen, dass unter den ersten 3 schon eine gute Antwort war. Ok, jetzt weiß er es, zumindest kennt er Deine Einschätzung nun. Das wäre ein cooles Feature, wenn irgendwo so KI mäßig ein Pfeil erscheint => gute Antwort! :lol: |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Da ich mich mit dieser Materie bis lang noch nie Auseinander setzen musste erhoffte ich mir einen Rat von Leuten die täglich bzw mehr damit zu tun haben.
Ich bin ja bereits am Lesen der verschiedensten Dokumentationen und stelle keine Fragen mehr. Eine DB anlegen mit 450k Datensätzen, nur mal so zum probieren um am Ende herauszufinden das es doof ist wollte ich verhindern aber okay, dann eben so. Danke auf jeden Fall für all Eure Meinungen! |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Zitat:
Und das Einfügen der Datensätze wird ja hoffe ich mal nicht von Hand geschehen sondern automatisiert. Dementsprechend sollte das auch nicht ewig dauern. Falls doch dann teste halt erst mal nur mit 100k. Ich denke ab nem gewissen Punkt helfen Ratschläge und das Lesen von Anleitungen/Dokumentationen/Tutorials nur noch bedingt und das einfachste und effektivste ist einfach mal loszulegen und zu probieren. Wenn man dann ein (besseres) Gefühl für das Problem entwickelt hat kann man ja durchaus wieder Informationen und Ratschläge suchen die mit der neuen Erfahrung wahrscheinlich ein ganzes Stück hilfreicher sind als zuvor :) |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Also auch nochmal meinen Senf dazu:
Die eigentlichen Daten werden getrennt von den Blobs abgelegt. Je Bild wird die MD5-Checksumme errechnet, das geht bei den kleinen Bildern schnell, entsprechendes liefert Delphi. Die Bilder kommen in Blobs einer Tabelle, die neben dem Blob nur noch die MD5-Checksumme hat. Da kommt ein eindeutiger Index drauf. Doppelte MD5-Checksummen weisen auf identische Blobs hin, die brauchen wir nicht. Der Datensatz, zu dem ein Blob gehört, enthält ebenfalls die MD5-Checksumme. Wird nun für einen Datensatz das Bild angefordert, so nimmt man aus dem Datensatz die MD5-Checksumme und sucht in der "Blob-Tabelle" und hat sein passendes Bild. Die Beschreibung dessen, was gemacht werden muss, ist vermutlich deutlich länger, als der zur Umsetzung erforderliche Quelltext. Gehören mehrere Bilder zu einem Datensatz, dann muss man sich noch eine "Zwischentabelle" machen, die einerseits den Schlüssel der Daten enthält und daneben die MD5-Checksumme des Bildes. Damit kann man dann das 1:n-Verhältnis zwischen Daten und Blobs aufzulösen. 450.000 * 15 kb = 6.750.000 kb = ca. 6.750 MB oder knapp 7 Gigabyte + unbekannter Verwaltungsoverhead der Datenbank. Das ist in heutiger Zeit keine so exorbitante Datenbankgröße. Und ja: Der Vorschlag zu testen ist sinnvoll. Und wenn nur mal die weiter oben vorgeschlagenen minimale Tabellenstruktur erstellt wird und dann ein Bild 100 oder 200k mal in die Datenbank gepumpt wird, mit 'nem erstmal nur Autoinc (oder ähnlichem) als eindeutigem Schlüssel. Und dann mal ein paar hundert Selects drauf loslassen und schauen, wie lange die Antwortzeit so ist. Und dann mal schauen, wie schnell oder langsam das Einfügen weiterer Kopien des Blobs wird. (Da die Blobs im Produktivbetrieb aber nur einmal erstellt werden, dürfte eine Zeitverzögerung beim Speichern aber immernoch im akzeptablen Bereich bleiben.) Und wenn dieser Minimalaufbau zu Ergebnissen führt, die inakzeptabel sind, dann weiterforschen. Meine tausende Texte in Blobs dauern, wenn etwas größer, schon ein bisserl beim Speichern, das Lesen ist (fast vernachlässigbar) schnell und alles liegt in einer Datenbankdatei, keine Trennung von Daten und Blobs in irgendeinen anderen Bereich (oder sowas), alles in der einen Datenbankdatei. Da die Bilder nur einmal in die DB geschrieben werden sollen, und dann nur noch gelesen werden, würd' ich mit Firebird ein insgesamt schnelles System, mit relativ wenig Programmmieraufwand, erwarten. |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Ich habe das mal getestet und du brauchst dir keine Sorgen zu machen.
FB 2.5.4 32-bit (Affinity Mask 14) oder einfach Classic Server verwenden Schätze aber 2 CPUs genügen oder sogar eine. Delphi 10.2 - FireDAC Nur mit Command einfach alternierend ein Bild zu 21k und eines zu 4k einfach mit LoadFrom File reingeladen in die zuvorganannte Tabellenstruktur. Commit nach 10k Sätzen und Transaktion neu gestartet. Größe ca. 7,5GB. Sind so 250k Sätze im Moment. Pro 1000 Sätze ca. 3 Sekunden leicht zunehmend ab 100k. DB über TCP (auf lokalen Rechner) 4 Sek. DB über Locales Protocol 3 bis 3,5 Sekunden im Schnitt. und die DB ist nicht von den Einstellungen her optimiert. Zuerst degradete die Performance vermutlich da Windows die Festplatte mitformatierte. Jetzt habe ich noch ein paar dazugeladen und die DB hat 9GB. Macht keinen Unterschied. Blobs in eigenem Table mit PK Spalte MD5. Zitat:
|
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Hier meine Theorie an der ich nun arbeite sie in die Praxis umzusetzen damit ich testen kann ohne hier fragen dazu zu stellen, dafür gibt es die Doku und um diesen Thread zu beenden.
Ich setze hier an: Dll bekommt Handle + "Namen" + Boolean DB öffnen/Verbinden in DB nach "Namen" schauen, gibt es den oder noch nicht. Wenn noch nicht dann einen neuen Datensatz anlegen. Wenn doch dann CRC von "Namen" (Original Datei) errechnen und mit CRC aus DB für "Namen" kontrollieren. Ist CRC gleich dann Bild aus DB an Funktion als Result. <<<<-- darum geht es mir im Eigentlichen Sinne, das ersparen einer Neuberechnung eines Bildes Ist CRC falsch dann ein neues Bild berechnen und das in DB ersetzen + als Result setzen. <<<<-- und hierbei habe ich bei so vielen Datensätzen Angst Boolean mit einbeziehen da zwei verschiedene Bilder da sein könnten. DB schließen/Verbindung Trennen Einzige Funktion dir User erhalten soll ist ein "ReCreate" o.ä. um nur noch "lebendige" Records zu behalten. Ende im Gelände. |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Wie oft wird die DLL aufgerufen?
DB-Verbinden und DB-Schließen dauert auch seine Zeit. DLL-Aufruf sporadisch, dann ist das ok. Eher "Dauerbetrieb", also permanente Zugriffe seitens der DLL auf die DB: Dann beim Laden der DLL die Datenbankverbindung herstellen und erst, wenn die DLL aus dem Speicher entfernt wird, die Verbindung schließen. |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Aufruf ist sporadisch aber den Tipp werde ich dennoch so umsetzen, das finde ich gut, Danke Delphi.Narium!
|
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Firebird ist gut geeignet, aber Sqlite3 womöglich genauso.
Interessant wäre ein Performancevergleich von beiden für deinen speziellen Fall mit Blobs. Beide Engines sollten den Speicher dynamisch nutzen, und gute Performance abliefern. Rollo |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Puh, noch mehr Hausaufgaben, Danke für SQLite3 Hinweis, mehr zu lesen, bald platze ich :)
|
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Zitat:
|
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Erste Tests mit MyBase/TClientDataSet werden arg langsam bei Datensätzen jenseits von 10k, das erschien mir am einfachsten zu Testen und fällt bei mir als Möglichkeit raus, Perfomance Vergleiche zwischen Firebird und SQLite finde ich nur veraltete, werde da auch meine Eigenen Tests erstellen aber wenn Du einen Hinweis/Link hättest der verschiedene Freie DBs vergleicht schau ich da auch gerne mal rein.
|
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Firebird ist de facto eine gute Wahl für Blobs in der Datenbank, Referenzen ins Filesystem speichern ist lustig, aber Unsinn, wenn man mit richtig großen Datenmengen zu tun hat.
Auch die schönste Directory Struktur, die vermeidet das man 1 mio Dateien in einem Verzeichnis hat, ist durch den Super DAU User mit der Maus schneller verschoben als man denkt und dann findet man nix wieder. Es hindert auch nur ein Readonly Verfahren oder NAS Techniken einen daran, davon einfach Dateien zu löschen. Speziell die NAS Technik geht dabei extrem auf die Performance. Von interessierter Verschlüsselungstrojanern, die gerne mal alle erreichbaren Dateien in allen Laufwerken encrypten rede ich da jetzt noch mal gar nicht. Wir haben in einer Produktivdatenbank beim Kunden ca 300 GB PDFs und passende Png Previews der erste Seite, sind insgesamt ca. 900000 Images und 900000 Pdfs. Sicherlich lässt sich die DB nicht so einfach backup/restoren, aber wir haben die auch aufgeteilt in Daten bis inkl 2017 (die db ist readonly, hat ca 250GB und muss nur ein mal pro Jahr gesichert werden) und in eine aktuelle Jahres DB, in der alle Dateien aus dem aktuellen Jahr landen. Diese wird täglich gesichert (und durch Replikation transaktionsecht auf 2 Servern gespeichert, aber das ist ein anderes Thema). Ende 2018 werden wir dann ggf die DB von Ende 2017 wieder Readwrite machen, die Daten aus der 2018 DB dahin verschieben und danach die große als neue 2018 DB wieder Readonly setzen. Den Zugriff auf die Inhalte machen wir immer über eine Stored Procedure und diese sucht dann den Blobinhalt per execute statement on external zunächst auf der aktuellen Jahres DB und wenn da nix zu finden ist, dann eben auf der Archiv DB. Per Updatable View kann man das in der Produktionsdatenbank auch direkt einbinden, so das die Blobsspalte in der Tabelle zwar so aussieht, als ob die dazu gehören würden, in Wirklichkeit aber die SP zum Abruf nutzt und eine schreibende SP benutzt, um die daten in die aktuelle Jahres DB zu packen. Die Datei Metadaten (also welche Blob Dateien existieren denn überhaupt) bleiben in der Produktionsdatenbank, die Blobs landen immer schon beim Schreiben gleich in der Jahres DB. Mit dem Updatable View lassen sich sogar Programme austricksen, die gar nicht wissen das die Blobs woanders sind. Das haben wir gerade für einen Kunden in USA so gemacht und realisieren das auch für einen Softwareanbieter in Deutschland. Dabei wird unter dem alten Tabellennamen ein updatable view erzeugt und die Blobspalte kommt aus einer anderen db und wird auch da geschrieben, im Programm muss nichts geändert werden. Bei dem Kunden in Deutschland steht übrigens dann auch immer in der Produktionsdatenbank in der Tabellen mit den blob metadaten das Erstellungsdatum und wir benutzen da die Jahreszahl, um pro Jahr jeweils eine DB zu haben. Das sind dann zwar ein paar mehr dateien auf dem Datenbankserver, aber man ist sehr flexibel und da alle alten dbs readonly sind, muss man das nicht ständig sichern. Mein Erfahrung damit ist übrigens das die Blob daten sehr schnell aus der DB geholt werden. egal ob eine db oder mehrere, wenn du aber eine Übericht von zB 300 Bilder darstellen willst, verbraucht die meiste zeit gar nicht das Laden vom Blob, sondern das decodieren von png oder jpg. Das war bei uns ein Unterschied von 0,2 sekunden (in der zeit waren alle blobs geladen, aber nicht angezeit) und 10 Sekunden (das war Laden der Blobs aus der DB und Anzeigen von 300 150*250 pixel pngs jeweils in 50*75 images auf einer scrollbox. Das können verschiedene Image Komponenten sehr unterschiedlich schnell oder lahm) |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Firbird ist extrem stabil bei zig GB von Daten, setze ich gerne ein (im Moment 2.5.x, Planung zu 3.0.2 bald).
Sqlite auch gerne, weil Crossplattform, nicht mit mehreren GB getestet. Dies ist vielleicht auch lesenswert, noch nicht ganz so alt ... ![]() ![]() ![]() Rollo |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Firebird: Test-Project mit 50000 Datensätze ausprobiert, das Bereitstellen der Daten von DB wenn Index bekannt ist geht extrem rasant, längste Zeit wird beim Suchen und Vergleichen von Feld "Name" verballert, suche läuft bereits im Eigenen Thread.
Dennoch wird momentan weniger Zeit mit suchen verbraucht als mit einer Bild-Neuberechnung. Wenn sich das beim zehnfachen Datensatz nicht ändert bin ich am Ziel :-) Momentan wird Datenbank wild beschrieben, ohne sortierung oder der gleichen. Suchen und finden eines Datensatzes dauert grob 2 Wimpernschläge, vielleicht auch weniger/mehr, alles nur objektiv betrachtet, keine Nanosekunden genau Benchmark Session nötig gewesen. Als Unterbau/Schnittstelle für Delphi nutze ich UIB. Nun fang ich an mich dem Thema partitionieren zu nähern, da weiß ich das weder FB3 noch SQlite3 das nativ können. Mit dem "Jahreszahlen" Tipp kann ich auch etwas anfangen und werde es so umsetzen, das klingt für mich logisch nachvollziehbar (kleinere DB = schnellere Suche). Vielen Dank das Ihr mich in die Richtung bewegt habt wo ich nun bin, Danke! |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Zitat:
Suche sollte doch das DBMS machen? Was steht genau in diesem Feld? Passender Index? |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Die Suche ist Aufgebaut nach diesem Beispiel-Code von UIB:
Delphi-Quellcode:
Die Bilder hole ich mir wie in diesem UIB-Code Sample:
unit main;
interface uses {$IFDEF LINUX} libc, QForms, QStdCtrls, QControls, QGraphics, QDialogs, QExtCtrls, {$ELSE} Windows, Graphics, Controls, Forms, Messages, Dialogs, StdCtrls, {$ENDIF} SysUtils, Classes, uib, SyncObjs; type TForm1 = class(TForm) DataBase: TUIBDataBase; Button1: TButton; procedure Button1Click(Sender: TObject); private { Déclarations privées } public { Déclarations publiques } end; TMyThread = class(TThread) protected procedure Execute; override; destructor destroy; override; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var i: integer; begin for i := 0 to 49 do TMyThread.Create(False); end; var x: integer = 0; { TMyThread } destructor TMyThread.destroy; begin inherited; end; procedure TMyThread.Execute; var Query: TUIBQuery; Transaction: TUIBTransaction; begin FreeOnTerminate := true; // Form1.DataBase.Lock; //simulate single thread try Query := TUIBQuery.Create(nil); Transaction := TUIBTransaction.Create(nil); try Transaction.DataBase := Form1.DataBase; Query.Transaction := Transaction; Query.FetchBlobs := True; Query.SQL.Text := 'select * from project'; Query.Open; while not Query.EOF do begin Query.Next; Sleep(10); // simulate activity end; finally Query.Close(etmCommit); Query.Free; Transaction.Free; end; finally // Form1.DataBase.UnLock; //simulate single thread end; end; end.
Delphi-Quellcode:
unit main;
interface uses {$IFDEF LINUX} libc, QForms, QStdCtrls, QControls, QGraphics, QDialogs, QExtCtrls, {$ELSE} Windows, Graphics, Controls, Forms, Messages, Dialogs, StdCtrls, ExtCtrls, {$ENDIF} SysUtils, Classes, uib; type TMainForm = class(TForm) Image: TImage; LoadImage: TButton; SaveImage: TButton; DataBase: TUIBDataBase; Transaction: TUIBTransaction; Query: TUIBQuery; OpenDialog: TOpenDialog; procedure LoadImageClick(Sender: TObject); procedure SaveImageClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var MainForm: TMainForm; implementation uses Math; {$R *.dfm} procedure TMainForm.LoadImageClick(Sender: TObject); var Stream: TMemoryStream; begin Query.SQL.Text := 'Select Stream from TBLOB'; Query.Params.Clear; Query.Open; Stream := TMemoryStream.Create; try Query.ReadBlob('STREAM', Stream); Image.Picture.Bitmap.LoadFromStream(Stream); finally Stream.Free; end; Query.Close(etmCommit); end; procedure TMainForm.SaveImageClick(Sender: TObject); var Stream: TFileStream; begin If OpenDialog.Execute then begin Stream := TFileStream.Create(OpenDialog.FileName, fmOpenRead); try Query.SQL.Text := 'UPDATE TBLOB SET STREAM = :blob'; Query.ParamsSetBlob('blob', Stream); Query.ExecSQL; finally Stream.Free; end; Query.Close(etmCommit); end; end; end. |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Zu sqlite versus irgendwas habe ich keine Zahlen, nur .
Falls Du selber den Vergleich auf der sqlite Seite meinst, der ist tatsächlich schon sehr alt und die Zahlen auch schwer nachvollziehbar, wie sogar der Artikel selber angibt. Was hindert Dich, den Hahn aufzudrehen und Deine Tests mit 500k Datensätzen zu machen? Das sollte problemlos sein. Jedenfalls würde ich das machen, bevor ich mit "künstlicher" Partitionierung ala Jahreszahlen anfange. Dieses Modell würde ich nur unter Zwang und bei ziemlich statischen Daten anwenden, um meinetwegen Backupplatz zu sparen. Oder wenn es sich sonst wie rechnet, also Implementierungsaufwand gegen Nutzen. Der Frage von mkinzler kann ich mich nur anschließen, was macht der Thread? Es geht doch nur um das Absetzen einer Abfrage mit einer Antwortzeit von vermutlich Millisekunden? |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Zitat:
|
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Dieser Code scheint wenig mit dem eigentlichen Programm gemein zu haben und eigenet sich m.M. nach wenig das spätere Verhalten nachzubilden.
Da immer die komplette Tabelle gelesen wird, braucht das natürlich umso länger je mehr Datensätze da sind. Im Normalfall sollte man ja nur die Daten anfordern, welche benötigt werden. Die Performance einer Datenbankanwendung steht und fällt mit dem Entwurf der Abhängigkeiten und Anlage von Indices. |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Ja ich bin da noch totaler Neuling und bin ehrlich gesagt froh das es so einfach war umzusetzen jetzt noch Lernprozess abschliessen was was tatsächlich macht und wie es funktioniert und was ich tatsächlich brauche herausfinden.
Hier stand primär nur an: Lege DB an, führe Zufallszugriffe durch um einen Ersteindruck zu gewinnen. Da sind halt noch viele "Brain-Bugs" aufgrund von nicht-Wissen, aber wird schon werden hehe In dem Thread wird "Name" abgerufen um "CRC" zu erhalten um diese dann zu berechnen und gegenzuprüfen, hat also bestimmt nichts mit DB an sich zu tun sondern CRC Verfahren. |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
SQL-Code:
z.B.
select
<Feldliste> from <Tabelle> where <Bedingung>;
SQL-Code:
Liefert dann die/den Datensatz zu, auf welchen die Bedingung zutrifft. Das DBMS entscheidet hierbei ob/welche Indizes es verwendet.
select
Spitzname, Name, Vorname from Benutzer where Spitzname="KodeZwerg"; Zitat:
|
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Zitat:
|
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
angepasst:
Zitat:
Dann kann dir "egal" sein, wieviel DS in der Tabelle stehen. |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Danke für Deine Verbesserung zu dem Beispiel-Code!
Jetzt wo ich sehe wie Du auf DB zugreifst, also wie Du die select instanz aufbaust und über ('param_crc').DataType := ftString; darauf Zugreifst, in dem Moment wo ich's sah hat sich ein Nebel gelichtet um den Zusammenhang zwischen Doku und Code herzustellen. Das plus mkinzler's Post, sehr hilfreich um da besser durchzublicken, Danke! Jetzt schäm ich mich wie ich dachte das es funktioniert und geh voller Freude weiter daran!
Delphi-Quellcode:
ist nun in Dll Init enthalten und
Query := TUIBQuery.Create(nil);
Delphi-Quellcode:
in Dll Close, könnte da etwas passieren wenn DB auf ist solange Dll geladen?
Query.Free;
|
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Warum suchst Du eigentlich nach CRC? Nur um ein paar Bytes zu sparen?
Natürlich wäre es interessant zu wissen ob die Abfrage über CRC schneller ist als über Name, aber ich vermute, das die Berechnung des CRC viel von dem Vorteil auffrisst. Gruß K-H |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Zitat:
![]() Wahrscheinlich kann ich mit der Frage "Bytes sparen?" noch nichts anfangen weil ich sie gerade noch nicht verstehe. Um es nochmal mit meinen unwissenden Worten zu sagen: In DB soll ein Hauptfeld von dem sich alles ableitet "Name" heißen, da ein Unterfeld mit CRC der original Datei und ein zwei Blobs/Bilder. CRC soll dafür da sein um zu kontrollieren ob ein erneutes Bild-Berechnen nötig ist oder ob das Bild aus DB geladen werden kann. Die original Dateien wovon sich ein Bild ableitet sind nicht Statisch, manchmal wird doch noch etwas darin verändert und darauf muss ich reagieren können, eine Datums oder Dateigrößen abfrage ist da zu ungenau. Also so sollten die Datensätze visuell betrachtet aussehen: [NAME] (String) -> [CRC] (Word) und [BILD1] (Stream) und [BILD2] (Stream) So das ich über [NAME] den Rest anspreche und falls [NAME] noch nicht existiert ich eh einen neuen Datensatz anlege. edit Ps: [NAME] der bei Dll reinkommt ist ein voll qualifizierter
Delphi-Quellcode:
String wo ich nur den ExtractFilename() behalte der letztendlich als [NAME] in DB genommen wird, verstehst Du was ich damit sagen will?
Drive:Path\Filename+FileExt
|
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Dann würde ich eine Tabellenstruktur in der Art vorschlagen
Code:
Mit weiteren Index über NAME und CRC
ID BigInt PK
NAME VarChar(64) CRC Char(xx) IMG1 Blob Subtype 0 IMG2 Blob Subtype 0 Abfragen kann man dann mit
SQL-Code:
select
IMG1, IMG2 from Projekte where NAME = :name and CRC = :CRC; |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Zitat:
Delphi-Quellcode:
So in etwa hatte ich mir das gedacht könnte es funktionieren.
Query.SQL.Text := 'select BILD1, BILD2 from project where NAME = :name and CRC = :CRC;';
Query.Params.ParamByName('NAME').DataType := ftString; Query.Params.ParamByName('NAME').Value := MeineNameVariable; Query.Params.ParamByName('CRC').DataType := ftWord; Query.Params.ParamByName('CRC').Value := MeineCRCWordVariable; Query.Open; // hier bild1 oder bild2 laden usw. |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Wobei ich hier die Deklaration des prepared statements von der Ausführung trennen würde.
Einmalig die Deklaration
Delphi-Quellcode:
Bei der späteren Verwendung (mehrmalig) immer nur noch die Parameter entsprechend setzen:
Query.SQL.Text := 'select BILD1, BILD2 from project where NAME = :name and CRC = :CRC;';
Query.Params.ParamByName('NAME').DataType := ftString; Query.Params.ParamByName('CRC').DataType := ftWord; Query.Prepare; //Ist aber nicht unbedingt notwendig, wird bei der ersten Abfrage implizit durchgeführt
Delphi-Quellcode:
Query.Params.ParamByName('NAME').Value := MeineNameVariable;
Query.Params.ParamByName('CRC').Value := MeineCRCWordVariable; Query.Open; |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Ich verstehe was Du meinst, Danke für den Guten Ratschlag!
|
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Zitat:
Dann muß ich noch mal nachfragen, Du schreibst sinngemäß: Zunächst suche ich den Namen, wenn der nicht vorhanden ist wird er angelegt. Dann wird der CRC verglichen, ist der unterschiedlich, wird der neue eingetragen. Wenn ich das so richtig verstanden habe, mußt Du mit zwei Abfragen arbeiten. Ungefähr so: (Pseudocode)
Code:
Gruß
Function getCRC(name,CRC,IMG1,IMG2):boolean;
select IMG1, IMG2 from Projekte where NAME = :name and CRC = :CRC; result:=(reccount>0) ; end; Function GetName(Name); select name from Projekte where NAME = :name ; result:=reccount>0; end; If not GetName(Name) then InsertName(Name); If not getCRC(Name,CRC,IMG1,IMG2) then UpdateCRC(Name,CRC) else Machwasmit_IMG1_und_IMG2; K-H |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
in meinem Verständnis ist das CRC Verfahren eine Checksumme, mit der man ähnlich wie mit einer Quersumme die Konsistenz der Daten prüfen kann, aber keineswegs dazu geeignet, eine Eindeutigkeit sicherzustellen. Nur so als Hinweis, das du da nicht mit dem falschen Verfahren Inhalte überbügelst ...
Wenn du dir eine simple Bitmap Grafik vorstellst und die pixel so veränderst, das dein CRC den gleichen Wert ergibt, werden 2 unterschiedliche Bilder mit der gleichen CRC dargestellt. Würde ich so nicht als Merkmal der Eindeutigkeit festlegen wollen. |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Zitat:
SQL-Code:
oder
update or insert
SQL-Code:
machen.
merge
Delphi-Quellcode:
mit
if query.RecordCount > 0 then //gefunden
... else begin NeueBilderErzeugen(..); queryU.ParamByName ... ... end;
Delphi-Quellcode:
Ist eine name vorhanden wird der crc und die Bilder upgedatet sonst wird ein neuer DS erzeugt.
QueryU.SQL.Text := 'update or insert into project ( name, crc, bild1, bild) values ( :name, :crc, :bild1, :bild2) matching (name) returning id;';
... |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Zitat:
|
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Danke für Eure Nachträge, das mit der If then else Abfrage habe ich ähnlich bereits umgesetzt.
Nochmal zur CRC, die CRC wird berechnet von dateiname.ext und nicht aus den Bildern oder aus dateinamen. Also eine Prüfsumme der binär-Datei, das original Input File. Beispiel: Start analysiere "Datei.xyz", die CRC16 Berechnung für Datei "Datei.xyz" ergibt $0AF2 <<<<-- das hat noch nichts mit DB zu tun (Die CRC an sich muss nicht bulletproof sein aber geeignet um "Datei.xyz" zu verifizieren, da es schnell gehen soll entschied ich mich für CRC16 Methode, wobei CRC32/64 nicht arg länger braucht, also das kann ich mit einem Befehl abändern.) Jetzt schau ich wie bei Eurem DB Code nach "Datei.xyz" und prüfe ob in DB die gleiche CRC (if crc = $0AF2) drinnen ist wie die CRC16 Berechnung ergeben hat. <<<<-- hier erfolgen die DB aufrufe nach [NAME] + [CRC] Dann wird entschieden ob Bild1 oder Bild2 bei erfolgreicher CRC Prüfung geladen werden soll bzw das in DB hinterlegte Bild erneuert werden muss. Das alles bekomme ich Dank Eurem Code Beispielen und die vielen Hinweise mitlerweile sehr gut hin! Nun habe ich sogar Code von Euch vorliegen mit dem ich gleich auch neue DS anlegen kann bzw Updaten, das rockt! Vielen Lieben Dank für all Eure Mühen!! |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Der Name soll hier wohl als eindeutiger Identifizierer dienen, der unveränderlich ist. CRC kann sich datenabhängig ändern. Von daher kann die Abfrage nicht
SQL-Code:
select BILD1, BILD2 from project where NAME = :name and CRC = :CRC;
lauten (da hier bei geänderten Daten und damit geänderter CRC nicht gefunden wird), sondern nur
SQL-Code:
select BILD1, BILD2, CRC from project where NAME = :name;
Wenn dann die gefundene CRC von der im Programm berechneten abweicht, müssen die Bilder neu erstellt werden. Ungefähr sowas:
Delphi-Quellcode:
Um auf Änderungen der Daten reagieren zu können, würd' ich als CRC 'ne MD5-Checksumme nehmen, damit kann man dann auf Änderungen reagieren und auch eine Eindeutigkeit (soweit überhaupt erforderlich, da bereits über den Namen gegeben) sicherstellen.
// Einmalig irgendwo vor der ersten Benutzung der Querys;
QueryCRC.SQL.Text := 'select CRC from project where NAME = :name'; QueryCRC.Params.ParamByName('NAME').DataType := ftString; QueryCRC.Prepare; QueryBilder.SQL.Text := 'select Bild1, Bild2 from project where NAME = :name'; QueryBilder.Params.ParamByName('NAME').DataType := ftString; QueryBilder.Prepare; QueryUpdate.SQL.Text := 'update project set CRC = :CRC, Bild1 = :Bild1, Bild2 = :Bild2 where NAME = :name'; QueryUpdate.Params.ParamByName('NAME').DataType := ftString; QueryUpdate.Params.ParamByName('CRC').DataType := ftWord; QueryUpdate.Params.ParamByName('Bild1').DataType := ftWasAuchImmer; QueryUpdate.Params.ParamByName('Bild2').DataType := ftWasAuchImmer; QueryUpdate.Prepare; // In der Routine, die für die Anzeige der Bilder verantwortlich ist: MeineCRCWordVariable := BerechneIrgendwieCRCAusAktuellenDaten(MeineNameVariable); QueryCRC.Params.ParamByName('NAME').Value := MeineNameVariable; QueryCRC.Open; if QueryCRC.RecordCOunt = 0 then begin // Neuen Datensatz anlegen. end else if QueryCRC.FieldByName('CRC').AsInteger <> MeineCRCWordVariable then begin QueryUpdate.Params.ParamByName('CRC').Value := MeineCRCWordVariable; QueryUpdate.Params.ParamByName('Bild1').Value := IrgendwieBild1Berechnen(MeineNameVariable); QueryUpdate.Params.ParamByName('Bild2').Value := IrgendwieBild2Berechnen(MeineNameVariable); QueryUpdate.ExecSQL; end; QueryCRC.Close; QueryBilder.Params.ParamByName('NAME').Value := MeineNameVariable; QueryBilder.Open; Bild1Anzeigen(QueryBilder.FieldByName('Bild1').Value); Bild2Anzeigen(QueryBilder.FieldByName('Bild2').Value); QueryBilder.Close; Ok, das hat sich wohl erledigt, da der letzte Beitrag von KodeZwerg genau das bereits verbal beschreibt. |
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Nur zum Verständnis: Datei.XYZ ist keine Bilddatei, sondern irgendeine Daten-Datei, deren Daten ggf. genutzt würden, die Bilder zu erzeugen?
|
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Zitat:
SQL-Code:
machen
update or insert into
|
AW: Datenbank für schnelle Bilder, Vorschläge bitte.
Zitat:
Die Datei.xyz kann man nicht in einem Bild-Betrachter laden, dort würde man nur Hex-Werte dargestellt bekommen, wenn überhaupt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:09 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz