AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Wieder mal die Tabellenstrukturen
Thema durchsuchen
Ansicht
Themen-Optionen

Wieder mal die Tabellenstrukturen

Ein Thema von stOrM · begonnen am 18. Mai 2017 · letzter Beitrag vom 23. Mai 2017
Antwort Antwort
Seite 4 von 6   « Erste     234 56      
Benutzerbild von stOrM
stOrM

Registriert seit: 7. Jun 2003
Ort: Mülheim an der Ruhr
436 Beiträge
 
Delphi 10.3 Rio
 
#31

AW: Wieder mal die Tabellenstrukturen

  Alt 18. Mai 2017, 16:41
Angebotsgültigkeit ist ein Problem für sich: Hier reicht eigentlich ein Datumsfeld, um die Gültigkeit des Angebots zu prüfen.

Anders sieht es aus, wenn von einem Angebot verschiedene Versionen im Umlauf sind, wenn zum Beispiel das Angebot nachgebessert wird. Dann wird es richtig aufwändig. War hier aber nicht gefragt.

Stichwort Tabellensalat: Ich habe dir nicht umsonst ein sehr plattes, aber halbwegs normalisiertes Datenmodel geschickt. In der Grafik (die hier recht klein ausgefallen ist) sind die Beziehungen (Relationen) zwischen den Tabellen aufgezeichnet. Die helfen dir bei der Zuordnung der einzelnen Datenfelder.

@Haentschman: Grundsatz, den ich bereits vor 30 Jahren lernen musste: Eine Datenbanktabelle ohne Primary Key ist BÄH! JEDE Tabelle - und wenn sie noch so klein ist - muss einen PK haben! In meiner Notation ist das immer das Feld mit dem Namen ID (den Präfix spare ich mir mal).

