AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Einfaches Datenbankmodell
Thema durchsuchen
Ansicht
Themen-Optionen

Einfaches Datenbankmodell

Ein Thema von Delbor · begonnen am 25. Jun 2018 · letzter Beitrag vom 28. Jun 2018
Antwort Antwort
Seite 3 von 4     123 4      
Delbor

Registriert seit: 8. Okt 2006
Ort: St.Gallen/Schweiz
1.186 Beiträge
 
Delphi 11 Alexandria
 
#21

AW: Einfaches Datenbankmodell

  Alt 26. Jun 2018, 10:07
Hi zusammen
Delbor will eine Datenbankanwendung schreiben.
Welche Datenbank(en) genutzt wird/werden soll, steht im Eingangspost.
Um dies etws zu präzidieren: Das DB-Modell wurde/wird mit MySQL Workbench erstellt. Standartmässig können damit auch MySQL-Datenbanken erstellt werden(ForwardIngeneering). Es gibt aber ein Plugin für MySQL-Workbench, das die MySQL-DDL-Statements in solche, die für SQLite optimiert sind, exportiert.. Dieses werde ich allerdings wohl löschen und neu installieren müssen - zum Schluuss wird mir eine Fehlermeldung um die Ohren geschlage, wonach eine oder mehrere Python-Dateien fehlen.

Gruss
Delbor
Roger
Man muss und kann nicht alles wissen - man muss nur wissen, wo es steht.
Frei nach Albert Einstein
http://roase.ch
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.508 Beiträge
 
Delphi 7 Professional
 
#22

AW: Einfaches Datenbankmodell

  Alt 26. Jun 2018, 10:28
@Delphi.Narium

Wenn du bei einem "Unit-Test" die Trigger der Datenbank mittestest dann hast du per Definition keinen Unit-Test sondern einen Integration-Test.

Das sind zwei paar Schuhe.

Ein Unit-Test testet die kleinst mögliche Einheit (z.B. eine öffentliche Methode) ohne irgendwelche externen Abhängigkeiten (z.B. Datenbanken). Wenn es Abhängigkeiten gibt, dann werden diese per Mock bereitgestellt. So ein Unit-Test ist klein und schnell und wird bei jeder Quelltext-Änderung ausgeführt (siehe TestInsight).

Ein Integration-Test ist wesentlich fetter als der Unit-Test aufgrund der Abhängigkeiten (z.B. von der Datenbank) die jetzt auch mit im Boot sind. Weil diese gewöhnlich (wesentlich) länger dauern als die Unit-Tests, werden diese auch nur zu bestimmten Zeitpunkten ausgeführt (Einchecken im Repository, Release-Build, etc.)

Wer es weiß der kann es auch.

Eine Datenbank ist kein Übel, sondern Mittel zum Zweck und manchmal auch völlig überflüssig und ein paar schlichte Dateien hätten es auch getan.

Natürlich macht man sich Gedanken was für Datenstrukturen die Anwendung benötigt um ihre Aufgabe zu erledigen, aber eben völlig losgelöst von dem eventuell zu verwendenden Datenbank-System.

Hat man diese Strukturen und die Anwendung, dann ist die Datenbank-Anbindung nur noch ein Spaziergang und das Datenbank-System wird austauschbar.

Das ist professionell.
Meine Datenbankanwendungen sind grundsätzlich so geschrieben, dass ihnen die darunterliegende Datenbank egal ist. Bin es gewohnt mit Datenmengen umzugehen, bei denen sich eine Datenhaltung außerhalb einer Datenbank verbietet. Man müsste dann quasi selbst eine Datenbank implementieren, um mit den Datenmengen umgehen zu können. Das ist unsinnig und zu aufwändig.

