Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Datenbank für schnelle Bilder, Vorschläge bitte. (https://www.delphipraxis.net/196084-datenbank-fuer-schnelle-bilder-vorschlaege-bitte.html)

jobo 24. Apr 2018 15:54

AW: Datenbank für schnelle Bilder, Vorschläge bitte.
 
Zitat:

Zitat von Neutral General (Beitrag 1400362)
Und nach 4 Seiten Diskussion (wo eigentlich unter den ersten 3 Antworten schon min. eine gute Antwort war) fühlt es sich langsam danach an als würde es nicht mehr aufhören :mrgreen:

Ja sagst Du als alter Hase! :)
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:

KodeZwerg 24. Apr 2018 16:00

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!

Neutral General 24. Apr 2018 16:08

AW: Datenbank für schnelle Bilder, Vorschläge bitte.
 
Zitat:

Zitat von KodeZwerg (Beitrag 1400366)
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.

Ich schreibe weder den anderen Leuten vor nichts mehr zu sagen noch musst du dich an meinen Rat halten ;)
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 :)

Delphi.Narium 24. Apr 2018 16:36

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.

MichaelT 24. Apr 2018 16:53

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:

Zitat von KodeZwerg (Beitrag 1400366)
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!


KodeZwerg 24. Apr 2018 17:22

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.

Delphi.Narium 24. Apr 2018 17:35

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.

KodeZwerg 24. Apr 2018 17:43

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!

Rollo62 24. Apr 2018 17:45

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

KodeZwerg 24. Apr 2018 19:42

AW: Datenbank für schnelle Bilder, Vorschläge bitte.
 
Puh, noch mehr Hausaufgaben, Danke für SQLite3 Hinweis, mehr zu lesen, bald platze ich :)

jobo 25. Apr 2018 07:39

AW: Datenbank für schnelle Bilder, Vorschläge bitte.
 
Zitat:

Zitat von KodeZwerg (Beitrag 1400394)
Puh, noch mehr Hausaufgaben, Danke für SQLite3 Hinweis, mehr zu lesen, bald platze ich :)

Würde mich jetzt überraschen, wenn sqlite schnell ist. Aber für single user Betrieb vielleicht okay.

KodeZwerg 25. Apr 2018 09:26

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.

IBExpert 25. Apr 2018 11:23

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)

Rollo62 25. Apr 2018 13:22

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 ...
https://blog.devart.com/increasing-s...rformance.html
https://code.i-harness.com/de/q/365eb
http://www.itexto.net/devkico/?p=398

Rollo

KodeZwerg 25. Apr 2018 17:13

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!

mkinzler 25. Apr 2018 17:19

AW: Datenbank für schnelle Bilder, Vorschläge bitte.
 
Zitat:

längste Zeit wird beim Suchen und Vergleichen von Feld "Name" verballert, suche läuft bereits im Eigenen Thread.
?
Suche sollte doch das DBMS machen?
Was steht genau in diesem Feld? Passender Index?

KodeZwerg 25. Apr 2018 17:25

AW: Datenbank für schnelle Bilder, Vorschläge bitte.
 
Die Suche ist Aufgebaut nach diesem Beispiel-Code von UIB:
Delphi-Quellcode:
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.
Die Bilder hole ich mir wie in diesem UIB-Code Sample:
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.

jobo 25. Apr 2018 17:25

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?

jobo 25. Apr 2018 17:29

AW: Datenbank für schnelle Bilder, Vorschläge bitte.
 
Zitat:

Zitat von KodeZwerg (Beitrag 1400497)
Die Suche ist Aufgebaut nach diesem Beispiel-Code von UIB:

Das sucht aber nicht, sondern kaut alle Datensätze inkl. BLOB durch, lokal.

mkinzler 25. Apr 2018 17:31

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.

KodeZwerg 25. Apr 2018 17:39

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.

mkinzler 25. Apr 2018 17:43

AW: Datenbank für schnelle Bilder, Vorschläge bitte.
 