Grüße
mikhal
war auch sehr nett von Dir.
Das Problem ist, grad wenn man das zum ersten mal macht, hat jeder eine Idee (ist ja auch super) nur überfordert das oft (mich zumindest. Erst hatte ja Haetschman da mit mir angefangen an einer groben Struktur und dann kam dein tolles Model inkl. den Verknüpfungen nur an dem Schritt bin ich ja noch gar nicht, da ich nicht weiss warum A mit B und C mit F das muss ich erst mal kapieren.
Was mir noch aufgefallen ist bei Dir gibt es Generatoren? Ich glaube das kann ich in MySQL wohl vergessen oder über Umwege?
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#32

AW: Wieder mal die Tabellenstrukturen

  Alt 18. Mai 2017, 17:30
Das Problem ist, grad wenn man das zum ersten mal macht, hat jeder eine Idee (ist ja auch super) nur überfordert das oft (mich zumindest. Erst hatte ja Haetschman da mit mir angefangen an einer groben Struktur und dann kam dein tolles Model inkl. den Verknüpfungen nur an dem Schritt bin ich ja noch gar nicht, da ich nicht weiss warum A mit B und C mit F das muss ich erst mal kapieren.
Was mir noch aufgefallen ist bei Dir gibt es Generatoren? Ich glaube das kann ich in MySQL wohl vergessen oder über Umwege?
Falls das erste Zitat stimmt, dann ist das vollkommen unerheblich, da Du nicht sooo viele Vorkenntnisse hast.
Was an Mikhals Vorschlag verstehst Du nicht?

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#33

AW: Wieder mal die Tabellenstrukturen

  Alt 18. Mai 2017, 17:49
Was mir noch aufgefallen ist bei Dir gibt es Generatoren? Ich glaube das kann ich in MySQL wohl vergessen oder über Umwege?
Das spielt für ein logisches Modell keine Rolle, ein physisches (Berücksichtigung des konkreten RDBMS) muss das dann entsprechend adaptieren. In mysql wahrscheinlich autoincrement Felder. Tja und wo wir gerade beim Thema sind, wenn Du (noch) die Wahl hast, empfehle ich als Alternative zu mySQL Firebird oder Postgres. Beide können Geneneratoren/Sequenzen (und natürlich mehr, weswegen ich sie empfehle)
Gruß, Jo
  Mit Zitat antworten Zitat
Benutzerbild von stOrM
stOrM

Registriert seit: 7. Jun 2003
Ort: Mülheim an der Ruhr
436 Beiträge
 
Delphi 10.3 Rio
 
#34

AW: Wieder mal die Tabellenstrukturen

  Alt 19. Mai 2017, 12:59
So ich bin nun endlich dazu gekommen, Mikhal’s Vorschlag in MySQL zu importieren.

Da ich aus verschiedenen Gründen MySQL nutzen muss, und dort keine Generatoren zur Verfügung stehen, sehe ich das richtig das nun in jeder Tabelle das erste Feld, sprich das „ID“ also das Feld mit dem Primary Key drauf, auf auto increment gesetzt werden muss?

Jetzt wo ich das ganze vor mir habe und die Verknüpfungen der Tabellen untereinander sehe stellen sich mir weitere Fragen dazu:

Wie ist denn jetzt das vorgehen wenn man so eine Struktur hat auf der Programmiertechnischen Ebene?

1. Ich müsste ein Query erstellen das die Verknüpfung der Tabellen untereinander berücksichtigt, die Felder auswählen, die zur Eingabe benötigt werden und in einer Maske anzeigen, die der Benutzer ausfüllen muss?

Also so was in der Art:

Code:
SELECT
  Hier die Felder aus den verschiedenen Tabellen die ich zum Anzeigen und ausfüllen brauche?
FROM
  kunden
  INNER JOIN anschriften ON anschriften.ANS_KUN_ID = kunden.KUN_ID
  INNER JOIN angebote ON angebote.ANG_KUN_ID = kunden.KUN_ID
  INNER JOIN angebotspositionen ON angebotspositionen.POS_ANG_ID = angebote.ANG_ID
  INNER JOIN einheiten ON angebotspositionen.POS_EIN_ID = einheiten.EIN_ID
  INNER JOIN preise ON preise.PRE_EIN_ID = einheiten.EIN_ID
  INNER JOIN produkte ON angebotspositionen.POS_ART_ID = produkte.ART_ID AND preise.PRE_ART_ID = produkte.ART_ID
2. Wie berechnet man die Preise und ggf. weitere Dinge wie Ablaufdatum des Angebots automatisch anhand der später vorliegenden Daten?
Ich hatte einige Tage zuvor, bevor ich mich an Euch gewandt hatte, ja selber immer wieder angefangen Tabellenstrukturen dafür zu erstellen und immer wieder auch verworfen. Was aber dabei raus kam, war dann die Idee mit einem VIEW wo ich dann so etwas gemacht hatte:

CAST(((`angebots_scheme`.`angebote`.`anzahl` * `angebots_scheme`.`artikel`.`ek_preis`) * `angebots_scheme`.`angebote`.`aufschlag`) AS DECIMAL (18 , 2 )) AS `G-Preis`

Wäre das einigermaßen sinnvoll, oder wie würdet Ihr so etwas machen?

3. Ich hoffe ich habe das nun einigermaßen kapiert, warum man weitere Tabellen anlegt und nicht alles z.B. in eine schreibt, dabei taucht dann wieder eine Frage auf:
Wenn man jetzt mal beim Mikhal die Anschriften Tabelle als Grundlage nehmen würde, wenn man dort nun ein Feld Postleitzahl hätte, was sich ja beim Umzug eines Kunden, immer wieder ändern würde, müsste ich dann eine Tabelle Postleitzahlen,Orte anlegen welche dann auf die Kunden Tabelle wiederum verweist, KUN_ID?

4. Bei Mikhal’s Model fehlt mir noch die Zonen Tabelle die aus 3 Feldern bestehen sollte:

ZON_ID, (PK)
ZON_BEZEICHNUNG (VARCHAR)
ZON_PREIS (DECIMAL)

Verstehe ich es richtig, wenn ich nun in der Kunden (oder Anschriften) Tabelle ein Feld KUND_ZON_ID anlege damit auf die Tabelle Zonen Feld ZON_ID verweisen muss?
Der Grund dieser Tabelle ist, das Anfahrtswege zum Kunden durch Zonen geregelt werden, z.B. Zone 1 wäre bis 25 KM oder so etwas in der Art, Preis 15,00€ pauschal, welche dann wiederum als Position Anfahrtskosten oder wie auch immer im Angebot auftauchen würde. Dies ist ja bei Umzug eines Kunden auch wieder ein Feld was sich verändern kann, daher der Gedanke zu einer weiteren Tabelle.

5. Die Angebote Tabelle von Mikhail besitzt das Feld Angebot Datum.
Wenn ich eine Gültigkeit für ein Angebot setzen möchte (von - bis) z.B. würde es reichen wenn (sofern die Idee mit meinem View für die Berechnungen richtig war)
das man dort z.B. das ANG_DATUM + (VerfallsTage) errechnen lässt?

Ich habe darüber nachgedacht ob ich später in den Tabellen Datensätze löschen soll oder nicht, irgendwie macht mir das Sorgen, deshalb dachte ich, ist es vielleicht ok, wenn man das nicht macht (aus Angst auf irgendwelche Probleme zu stossen die ich noch nicht kenne, weil mir dazu die Grundlagen fehlen) das man einfach nur ein flag setzt (aktiv 0,1) und so dieses Angebot oder was auch immer später im Query beim abrufen der Daten über Where Klausel einfach berücksichtig. So tauchen diese Daten eben nicht mehr auf für den Benutzer sind aber weiterhin vorhanden in der Tabelle.

So würde ich es dann beim Ablaufdatum eines Angebotes machen, View hat das Ablaufdatum errechnet, ich schaue über ein Query in der Angebot Tabelle nach und setz aktiv auf 0

6. Die Angebotspositionen nehmen den Preis auf, eine Änderung des Preises in der Preistabelle wird sich dann nicht auf das Angebot auswirken. Darüber hinaus habe ich in der Preistabelle die Möglichkeit geschaffen, einen Gültigkeitszeitraum für den Preis zu definieren.

Was heißt das genau für mich, wenn ein Preis seine Gültigkeit erreicht hat setz ich das PRE_GUELTIG_BIS auf das entsprechende Datum? Ich kenne im Vorfeld ja nicht den Gültigkeitszeitraum, was ist wenn dieser erreicht ist, muss dann ein neuer Preis hinterlegt werden? Oder wie soll das gemacht werden, dass ist mir nicht klar im Moment.

7. Die Anschrift besitzt ein Feld Anschrifttyp, der als SmallInt definiert ist (1=Lieferadresse, 2=Rechnungsadresse, 3=abweichende Lieferadresse...), kann man auch über eine Nachschlagetabelle realisieren.

Wie ist das genau gemeint, bzw wie wird das gemacht, ist ebenfalls noch nicht ganz klar.
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#35

AW: Wieder mal die Tabellenstrukturen

  Alt 19. Mai 2017, 13:51
mal auf die Schnelle zu Deinen ersten beiden Punkten.

Du würdest nicht solche (riesigen) Joins bauen und das Ergebnis editieren.
Solche ein Select wie unter (1) würdest Du ggf in einem Report benötigen, vermutlich nicht mal da.

Wenn Du Adressen erfasst (Eingabe), hast Du ein query für die Adresstabelle. Wenn es ein Artikel ist, dann ein Query für die Artikel usw.
Verbindungen wie Du sie im Selectstatement oben später nutzt, stellst Du bei der Eingabe bspw. durch DBLookupcombobox her oder durch die Nutzung von Master Detail Properties in Datasets.

Damit würde ich jedenfalls anfangen. Eins nach dem anderen. Erfassung von Kunden, Kundenadressn, Artikeln usw., alles nach dem gleichen Muster.
Wenn das läuft und das Vorgehen / Implementierung klar ist, kannst Du komplexere Eingabemasken in Angriff nehmen, z.B. gemeinsame Erfassung von Kunde und Hauptanschrift. Usw. usf.

Wichtig ist erstmal, dass Du alles sauber rein und raus bekommst (und bei Bedarf reporten kannst> hier sind dann je nachdem größere Joins notwendig, mit einem guten Reportdesigner aber auch nicht so sehr)

Vergessen: Berechnung von Preisen etc. , Dein Ansatz ist ok, man kann hier und an anderen Stellen über die Nutzung von Views nachdenken. Das sind sozuagen benannte select Statement, mit denen man immer wieder kehrende Aufgaben (Darstellungen) sauber abbilden kann.
Gruß, Jo

Geändert von jobo (19. Mai 2017 um 13:54 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von mikhal
mikhal

Registriert seit: 11. Sep 2003
Ort: Linz am Rhein
796 Beiträge
 
Delphi 11 Alexandria
 
#36

AW: Wieder mal die Tabellenstrukturen

  Alt 19. Mai 2017, 14:19
Deine Fragen 1 und 2 hat Jobo ja bereits beantwortet. Hier meine Antworten zu den folgenden Fragen:

Zu 3): Natürlich kannst du die PLZ als zusätzliches Feld aufnehmen, genauso wie die Straße, den Ort etc. Dazu benötigst du keine zusätzliche Tabelle für die PLZ, es sei denn, du möchtest dir das Eintippen des Ortes sparen, dann benötigst du eine Tabelle mit der PLZ und dem Ortsnamen. Dann kannst du nachdem die PLZ in dieser Tabelle gefunden wurde, den Ortsnamen automatisch ziehen. Referenzieren musst du dann den PK der Postleitzahlen-Tabelle in deinem Anschriftendatensatz: PK in PLZ-Tabelle PLZ_ID Integer, zusätzliches Feld ANS_PLZ_ID Integer als FK (Fremdschlüssel oder Foreign Key).

zu 4): Kannst du so machen, ich hätte es aber als Produkt geführt, damit ich die Preisfindung leichter realisieren kann (Stichwort: Gültigkeitszeitraum). Aufwendig wird bei der Nutzung einer Zonentabelle die Zuordnung in der Angebotsposition, hier gibt es in meinem Datenmodell keine Referenz zu einer Zonentabelle, musst du dann ergänzen. ACHTUNG: Dann bekommst du ein Problem mit dem Artikel, denn der FK ANG_ART_ID ist im Modell NOT NULL definiert, muss also gefüllt werden! Dein Ansatz die Zone beim Kunden zu hinterlegen ist nicht falsch, dann solltest du aber tatsächlich eine Funktion schreiben, die aus dieser Zoneninformation einen Dummy-Artikel im Angebot generiert (der muss im Produktstamm angelegt sein), der über die Preistabelle der Produkte den richtigen Preis im Angebot aufführt.

zu 5): Richtig, das Datum bezieht sich auf das Erfassungsdatum, wenn du im Programm oder einer Hilfstabelle einen festen Zeitraum für die Gültigkeit eines Angebots festlegst, kannst du das Enddatum berechnen. Du solltest aber ein weiteres Datenfeld in der Tabelle aufnehmen, dass dieses errechnete Datum aufnimmt. Sollte sich später einmal dieser vorgegebene Zeitraum ändern, wirst du falsche Daten berechnen.

zu 6): Richtig

zu 7): Ja, ich habe es mir hier einfach gemacht. Ich schrieb ja bereits, dass dieses Modell flach und einfach gehalten ist.

Grüße Mikhal
Michael Kraemer
Computer erleichtern die Arbeit...
...und die Erde ist eine Scheibe!
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#37

AW: Wieder mal die Tabellenstrukturen

  Alt 19. Mai 2017, 15:40

7. Die Anschrift besitzt ein Feld Anschrifttyp, der als SmallInt definiert ist (1=Lieferadresse, 2=Rechnungsadresse, 3=abweichende Lieferadresse...), kann man auch über eine Nachschlagetabelle realisieren.

Wie ist das genau gemeint, bzw wie wird das gemacht, ist ebenfalls noch nicht ganz klar.
Du hast eine "Kundentabelle"und eine "Anschrifttabelle".
in der Anschrifttabelle gibt es
AnschriftID
KundenID
Anschrifttyp
Strasse,Ort,plz (usw. was man so braucht)

in Anschrifttyp kommt dann die 1,2,3,4..x hinein, über die definiert wird was für ein Typ (Rechnungsadresse, Lieferadresse, primäre Adresse...) das ist.

Wenn Du jetzt an einen Kunden liefern willst, dann kommt auf den Lieferschein die Lieferadresse und auf die zu erstellende Rechnung die Rechnungsadresse. Soweit ist das ja wohl einsichtig.
select Name,strasse,plz,ort from kundentable join adresstable on (kundentavle.kundenID=adresstable.kundenID and adresstable.adresstyp=x) Interessant wird es wenn Du keine Lieferadresse erfasst hast. Dann könntest Du
a) davon ausgehen, das das dem Büro schon auffällt und die entsprechenden Korrekturen durchgeführt werden.
b) eine Fehlermeldung ausgeben
c) falls die Lieferadresse,Rechnungsadresse.... fehlt, die primäre Adresse ausgeben
d) es garnicht dazu kommen lassen, da immer alle Adressen erfasst werden müssen und sei es durch ein automatisches klonen der Daten
e) da der adresstyp auch eine Wertigkeit beinhaltet, bei der Suche nach einer Adresse, sollte diese nicht vorhanden sein, Du die höherwertige Adresse ausgibst.

