Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Daten aus Datenbank in Speicher halten?! (https://www.delphipraxis.net/165497-daten-aus-datenbank-speicher-halten.html)

Mavarik 7. Jan 2012 03:33

AW: Daten aus Datenbank in Speicher halten?!
 
Wie wäre es mit:

Delphi-Quellcode:
'Select * from [$TABLENAME] where FILMNAME LIKE '''+Sucher.Text+'%'' OR SCHAUSPIELER LIKE '''+Sucher.Text+'%'' OR WAHTEVER LIKE '''+Sucher.Text+'%''');


Mavarik

Furtbichler 7. Jan 2012 08:38

AW: Daten aus Datenbank in Speicher halten?!
 
Das beantwortet die Frage nicht.

RWarnecke 7. Jan 2012 09:14

AW: Daten aus Datenbank in Speicher halten?!
 
Zitat:

Zitat von hans ditter (Beitrag 1144321)
@Sharky: Das war letztlich auch das, was ich problematisch gesehen hab. Die beste Lösung sieht für mich im Moment wie die Antwort von RWarnecke mit Klassen und ObjectList, obwohl mir die Umsetzung noch nicht ganz klar ist...

Was hat die Klasse zu tun? Holt die die Daten aus der DB oder nimmt sie die Daten eines Datensatzes auf oder wie? Und was speicher ich in der ObjectList? Pointer auf die Klasse? Oder irgendwas anderes?

LG; hans ditter

Unter diesem Link habe ich mal ein Beispiel gepostet. Die Klasse enthält die Spalten der Tabelle aus der Datenbank. Die Klasse wird dann in der TObjectList gespeichert. Somit enthält die TObjectList alle Datensätze der Tabelle.

ConnorMcLeod 7. Jan 2012 09:19

AW: Daten aus Datenbank in Speicher halten?!
 
Wenn alles in den Speicher passt, dann könnten MemTables z.B. von JEDI helfen.

hans ditter 7. Jan 2012 17:24

AW: Daten aus Datenbank in Speicher halten?!
 
@Connor: Bei meinem Projekt dürfte das wohl noch passen, aber wenn es irgendwann mal größer werden sollte? Ganz allgemein: Wie wird denn das z.B. auch bei den datensensitiven Komponenten gemacht? Halten die die Daten auch die ganze Zeit im Speicher oder sozusagen "just-in-time"?

@RWarnecke: Du sagtest es ja schon, aber nur um sicherzugehen... ;) Die Klassen enthält alle Felder eines Datensatzes aus der Tabelle. Die ObjectList hingegen enthält alle instanziierten Klassen, somit also alle Datensätze der Tabelle?!

- Wird das nich bei größeren Projekten extrem Speicherfressend? Oder wird da immer nur ein Teil der Daten geladen, sozusagen +- 10 Datensätze um den angefragten herum?

- Wenn man die Klasse instanziiert, dann muss sie ja einer Variable zugeordnet werden, ist da dann der Ausdruck
Delphi-Quellcode:
var obj: TKlasse;
begin
  New(obj);
  ...
end;
der richtige Ansatzpunkt?

- Kann man bei Erzeugung einer neuen Klasse selbige auch automatisch an die ObjectList anhängen? Passiert dies bei deinem Bsp. (dein Link) über das NotifyEvent?

LG und vielen Dank schonmal für die Antworten! :)

hans ditter

EDIT:

Mir ist eben noch ein Gedanke gekommen. Jetzt hab ich zwar schön die Grundlage geschaffen, die Daten im Speicher bereit zu halten. Aber wie bekomme ich die überhaupt aus der Datenbank raus? Schreibt man dazu einen alleinstehenden Extracode?
Meine Idee war, eine dritte Klasse 'Database' (o.ä.) zu entwerfen, die die ObjectList enthält und außerdem Methoden bereitstellt, Datensätze zu ändern, zu löschen oder hinzuzufügen. Meiner Meinung nach würde das die Möglichkeit geben, relativ leicht später Datensätze zu bearbeiten. Z.B. müsste man dann im Hauptprogrammcode nur noch ein TMovie-Objekt erzeugen, welches, durch TDatabase, automatisch der Datenbank hinzugefügt wird.

Was haltet ihr von der Idee?

RWarnecke 7. Jan 2012 21:41