SQL-Code:
select
    <Feldliste>
from
    <Tabelle>
where
    <Bedingung>;
z.B.

SQL-Code:
select
    Spitzname, Name, Vorname
from
   Benutzer
where
    Spitzname="KodeZwerg";
Liefert dann die/den Datensatz zu, auf welchen die Bedingung zutrifft. Das DBMS entscheidet hierbei ob/welche Indizes es verwendet.
Zitat:

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.
Nach Ermittlung des CRC musst Du dann in der Datenbank nur nach diesem Suchen

KodeZwerg 25. Apr 2018 17:51

AW: Datenbank für schnelle Bilder, Vorschläge bitte.
 
Zitat:

Zitat von mkinzler (Beitrag 1400502)
Liefert dann die/den Datensatz zu, auf welchen die Bedingung zutrifft. Das DBMS entscheidet hierbei ob/welche Indizes es verwendet.

Ja da bin ich gerade am Lesen + DBMS verstehen, hab noch das ganze MyBase gedöns im Kopf, Vielen Dank!!

jobo 25. Apr 2018 18:40

AW: Datenbank für schnelle Bilder, Vorschläge bitte.
 
angepasst:
Zitat:

Zitat von KodeZwerg (Beitrag 1400497)
Die Suche ist Aufgebaut nach diesem Beispiel-Code von UIB:
Delphi-Quellcode:
unit main;

interface

uses
..snipp..
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 imageblobfeldname <, andereFelder> from project where crc = :param_crc';
      Query.Params.ParamByName('param_crc').DataType := ftString;
      Query.Params.ParamByName('param_crc').Value := <valueVonIrgendwoher>;
      Query.Open;
      while not Query.EOF do //diese Prüfung kann bleiben, könnte leere Menge ergeben, dann Fehlerbehandlung (ergänzen), gewünschtes Ergebnis: 1 Datensatz
      begin
        //Query.Next;
        //Sleep(10); // simulate activity
        // code für Picture Befüllung aus BLOB Stream (steht schon in Deinem Beispiel oben, keine neue Query Vararible nötig)
      end;
    finally
      Query.Close(etmCommit);
      Query.Free;
      Transaction.Free;
    end;
  finally
    // Form1.DataBase.UnLock; //simulate single thread
  end;
end;

end.

Du musst in der Query das Ergebnis direkt von 500k Datensätzen auf einen einschränken.
Dann kann dir "egal" sein, wieviel DS in der Tabelle stehen.

KodeZwerg 25. Apr 2018 19:45

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:
Query := TUIBQuery.Create(nil);
ist nun in Dll Init enthalten und
Delphi-Quellcode:
Query.Free;
in Dll Close, könnte da etwas passieren wenn DB auf ist solange Dll geladen?

p80286 25. Apr 2018 21:03

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

KodeZwerg 26. Apr 2018 06:16

AW: Datenbank für schnelle Bilder, Vorschläge bitte.
 
Zitat:

Zitat von p80286 (Beitrag 1400508)
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.

Hier beschrieb ich was ich mit DB vorhabe.
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:
Drive:Path\Filename+FileExt
String wo ich nur den ExtractFilename() behalte der letztendlich als [NAME] in DB genommen wird, verstehst Du was ich damit sagen will?

mkinzler 26. Apr 2018 06:54

AW: Datenbank für schnelle Bilder, Vorschläge bitte.
 
Dann würde ich eine Tabellenstruktur in der Art vorschlagen

Code:
ID   BigInt PK
NAME VarChar(64)
CRC  Char(xx)
IMG1  Blob Subtype 0
IMG2  Blob Subtype 0
Mit weiteren Index über NAME und CRC

Abfragen kann man dann mit

SQL-Code:
select
  IMG1, IMG2
from
  Projekte
where
  NAME = :name and CRC = :CRC;

KodeZwerg 26. Apr 2018 07:33

AW: Datenbank für schnelle Bilder, Vorschläge bitte.
 
Zitat:

