![]() |
AW: Wieder mal die Tabellenstrukturen
Zitat:
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? |
AW: Wieder mal die Tabellenstrukturen
Zitat:
Zitat:
Was an Mikhals Vorschlag verstehst Du nicht? Gruß K-H |
AW: Wieder mal die Tabellenstrukturen
Zitat:
|
AW: Wieder mal die Tabellenstrukturen
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:
2. Wie berechnet man die Preise und ggf. weitere Dinge wie Ablaufdatum des Angebots automatisch anhand der später vorliegenden Daten?
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 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. |
AW: Wieder mal die Tabellenstrukturen
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. |
AW: Wieder mal die Tabellenstrukturen
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 |
AW: Wieder mal die Tabellenstrukturen
Zitat:
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.
SQL-Code:
Interessant wird es wenn Du keine Lieferadresse erfasst hast. Dann könntest Du
select Name,strasse,plz,ort from kundentable join adresstable on (kundentavle.kundenID=adresstable.kundenID and adresstable.adresstyp=x)
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 |
AW: Wieder mal die Tabellenstrukturen
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. |
AW: Wieder mal die Tabellenstrukturen
@p80286 Danke für die weitere Ausführung, du kannst einem echt Mut machen :-D
@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? |
AW: Wieder mal die Tabellenstrukturen
es gibt hier einen großen Denkfehler bzgl der Postleitzahlen:
Eine Postleitzahl kann durchaus mehrere Orte umfassen ![]() mfg Hannes |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:38 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