AW: Daten aus Datenbank in Speicher halten?!
 
Zitat:

Zitat von hans ditter (Beitrag 1144819)
Die ObjectList hingegen enthält alle instanziierten Klassen, somit also alle Datensätze der Tabelle?!

Jaein, es kommt drauf an, wie Du Sie füllst.

Zitat:

Zitat von hans ditter (Beitrag 1144819)
- Wird das nich bei größeren Projekten extrem Speicherfressend? Oder wird da immer nur ein Teil der Daten geladen, sozusagen +- 10 Datensätze um den angefragten herum?

Der Speicherverbauch ist bis jetzt immer im Rahmen geblieben, egal wieviele Datensätze ich geladen hatte in der TObjectList.

Zitat:

Zitat von hans ditter (Beitrag 1144819)
- Wenn man die Klasse instanziiert, dann muss sie ja einer Variable zugeordnet werden, ist da dann der Ausdruck
Delphi-Quellcode:
var obj: TKlasse;
begin
  New(obj);
  ...
end;
der richtige Ansatzpunkt?

Du nimmst den Quelltext aus meinen obenstehenden Link. Und so fülle ich die TObjectList :
Delphi-Quellcode:
procedure TDM_Main.SetAnsprechpartnerListe(Kundennr : string);
begin
  if AnsprechpartnerListe.Count > 0 then
    AnsprechpartnerListe.Clear;
  with UniQuery_Ansprechpartner do
  begin
    SQL.Text := 'SELECT * FROM Ansprechpartner WHERE Kundennr = :KundenID;';
    ParamByName('KundenID').AsString := Kundennr;
    Open;
    while not Eof do
    begin
      AnsprechpartnerListe.Add(TAnsprechpartner.Create);
      with TAnsprechpartner(AnsprechpartnerListe.Last) do
      begin
        KundenNr := FieldByName('Kundennr').AsString;
        Vorname := FieldByName('Vorname').AsString;
        Nachname := FieldByName('Nachname').AsString;
        Telefon1 := FieldByName('Telefon1').AsString;
        Telefon2 := FieldByName('Telefon2').AsString;
        Fax     := FieldByName('Fax').AsString;
        Mobil   := FieldByName('Mobil').AsString;
        EMail   := FieldByName('EMail').AsString;
      end;
      Next;
    end;
    Close;
  end;
end;
Zitat:

Zitat von hans ditter (Beitrag 1144819)
- Kann man bei Erzeugung einer neuen Klasse selbige auch automatisch an die ObjectList anhängen? Passiert dies bei deinem Bsp. (dein Link) über das NotifyEvent?

Das NotifyEvent nutze ich dazu, wenn Änderungen in der TObjectList gemacht wurden diese in die Datenbank zu übertragen.

stahli 7. Jan 2012 22:39

AW: Daten aus Datenbank in Speicher halten?!
 
Wenn alle Daten im Speicher verwaltet werden können und keine Multiuser-Zugriffe und Transaktionen nötig sind, dann ist es am einfachsten, die Daten in Objekten zu verwalten.
So lässt sich die Geschäftslogik am einfachsten umsetzen. In meinem Framework habe ich einen Klassengenerator eingesetzt, der mir die Klassen anhand einer vorgegebenen Struktur erzeugt.
Damit kann ich sehr flexibel und komfortabel arbeiten.

Die Daten werden in einer Textdatei serialisiert abgelegt und die Daten-Objekte werden beim Einlesen einer Datei neu erzeugt und gefüllt. Es sind damit natürlich keine Mehrfachzugriffe und Transaktionen möglich.

Auf keinen Fall will ich mehr auf eine Datenbindung verzichten. Egal,ob es nun im Detail mit LiveBinding, DSharp, DBControls oder mit meinen odControls erfolgt.
Jedenfalls will ich im Projekt nicht Edit.Text := Person.FirstName und Person.FirstName := Edit.Text schreiben müssen. Der Datentransport zwischen GUI und Datenschicht soll möglichst automatisiert erfolgen.
Daraus kann man auch erkennen, dass ich GUI und Daten künftig immer trennen will.