Zitat von mkinzler (Beitrag 1400515)
Dann würde ich eine Tabellenstruktur in der Art vorschlagen

Delphi-Quellcode:
 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.
So in etwa hatte ich mir das gedacht könnte es funktionieren.

mkinzler 26. Apr 2018 07:45

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:
 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
Bei der späteren Verwendung (mehrmalig) immer nur noch die Parameter entsprechend setzen:

Delphi-Quellcode:
 Query.Params.ParamByName('NAME').Value := MeineNameVariable;
 Query.Params.ParamByName('CRC').Value := MeineCRCWordVariable;
 Query.Open;

KodeZwerg 26. Apr 2018 07:53

AW: Datenbank für schnelle Bilder, Vorschläge bitte.
 
Ich verstehe was Du meinst, Danke für den Guten Ratschlag!

p80286 26. Apr 2018 08:39

AW: Datenbank für schnelle Bilder, Vorschläge bitte.
 
Zitat:

Zitat von KodeZwerg (Beitrag 1400513)
Hier beschrieb ich was ich mit DB vorhabe.

Pardon nicht aufmerksam gelesen, ich hatte es so verstanden, daß du den CRC des Dateinamens bildest, nicht des Dateiinhaltes.:oops:

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:
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;
Gruß
K-H

IBExpert 26. Apr 2018 09:15

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.

mkinzler 26. Apr 2018 09:29

AW: Datenbank für schnelle Bilder, Vorschläge bitte.
 
Zitat:

Zitat von p80286 (Beitrag 1400535)
Wenn ich das so richtig verstanden habe, mußt Du mit zwei Abfragen arbeiten.

Nein ich würde das eher über ein
SQL-Code:
update or insert
oder
SQL-Code:
merge
machen.

Delphi-Quellcode:
if query.RecordCount > 0 then //gefunden
...
else
begin
  NeueBilderErzeugen(..);
  queryU.ParamByName ...
  ...
end;
mit
Delphi-Quellcode:
  QueryU.SQL.Text := 'update or insert into project ( name, crc, bild1, bild) values ( :name, :crc, :bild1, :bild2) matching (name) returning id;';
...
Ist eine name vorhanden wird der crc und die Bilder upgedatet sonst wird ein neuer DS erzeugt.

mkinzler 26. Apr 2018 09:31

AW: Datenbank für schnelle Bilder, Vorschläge bitte.
 
Zitat:

Zitat von IBExpert (Beitrag 1400542)
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.

Ein Hash wäre u.U besser geeignet.

KodeZwerg 26. Apr 2018 09:53

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!!

Delphi.Narium 26. Apr 2018 10:00

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:
// 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;
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.


Ok, das hat sich wohl erledigt, da der letzte Beitrag von KodeZwerg genau das bereits verbal beschreibt.

Jumpy 26. Apr 2018 10:01

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?

mkinzler 26. Apr 2018 10:03

AW: Datenbank für schnelle Bilder, Vorschläge bitte.
 
Zitat:

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

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

select BILD1, BILD2, CRC from project where NAME = :name;
Warum es macht doch keinen Unterschied ob es noch kein Bild oder eines, welches geändert wurde gibt. In beiden Fällen muss neu berechnet werden. Ich würde es, wie oben beschrieben per
SQL-Code:
update or insert into
machen

KodeZwerg 26. Apr 2018 10:06

AW: Datenbank für schnelle Bilder, Vorschläge bitte.
 
Zitat:

Zitat von Jumpy (Beitrag 1400553)
Nur zum Verständnis: Datei.XYZ ist keine Bilddatei, sondern irgendeine Daten-Datei, deren Daten ggf. genutzt würden, die Bilder zu erzeugen?

Genau, Datei.xyz ist eine binär-Datei die nichts mit Bildern zu tun hat aber durch Analyse entsteht ein Diagram (Bild) was es in zwei Ausführungen geben kann, das steuer ich über eine Boolean (True = Bild1, False = Bild2)
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.
Seite 2 von 3     12 3      

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