und da gibt es bestimmt noch ein paar Winkelzüge um das noch verwirrender zu gestalten.
Des weiteren kann man natürlich auch die Adressen mit einem Gültigkeitsdatum, bzw einem Zeitraum versehen.
Langer Rede kurzer Sinn, neben den Daten für die DB-Struktur KundenID,AdressID und den nackten Nutzdaten Strasse,PLZ,Ort (Gebäude no??) benötigst Du noch interne Verwaltungsdaten Startdatum,Endedatum,Adresstyp usw.

Wichtig hierfür ist, daß Du weißt welche Arbeitsabläufe Du mit welchen Daten du abbilden willst.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
jobo

Registriert seit: 29. Nov 2010
3.072 Beiträge
 
Delphi 2010 Enterprise
 
#38

AW: Wieder mal die Tabellenstrukturen

  Alt 19. Mai 2017, 22:15
Noch ein paar Anmerkungen:

zu 4)
Die Zonen müssen sich bei einem Datenmodell mit möglichen Mehrfachadressen nicht auf den Kunden, sondern auf die Adressen, bzw. die jeweils verwendete Lieferadresse beziehen bzw dort eingetragen werden. Genau genommen spielt sogar das Auslieferungslager mit rein, wenn es mehrere gibt.
Wenn Du nichts besseres zu tun hast, kannst Du auch gleich mit Entfernungstabellen arbeiten.