D. h.: Die Datenbank ist (annähernd) beliebig austauschbar, aber das Datenmodell ist immer gleich. (Annähernd deshalb: Es gibt zwar 'nen SQL-Standard, aber so wirklich 100% kompatibel sind die Datenbanken da nicht.)
Aber es gibt Möglichkeiten das so flexibel zu gestalten, dass man ohne Programmänderung trotzdem die Datenbank wechseln kann.
  Mit Zitat antworten Zitat
Delbor

Registriert seit: 8. Okt 2006
Ort: St.Gallen/Schweiz
1.186 Beiträge
 
Delphi 11 Alexandria
 
#23

AW: Einfaches Datenbankmodell

  Alt 26. Jun 2018, 14:02
Hi TigerLilly
Danke für deine Antwort! Sehr umfassend!
Vielleicht zurück zum Anliegen des TE. Ergänzend zu noch nicht Gesagtem:

Allgemein:
* Die Tabellen alle mit TBL_ beginnen zu lassen ist überflüssig.
* Ich bevorzuge es, die IDs (=PKs) mit dem Tabellennamen zu benennen. So wie du es bei Tbl_User gemacht hast (Tbl_USer -> UserID), aber bei den anderen nicht (Tbl_Konto -> ID)
* Die IDs einmal mit und einmal ohne _ zu bennen ist nicht gut. Adress_ID und UserID ist eine ziemliche Fehlerquelle.
* Ich würde nicht mit den Standarddatentypen arbeiten, sondern UDDT, also selbst definierte Typen, verwenden + allen Feldern, die gleichen Typ haben, diesen zuordnen. Also statt FLOAT bei Beträgen würde ich einen UDDT "Betrag" vom Typ Float zwischenschalten. Diesen ev. mit Default oder not null etc aufpeppen. Das macht es dann zB leichter alle Telefonnummern zu verlängern, weil du nur einmal den UDDT ändern musst.
* Mach dich über den Unterschied zwischen VARCHAR und NVARCHAR schlau.
* INT INTEGER DEC FLOAT ist ein ziemliches Typgemisch - siehe vorher UDDT.
* "Text" als Feldname ist unglücklich, da a) nichtssagend + b) oft ein reserviertes Wort.
* Tabellennamen sollten einheitlich entweder alle Einzahl oder alle Mehrzahl sein. Jetzt gibt es die Tbl_Firma, aber auch die Tbl_Adressen.


Tbl_Konto
* Wenn Saldo die Differenz/Summe aus Gutschrift und Belastung ist, lass es. Das kannst du als Abfrage ausrechnen. Außer du musst Rundungseffekte berücksichtigen, dann kann das sinnvoll sein.
* Vertrag_ID verweist wohin? Ist das nicht redundant, denn über die Rechnung kommst du ja auch zum Vertrag?

Tbl_Adressen
* Mir fehlt da Land+PLZ+eine zweite Adresszeile
* 45 zeichen für die Straße können knapp werden
* Das Design ist da etwas komisch - es gibt Adressen + User+Firmen bekommen welche zugeordnet?

Tbl_User
* da gibt es drei Verweise in die Tbl_Adressen. Warum?

Ich lass es mal gut sein - da gibt es schon Dinge zum Bessermachen
Zu Allgemein:
  1. In der Bilddatenbanh hatte ich ursprüngich Namen wie 'Bildtabelle' oder 'KategorienTabelle verwendert. Workbench generierte daraus im Falle von Interselektionstabellen Feldname wie 'Bildtabelle_to_KategorienTabelle' oder 'BildtabelleFeldname_to_KategorienTabelleFeldname' . Irgendwann hab ich das dann geändert und möglichst kurze Namen verwendet, wobei ich das'Tbl_' einführte - das soll mir vor allem im Code klar aufzeigen, dass ich mit einer Tabelle arbeite.
  2. Das ist sicher übersichtlicher
  3. Werd ich korrigieren
  4. ??
  5. Werd ich korrigieren. Wenn ich das richtig verstehe (was ich im Moment eher bezweifle), ergibt das einen Datentyp, der aus mehren Feldern besteht - wobei: Nur einmal den UDDT ändern zu müssen, klingt schomal gut.. Zu UDDT hab ich bisher dies und das gefunden. Noch nicht viel, wie ich finde.