Passen die Daten nicht (auf jeden Fall) in den Speicher oder sind mehrfache Zugriffe oder Transaktionen erforderlich, sollte man eine Datenbank verwenden (dafür sind sie ja da).
Über einen SQL-DB-Server kann man Joins über mehrere Tabellen abrufen und die Daten filtern oder Mengen bearbeiten.

Der einfache Weg ist dann, DBControls zu verwenden. Man kann halt recht wenig zaubern und hat i.d.R. immer den Fokus auf einem Datensatz.
Die Geschäftslogik realisiert man über SQL-Statements, was - ja na - auf jeden Fall umständlich ist.

Deshalb gibt es ORM-Lösungen (bekannte Beispiele sind wohl mORMot und DORM), die den Programmierer mit Objekten arbeiten lassen, die Daten aber in einer Datenbank gespeichert werden. Dann ist die Frage, wann die Daten-Objekte erzeugt werden und wie lange sie am Leben bleiben. Auf jeden Fall macht es natürlich Aufwand, die Objekte zu erzeugen und die Daten hin und her zu schaufeln. Die Frage ist auch (für mich), wie mit Versionsänderungen umgegangen wird. Was ist, wenn ich ältere Daten in meinem aktuellen Projekt öffnen will? Außerdem hat das Konzept seine Grenzen wohl bei sehr großen Datenbanken.

Wenn die Geschäftslogik sehr komplex ist und die Daten nicht übermäßig umfangreich sind, ist eine ORM-Lösung sicher sinnvoll.
Ein Databinding sollte dann auch wieder geregelt werden.

Steht die Datenbank im Vordergrund, ist ein ORM-Einsatz sicher nicht sinnvoll. Eine Bank wird ihre Konten wohl mit einer klassischen DB-Anwendung verwenden.

Wenn schon "normale DB-Anwendung", dann kann man überlegen, ob man einfach per Clients auf die DB zugreift oder eine mittlere Schicht bereitstellt, die die Geschäftslogik enthält und ihrerseits auf die DB zugreift (Multi-Tier-Anwendung). Die Clients sind dann quasi nur noch zum Anzeigen und Bearbeiten der Daten da.

Alles hat seine Vor- und Nachteile und ist mit unterschiedlichen Aufwänden verbunden.

Deshalb kann man wohl nie so einfach sagen, was man "ab besten" einsetzen soll...

Soweit mal meine Einschätzung der Sachlage. ;-)

Chemiker 8. Jan 2012 00:24

AW: Daten aus Datenbank in Speicher halten?!
 
Hallo hans ditter,

ich kenne jetzt nicht die Datenbank SQLite. Aber ich vermute, dass damit ganz normale Abfragen über SQL möglich sind.

Eine andere Möglichkeit um alle Daten im Speicher zu halten ist mit TClientDataSet . Damit kann man einen gesamten Datenbestand aus der DB in den Speicher lesen und wenn man will auf die lokale Festplatte speichern.

Bis bald Chemiker

BUG 8. Jan 2012 16:38

AW: Daten aus Datenbank in Speicher halten?!
 
Das Vorgehen: alle Daten holen, in Speicher bearbeiten / Anfragen machen und wieder zurückschreiben macht die Nutzung einer Datenbank absurd. Damit eleminierst nahezu alle Vorteile, die dir eine Datenbank bietet.

Und Caching sollte bei einer lokalen Datenbank wie sqlite nur in Ausnahmefällen etwas bringen.

Furtbichler 8. Jan 2012 19:19

AW: Daten aus Datenbank in Speicher halten?!
 
Na ja, wenn man sich merkt, welche Daten verändert wurden, ist das Zurückschreiben doch kein Problem.
Und "Alles im Speicher halten" ist -je nach Anwendung und Definition von "Alles"- manchmal auch sinnvoll.

Wir müssen (bzw. wollen) bis zu 5000 Aufträge im Speicher halten, weil die Disponenten beim Anruf eines Kunden schnell die richtigen Aufträge finden müssen. Eine Query dauert dann leider doch etwas, weil auch Großkunden mit mehreren Hundert Aufträgen dabei sind. Und pro Auftrag sind es 300-400 Details, die mit geladen werden, also schon einiges an Daten.

Hier definieren wir "Alles" mit "alle noch nicht fakturierten Aufträge" und schon ergibt das Konzept Sinn.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:26 Uhr.
Seite 2 von 3     12 3      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz