Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Datenstruktur clientseitig abbilden? (https://www.delphipraxis.net/139831-datenstruktur-clientseitig-abbilden.html)

Namenloser 6. Sep 2009 13:49

Datenbank: Firebird • Zugriff über: ZEOS

Datenstruktur clientseitig abbilden?
 
Hallo,

angenommen, ich habe verschiedene Tabellen, die über irgendein Feld miteinander verknüpft sind, wie stelle ich das clientseitig am besten dar? Die Beschreibung ist etwas hakelig, deshalb hier mal ein Minimalbeispiel einer imaginären Forensoftware:
Code:
Table "Entries":
  ID: int
  AuthorID: int
  Text: text;

Table "Users":
  ID: int
  Name: int
Hier referenziert Entries über das Feld AuthorID also die Tabelle Users. Mit JOIN könnte man hier z.B. sehr elegant für einen Beitrag den Namen gleich mit herausbekommen und direkt verarbeiten. Aber wie mache ich das am besten, wenn ich mein Programm objektorientiert aufbauen möchte? Hierbei würde es sich quasi aufdrängen, dass Beitrag und Autor jeweils eigenständige Objekt sind und das Beitragsobjekt eine Referenz auf den jeweiligen Nutzer enthält.

Das Problem wäre, dass für jeden Beitrag die gesamte Liste an Usern durchgegangen werden müsste, um über die ID die Referenz herauszubekommen. Somit würde ich dann doch wieder die Daten manuell durchsuchen und könnte ich mir die Datenbank eigentlich sparen...

Also kurz gesagt habe ich das Gefühl, auf dem Holzweg zu sein. Ich habe nicht wirklich viel Erfahrung mit Datenbanken, bzw. habe sie bisher eigentlich nur für meine Webseite verwendet. Daher meine Frage: Wie macht man sowas professionell?

Vielen Dank

DeddyH 6. Sep 2009 13:58

Re: Datenstruktur clientseitig abbilden?
 
Vielleicht hilft Dir dieser Thread (inkl. der Querverlinkungen) etwas weiter.

omata 6. Sep 2009 16:35

Re: Datenstruktur clientseitig abbilden?
 
Zitat:

Zitat von NamenLozer
Das Problem wäre, dass für jeden Beitrag die gesamte Liste an Usern durchgegangen werden müsste, um über die ID die Referenz herauszubekommen

Binäre Suche.

Namenloser 7. Sep 2009 23:12

Re: Datenstruktur clientseitig abbilden?
 
Tut mir Leid, dass ich mich noch nicht wieder gemeldet habe, ich bin zur Zeit immer noch am überlegen wie ich das am besten aufbaue.

Vielen Dank schon mal für deinen Link, Detlef. Ich habe mir den Thread und die Querverlinkungen durchgelesen, es tut gut, zu sehen, dass ich nicht der einzige mit diesem Problem bin, und bin jetzt denke ich auch ein Stückchen weiter. Also alle Lösungen, die ich bisher gesehen habe, waren auf eine eindeutige ID jedes Datensatzes angewiesen. Allerdings ist mir noch nicht ganz klar, wie das bei Abfragen funktionieren soll, die über mehrere Tabellen gehen....

Also wie gesagt, ein paar Eindrücke habe ich gesammelt, ganz schlüssig, wie ich es jetzt angehe, bin ich aber noch nicht. Ich wollte euch nur kurz wissen lassen, dass ich eure Beiträge gelesen habe und das Thema noch aktuell ist.

@omata:
Daran hatte ich zwar auch schon gedacht, aber das ist keine Lösung des eigentlichen Problems... es macht nur den Umweg schneller. Ich nutze ja gerade auch deshalb Datenbanken, damit ich mich um solchen Kram wie Suchalgorithmen nicht selbst kümmern muss.

omata 7. Sep 2009 23:32

Re: Datenstruktur clientseitig abbilden?
 
Naja, du musst dich entscheiden, entweder sucht du (das dauert, verbraucht aber weniger Speicher) oder du speichert die Information mit ab (dann bist du schneller, benötigst aber mehr Speicherplatz).
Das gilt es immer abzuwägen, du musst dir klar werden, was dir wichtig ist.

Eine Datenbank einzusetzen, ist doch eine gute Idee...

Angel4585 8. Sep 2009 07:16

Re: Datenstruktur clientseitig abbilden?
 
Suchst du sowas wie Hashmaps? Hier giobts ein Link zu ner Implementierung in Delphi: Hash-Tabellen

DeddyH 8. Sep 2009 08:39

Re: Datenstruktur clientseitig abbilden?
 
Um alle Daten sofort zur Verfügung zu haben, müsstest Du ja die komplette DB im Speicher halten. Das macht in meinen Augen wenig Sinn. Bei gescheiter Indexierung sollte auch eine Abfrage zu der Zeit, wo die Daten wirklich benötigt werden, kein großes Performanceproblem darstellen. Nehmen wir einmal Folgendes an: Du hast aus der Datendefinition der Tabelle Users eine Klasse TUser erstellt, die zunächst nur die Daten, die auch in dieser einen Tabelle definiert wurden, enthält. Nun wäre es doch kein Problem, diese Klasse um eine Methode zu erweitern, die die Einträge des aktuellen Benutzers ermittelt. Was nach meiner Erfahrung gut klappt ist, solche Auflistungen für die Darstellung in TStrings-Objekten abzulegen (das Gleiche gilt auch für die Users-Tabelle). Ein Beispiel aus dem Kopf:
Delphi-Quellcode:
procedure TUser.GetEntries(const sl: TStrings);
var Entry: TEntry;
begin
  sl.BeginUpdate;
  try
    sl.Clear;
    //dem Objekt sei ein TQuery o.ä. zugewiesen
    Query.Close;
    Query.SQL.Text := 'SELECT ID,Text FROM Entries WHERE AuthorID = :id';
    Query.ParamByName('id').Value := self.ID;
    Query.Open;
    while not Query.EOF do
      begin
        //Entry-Objekt anlegen, befüllen und in TStrings ablegen
        Entry := TEntry.Create;
        Entry.ID := Query.FieldByName('ID').AsInteger;
        Entry.AuthorID := self.ID;
        Entry.Text := Query.FieldByName('Text').AsString;
        sl.AddObject(IntToStr(Entry.ID),Entry);
      end;
  finally
    sl.EndUpdate;
  end;
end;
Man muss halt nur darauf achten, im Delete, Clear, Destroy usw. des TStrings-Objektes die enthaltenen TEntry-Objekte wieder freizugeben.

Namenloser 17. Sep 2009 17:11

Re: Datenstruktur clientseitig abbilden?
 
Nanu, hier gabs ja inzwischen neue Beiträge :shock: Wieso wurde ich darüebr nciht benachrichtigt? :gruebel:

Ich habe nicht vor, die gesamte Datenbank im Programmspeicher zu halten, das wäre ja absolut kontraproduktiv. Daher helfen mir hier auch Hashmaps nicht.

Eigentlich wollte ich jetzt aber mal über den aktuellen Stand schreiben. Ich bin schon bei der Implementierung, aber ich bin mir unsicher, ob ich nicht vielleicht gerade das Rad neu erfinde, und Klassen schreibe, die es schon standardmäßig gibt - denn wie gesagt hab ich unter Delphi noch nix mit Datenbaken zu tun gehabt.

Hier ist das Konzept:

Es gibt folgende (wichtige) Klassen:
  • Datenbank (TDatabase)
  • Tabelle (TTable)
  • Datensatz/Zeile in einer Tabelle (TTableRow)
  • Feld (TField)
  • Feld-Wert (TFieldValue)
  • Resultat einer Abfrage (Liste) (TQueryResult)
  • Datensatz/Zeile in einer Abfrage (TQueryResultRow)
Es gibt also die Basislasse TTableRow für einen Datensatz in einer Tabelle, quasi eine Zeile. Die Felder eines Datensatzes (TField) werden in einer Liste von TTableRow verwaltet. Die Werte dieser Felder (TFieldValue) sind selbst Objekte eines abstrakten Typs. Einer der Vorteile: Die Klasse TTableRow ist selbst von TFieldValue abgeleitet, d.h. mit Referenzen kann hier sehr elegant umgegangen werden. Zur Identifizierung kann jede Zeile eine eindeutige ID zugewiesen bekommen, das ist zwar nicht zwingend, aber bestimmte Funktionen lassen sich sonst eben nicht nutzen.

Die Datenbank wird eine Funktion haben, einen Query auszuführen. Das Ergebnis wird als TQueryResult ausgegeben. Statt die Felder direkt zu beinhalten, beinhaltet TQueryResult Referenzen auf die entsprechenden Tabellendatensätze, die die angeforderten Informationen enthalten. Das soll die Verwaltung vereinfachen und dafür sorgen, dass die Datenbankstruktur besser auf die Klassenstruktur übertragen wird.

Natürlich kann und wird es passieren, dass die gleichen Tabellendatensätze an verschiedenen Stellen verwendet werden. Damit die Daten synchron bleiben, speichert jede TTableRow Referenzen auf andere TTableRow-Objekte, die auf den gleichen Datensatz zugreifen. Hier kommt die Klasse TTable ins Spiel, die eine Liste mit Datensätzen entählt, die im Progamm in Verwendung sind. Dazu kennt jedes TTableRow-Objekt die Tabelle, zu der es gehört. Wenn nun ein neues TTableRow-Objekt durch eine Abfrage angelegt wird, prüft es zunächst ob in seiner Tabelle dieser Datensatz schon vorhanden ist (dazu nutzt es die optionale ID), wenn nein, fügt es sich zur Referenzliste der Tabelle hinzu, sonst pickt es sich das dort vorhandene Objekt (ich nenn es jetzt mal den Verwalter) heraus, und meldet sich dort an. Es wird dann zur Referenzliste dieses Verwalters, sowie aller Referenzen, die der Verwalter kennt, hinzugefügt. Ebenso kopiert es alle "Bekannten" dieses Verwalters, sowie den Verwalter, in seine eigene Referenzliste ein. Wird ein Objekt zerstört, entfernt es sich automatisch aus den Referenzlisten der anderen Objekte. Falls das Objekt der Verwalter ist, wird das erste Objekt in seiner Referenzliste sein Nachfolger. Falls kein Nachfolger vorhanden ist, wird das Objekt aus der Referenzliste der Tabelle entfernt.

Statt der ganzen Listen hatte ich auch schon über Interfaces nachgedacht (Referenzzähler), aber da ich von Interfaces keine Ahnung habe, möchte ich lieber die Finger davon lassen, statt mir eine weitere Fehlerquelle ins Programm zu holen

Es ist so gedacht, dass die oben genannten Klassen nicht direkt verwenden werden, sondern nur das Grundgerüst darstellen. Letztendlich sollen abgeleitete Klassen verwendet werden, die die Datenstruktur repräsentieren. Für jede Tabelle wird eine eigene Klasse von TTable abgeleitet etc. Das könnte von einem Generator automatisch erledigt werden.

Ich hoffe mein Ansatz ist deutlich geworden. Nun möchte ich gerne hören, was ihr davon haltet. Zu komplex? Rad neu erfunden? Oder vielleicht total genial? :mrgreen:

Vielen Dank schonmal fürs Lesen und eure Antworten!

sx2008 18. Sep 2009 00:06

Re: Datenstruktur clientseitig abbilden?
 
Zitat:

Zitat von NamenLozer
Zu komplex? Rad neu erfunden? Oder vielleicht total genial? :mrgreen:

Sowohl als auch :-)
Du gehst hier in Richtung persistent Framework.
Das Problem ist die Zuordnung (Mapping) zwischen deinen Bussiness-Objekten und der relationalen Datenbank.
Es "klemmt" einfach irgendwie (Object-Relational Impedance Mismatch) und eine allgemeine Lösung passend für alle Anwendungfälle lässt sich schwer finden.

Je weiter du mit deiner Klassenbibliothek kommst umso schwieriger werden die Probleme.
Viele haben schon aufgegeben z.B. Jedi Obiwan
Aber lass dich nicht von mir entmutigen. :hi:
Weitere Ideen kannst du hier bekommen.

Oder vielleicht möchtest du auch das tech inside Open Persistent Framework anschauen.

Namenloser 22. Sep 2009 18:24

Re: Datenstruktur clientseitig abbilden?
 
Hallo,

wenn ich ein DB.TField von eienr TZQuery habe, wie kann ich dann herausfinden, aus welcher Tabelle dieses Feld stammt?

Ich habe eben noch mal die OH gewälzt, und dabei gesehen, dass Delphi von Haus aus auch schon Persistenz ermöglicht, z.B. für die datensensitiven Komponenten. Wie nutzt man dieses Feature? Gibt es irgendwas, das dagegen spricht, es zu benutzen?

Danke


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:38 Uhr.
Seite 1 von 2  1 2      

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