Das überarbeitete Modell steht soweit, ich muss es allerdings nochmal durchsehen.

Gruss
Delbor
Roger
Man muss und kann nicht alles wissen - man muss nur wissen, wo es steht.
Frei nach Albert Einstein
http://roase.ch
  Mit Zitat antworten Zitat
TigerLilly

Registriert seit: 24. Mai 2017
Ort: Wien, Österreich
1.211 Beiträge
 
Delphi 11 Alexandria
 
#24

AW: Einfaches Datenbankmodell

  Alt 26. Jun 2018, 16:00
Sorry, ich hab nicht gesehen, dass SQLite dein target ist. UDDTs gehen da gar nicht + VARCHAR/NVARCHAR auch nicht.
  Mit Zitat antworten Zitat
Delbor

Registriert seit: 8. Okt 2006
Ort: St.Gallen/Schweiz
1.186 Beiträge
 
Delphi 11 Alexandria
 
#25

AW: Einfaches Datenbankmodell

  Alt 26. Jun 2018, 17:39
Hi zusammen

@ TigerLilly:
Ich werde wohl noch andere Datentypen von Hand anppassen müssen, wenn es mir nicht gelingt, das Workbench-Plugin für SQLite-Export neu zu installieren. Wobei das wohl alles nuur halb so wild ist, wie es sich anhört: ich habe auch noch das Tool SQLIte Expert auf der Platte - leider nur in der Personal-Edition. Die Professional hätte einen grafischen Designer ála Workbench mit an Board. Leider sehe ich keine Möglichkeit, das Ding Online zu kaufen - preislich würde es sich durchaus in einem vertretbaren Rahmen halten.
Anrerseits liessen sich die Tabellen auch mit der Personal aufgrund des Workbench-Modells erstellen - zwar mehr oder weniger 'von Hand. Egal, irgendwie krieg ich das schon hin.

Inzwischen habe ich das Modell überarbeitet:
17_18_18-pdfofficerdata.jpg

Ich hab auch eine Kontobeschreibungs-Tabelle eingebaut, analog zur Empfehlung von hstreicher, eine Kontokopf-Tabelle einzuführen - ich seh mich schon, wie ich mir an den Kopf greife angesichts einer Bildschirmseite voller gleichlautender Kontonamen...
Beim ersten Entwurf der Tabellen hatte ich die erfordrlichen Fremdschlüssel-Felder mit eingefügt, und als ich die Beziehungen einzeichnete, tat Workbench nochmals dasselbe - ich hoffe nur, ich hab jetzt alle "Bösewichte" erwischt.

Gruss
Delbor
Roger
Man muss und kann nicht alles wissen - man muss nur wissen, wo es steht.
Frei nach Albert Einstein
http://roase.ch
  Mit Zitat antworten Zitat
mkinzler
(Moderator)

Registriert seit: 9. Dez 2005
Ort: Heilbronn
39.861 Beiträge
 
Delphi 11 Alexandria
 
#26

AW: Einfaches Datenbankmodell

  Alt 26. Jun 2018, 18:13
Alternativ die Community Edition von DBeaver

https://dbeaver.io/
Miniaturansicht angehängter Grafiken
dbeaver-sqlite.jpg  
Markus Kinzler
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.508 Beiträge
 
Delphi 7 Professional
 
#27

AW: Einfaches Datenbankmodell

  Alt 26. Jun 2018, 18:15
Schau Dir bitte nochmal die ganzen Fremdschlüssel an, da scheint einiges mehrfach zu sein.

Warum hat TblAdressen einen Fremdschlüssel auf Tbl_User_UserID? Müsste das nicht umgekehrt sein? Ein User verweist auf eine der Adressen und nicht eine Adresse verweist auf einen User?
Was ist denn, wenn zwei User die gleiche Adresse haben? Wird die Adresse dann doppelt abgelegt, weil sie nur auf einen User verweisen kann?
Oder müssten nicht die beiden User auf die gleiche Adresse verweisen, um eine doppelte Speicherung einer Adresse zu vermeiden?

