![]() |
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:
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.
Table "Entries":
ID: int AuthorID: int Text: text; Table "Users": ID: int Name: int 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 |
Re: Datenstruktur clientseitig abbilden?
Vielleicht hilft Dir
![]() |
Re: Datenstruktur clientseitig abbilden?
Zitat:
|
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. |
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... |
Re: Datenstruktur clientseitig abbilden?
Suchst du sowas wie Hashmaps? Hier giobts ein Link zu ner Implementierung in Delphi:
![]() |
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:
Man muss halt nur darauf achten, im Delete, Clear, Destroy usw. des TStrings-Objektes die enthaltenen TEntry-Objekte wieder freizugeben.
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; |
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:
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! |
Re: Datenstruktur clientseitig abbilden?
Zitat:
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 ( ![]() Je weiter du mit deiner Klassenbibliothek kommst umso schwieriger werden die Probleme. Viele haben schon aufgegeben z.B. ![]() Aber lass dich nicht von mir entmutigen. :hi: Weitere Ideen kannst du ![]() Oder vielleicht möchtest du auch das ![]() |
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 00:53 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 by Thomas Breitkreuz