zu 7.
Wurde ja schon erklärt. Grundsätzlich ist eine Nachschlagetabelle technisch nichts anderes als andere Tabellen. Sie hat keinen anderen Zweck als einen symbolischen Zahlwert durch Klartext zu ersetzen, spart etwas Platz und spart bei interner Verwendung des Symbolwertes Rechenleistung.
Der Nachschlagewert kann dann wiederum bei Bedarf übersetzt werden, geändert werden .. etc ohne dass man an der Verarbeitungslogik justieren muss. Diese Mechaniken baut man nach Bedarf auf, jeder hat da so seine Steckenpferde.
Nachschlage können untereinander wiederum klassifiziert werden, Priorisierungen, Sortierungen, je nachdem worum es geht.
Aber lieber klein anfangen. Ein Nachschlagetyp kommt im Zweifel auch ohne Nachschlagetabelle aus. Kann man alles nach und nach erweitern.
Gruß, Jo

Geändert von jobo (19. Mai 2017 um 22:19 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von stOrM
stOrM

Registriert seit: 7. Jun 2003
Ort: Mülheim an der Ruhr
436 Beiträge
 
Delphi 10.3 Rio
 
#39

AW: Wieder mal die Tabellenstrukturen

  Alt 21. Mai 2017, 06:12
@p80286 Danke für die weitere Ausführung, du kannst einem echt Mut machen

@Jobo, Danke Dir werd ich berücksichtigen.

@Mikhal
Du schriebst davon, dass sich der Ort dann automatisch ziehen lässt, dass hab ich entweder nicht richtig verstanden oder ich hab hier einen Fehler gemacht.
Ich habe in der Anschriften Tabelle zwei weitere Felder angelegt:

AN_PLZ, Typ Integer(5)
AN_ORT Typ Varchar

Dann habe ich eine Postleitzahlentabelle erstellt mit den Feldern:

PL_VORWAHL, Typ Integer
PL_PLZ, Int(5)
PL_ORT, Typ Varchar
PL_BUNDESLAND, Typ Varchar

In der Anschriften Tabelle den FK (FK_AN_PLZ) angelegt und so verknüpft:

AN_PLZ = PL_PLZ

Wenn ich jetzt eine Postleitzahl in der Anschriftentabelle eintrage wird der Ort aber dort nicht automatisch eingetragen (ich denke mal entweder habe ich deinen Satz komplett missverstanden oder einen Fehler gemacht)

Ich habe mir zwei Sachen dazu überlegt, für den Fall, dass ich es falsch verstanden habe, ich könnte über einen JOIN mit dem Parameter PLZ den Ort aus der Postleitzahlentabelle holen und dann in die Anschriften Tabelle schreiben. Ginge ja auch notfalls, oder z.B. über einen After Insert Trigger wäre das glaube ich ja auch möglich?
  Mit Zitat antworten Zitat
hstreicher

Registriert seit: 21. Nov 2009
221 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#40

AW: Wieder mal die Tabellenstrukturen

  Alt 21. Mai 2017, 09:26
es gibt hier einen großen Denkfehler bzgl der Postleitzahlen:
Eine Postleitzahl kann durchaus mehrere Orte umfassen

http://www.gutefrage.net/frage/eine-...eine-bestimmte

mfg Hannes
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 4 von 6   « Erste     234 56      


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 22:03 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