Warum ist die Kontonr vom Typ Int? Gibt es keine Kontonummern mit führenden Nullen?
Warum ist die KontoNr auch als Konto-Nr in der Tbl_Kontobeschreibung enthalten? Sind damit unterschiedliche Kontonummern gemeint?

Warum heißt die Tabelle TblUser TblUser, aber die Fremdschlüssel, die auf sie verweisen, Tbl_User_UserID.

Warum gibt es in der Tabelle TblRechnungen einen Fremdschlüssel Tbl_Vertrag_Tbl_Firma_ID.
'ne Rechnung gehört zu einem Vertrag, ein Vertrag zu einer Firma, aber deshalb muss die Rechnung noch lange keinen Fremdschlüssel auf den Vertrag haben. Das ist eine zusätzlich zu pflegende Redundanz (die man allenfalls bei 'ner (z. B. aus Performanzgründen erforderlichen) Denormalisierung einführen kann.

Ähnliches kommt wiederholt vor.

Geändert von Delphi.Narium (26. Jun 2018 um 18:17 Uhr) Grund: Schreibfehler
  Mit Zitat antworten Zitat
Delbor

Registriert seit: 8. Okt 2006
Ort: St.Gallen/Schweiz
1.186 Beiträge
 
Delphi 11 Alexandria
 
#28

AW: Einfaches Datenbankmodell

  Alt 27. Jun 2018, 10:27
Hi Delphi.Narium

Zitat:
Warum hat TblAdressen einen Fremdschlüssel auf Tbl_User_UserID?
Ich habe da eine 1.1-Beziehung eingerichtet, da ich davon ausgegangen bin, dass es genau einen User an genau einer Adresse gibt. Aber das ist falsch, da ja auch die Ehefrau des Users Einkommen haben kann und/oder Rechnungen bezahlen muss. Und das Taschengeld der Kinder, bezw. was die damit machen, will/soll auch verwaltet werden/werden können.
Und natürlich können zwei User an der selben Adresse zuhause sein, aber verschiedenen Familien angehören.

Zitat:
Warum ist die Kontonr vom Typ Int? Gibt es keine Kontonummern mit führenden Nullen?
Dass ist schlicht ein Flüchtigkeitsfehler. Ohne wirklich zu wissen, dass es so ist, könnten Kontonummmern wohl auch Alphanummerische Zeichen enthalten.
Zitat:
Warum ist die KontoNr auch als Konto-Nr in der Tbl_Kontobeschreibung enthalten? Sind damit unterschiedliche Kontonummern gemeint?
Auch das ist ein Flüchtigkeitsfehler: ich habe schlicht vergessen, die Kontonummer aus der Kontotabelle zu löschen.

Zitat:
Warum heißt die Tabelle TblUser TblUser, aber die Fremdschlüssel, die auf sie verweisen, Tbl_User_UserID.
Die Fremdschlüssel werden jeweils von Workbench angelegt, aber, wenn ich das richtig gesehen habe, nicht unbedingt angepasst, wenn ich die Beziehung löschen und sie neu anlege.

Zitat:
Warum gibt es in der Tabelle TblRechnungen einen Fremdschlüssel Tbl_Vertrag_Tbl_Firma_ID.
Wie ich oben schon gesagt habe, legt Workbench die Fremdschlüssel an. Und das hat damit zu tun:

09_09_01-foreignkeys.jpg

Wenn hier Restrict festgelegt wird, kann gar nichts gelöscht werden. Bei allen anderen Möglichkeiten müsste ich mich erst schlau machen.

Und nun möchte ich mich endlich ganz herzlich bei mkinzler bedanken. Ab nun werde ich das Modell mit dbeaver neu erstellen.

Gruss
Delbor
Roger
Man muss und kann nicht alles wissen - man muss nur wissen, wo es steht.
Frei nach Albert Einstein
http://roase.ch

Geändert von Delbor (27. Jun 2018 um 10:52 Uhr) Grund: Der letzte Anhang liesssich nicht anzeigen. In der Vorschau hats jetzt geklappt - ich hoffe, das bleibt jetzt so
  Mit Zitat antworten Zitat
TigerLilly

Registriert seit: 24. Mai 2017
Ort: Wien, Österreich
1.211 Beiträge
 
Delphi 11 Alexandria
 
#29

AW: Einfaches Datenbankmodell

  Alt 28. Jun 2018, 07:49
Das ist gut zu lesen:
https://www.talend.com/blog/2017/05/...ctices-part-1/

Auch gut ist das Stichwort "Konzeptionelles Datenmodell".
Es gibt viele Tools, die das unterstützen + damit klebt man nicht von beginn an schon an den Möglichkeiten der target-DB.
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.116 Beiträge
 
Delphi 12 Athens
 
#30

AW: Einfaches Datenbankmodell

  Alt 28. Jun 2018, 08:35
Allgemein:
* Die Tabellen alle mit TBL_ beginnen zu lassen ist überflüssig.
* Ich bevorzuge es, die IDs (=PKs) mit dem Tabellennamen zu benennen. So wie du es bei Tbl_User gemacht hast (Tbl_USer -> UserID), aber bei den anderen nicht (Tbl_Konto -> ID)
* Die IDs einmal mit und einmal ohne _ zu bennen ist nicht gut. Adress_ID und UserID ist eine ziemliche Fehlerquelle.
* Ich würde nicht mit den Standarddatentypen arbeiten, sondern UDDT, also selbst definierte Typen, verwenden + allen Feldern, die gleichen Typ haben, diesen zuordnen. Also statt FLOAT bei Beträgen würde ich einen UDDT "Betrag" vom Typ Float zwischenschalten. Diesen ev. mit Default oder not null etc aufpeppen. Das macht es dann zB leichter alle Telefonnummern zu verlängern, weil du nur einmal den UDDT ändern musst.
* Mach dich über den Unterschied zwischen VARCHAR und NVARCHAR schlau.
* INT INTEGER DEC FLOAT ist ein ziemliches Typgemisch - siehe vorher UDDT.
* "Text" als Feldname ist unglücklich, da a) nichtssagend + b) oft ein reserviertes Wort.
* Tabellennamen sollten einheitlich entweder alle Einzahl oder alle Mehrzahl sein. Jetzt gibt es die Tbl_Firma, aber auch die Tbl_Adressen.
Solche Konventionen finde ich immer sehr gut, ich arbeite zwar nicht mit den komplexesten DBs aber hilfreich ist das immer.
Das kann ich Alles unterstreichen, und weiche davon nur in Sonderfällen ab (OK bei den Datentypen manchmal).

Zitat:
* Ich bevorzuge es, die IDs (=PKs) mit dem Tabellennamen zu benennen.
Ich benutze im Moment zwar möglichst konsequent ID, das sit aber eine gute Idee, werde ich mir mal ansehen.

Was ich als Konvention für mich festgestellt habe ist das bei den meisten Tabellen eine
möglichst gleiche Nomenklatur benutzen sein kann (nicht bei Allen Tabellen wohlgemerkt).
In der Art:
  • ID(_xxxx) - als PK
  • Name - Passt fasst immer, da muss ich nicht XxxxName schreiben, denn der Zusammenhang macht es klar
  • Descr - eine Beschreibung zum Eintrag kann ich auch ziemlich oft dazunehmen
  • ChgFirst - Oft ist es sinnvoll den Ersteller des Records zu protokollieren
  • ChgLast - sowie Wer hat den Record zuletzt geändert
  • ChgTime - und wann war das

Rollo
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 4     123 4      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:05 Uhr.
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