Grundlagenproblem Datenmodellierung

Aufgabenstellung: Für jeden Kunden soll eine Liefer- und eine Rechnungsadresse gespeichert werden können, aber nicht alle Kunden haben eine separate Rechnungsadresse.

Lösungsansatz:
In einer SQL-Datenbank würde ich die Beziehung zwischen einem Kunden und seinen Adressen folgendermaßen modellieren:

Kunde
Kundennummer
Vorname
Nachname

Adresse
Kundennummer
Adressart // mögliche Werte “Rechnungsadresse” und “Lieferadresse”
Straße
PLZ
Ort
Land

Über die Kundennummer und die Adressart kann ich für meine Kunden die gewünschte(n) Adresse(n) abrufen.

Lösungsansatz 4D 1:
In 4D habe ich das schöne Feature der Verknüpfungen. Auf die oben beschriebene Struktur kann ich sie aber nicht anwenden, weil eine Verknüpfung immer zwischen genau zwei Felder existiert. Würd ich in dem Beispiel die Felder Kundennummer für die Verknüpfung verwenden, erhielte ich für eine Kundennummer alle Adressen, obwohl ich typischerweise nur die Adresse einer Art, also Rechnungs- oder Lieferadresse, haben möchte.

Lösungsansatz 4D 2:
Eine Möglichkeit dieses Dilemma zu lösen, wäre für jede Adressart eine eigene Tabelle anzulegen. Die Struktur sähe dann so aus:

Kunde
Kundennummer
Vorname
Nachname

Adresse_Rechnung
Kundennummer
Straße
PLZ
Ort
Land

Adresse_Lieferung
Kundennummer
Straße
PLZ
Ort
Land

Vorteil: Für einen Kunden sind die korrekten Adressen immer geladen und ich kann sie einfach in einem Formular anzeigen.
Nachteil: Die Struktur muss geändert werden (neue Tabelle), wenn es in Zukunft weitere Adressarten gäbe.

Lösung durch Erweitern von Lösungsansatz 4D 1: Nach Ausführung eines relate many-Befehls könnte man jetzt die Auswahl in der Adresstabelle mit Hilfe der Adressart einschränken. Diese Lösung gefällt mir im Moment am besten.

Ich freue mich über Meinungen zu den Lösungsansätzen.

Das SQL Beispiel hinkt etwas.

Sie können dies 1:1 auch mit 4D abbilden. Gleiche Struktur, gleiche Vorgehensweise.
Nur schreiben Sie halt eine andere Syntax, also statt Select…Join verwenden Sie Query bzw Query by Formula.

Was wegfällt ist die automatische Verknüpfung, nur gibt es diese bei SQL auch nicht.

Ich persönliche nutze die Automatische Verknüpfung für die Rechnungsadresse, da ich diese meistens benötige und dafür Funktoinen wie Relate Many Selection und ähnliches mir das Leben leichter machen. Ich mache öfters Statistiken anhand der Rechnungsadresse (insbesondere Feld Land) also Lieferadresse.

Wenn man die Lieferadresse anzeigen möchte, könnte man heute diese entweder vorher ermitteln und in Variablen packen oder alternativ per Begin/End SQL, da dies die aktuelle Auswahl nicht verändert. Die Variablen dann anzeigen.
Macht man das in der Formular Methode, kann man dynamische Variablen nutzen, benötigt so keine globalen (und kann das gleiche Formular mehrfach ohne Konflikte nutzen).
Macht man das schon vorher, kann man jetzt auch ohne globale Variablen arbeiten, dafür den neuen “Form” Befehl verwenden: https://blog.4d.com/passing-data-back-and-forth-between-forms/

Adressen haben nichts mit Kunden zu tun, ein Kunde verwendet nur 1…N Adressen. Also 2 Tabellen.
Wird die Adresse auch von anderen Kunden benutzt, ist das sogar M…N, also Zwischentabelle und in dieser außerdem die Art der Adressverwendung.

Die Zwischentabelle ist idR übernormalisiert. Also in der Adresse auch ein Verwendungsfeld: , , , …

Fürs Wochenend-Studiumhttp://docs.oasis-open.org/ciq/v3.0/specs/ciq-specs-v3.html OASIS CIQ (xNAL)>. Danach dann ins Praktikable eindampfen.

Es geht auch ganz ohne Relationen:

Kunde
Kundennummer
Vorname
Nachname
Rechnung-Straße
Rechnung-PLZ
Rechnung-Ort
Rechnung-Land
Liefer-Straße
Liefer-PLZ
Liefer-Ort
Liefer-Land

Ja, bei SQL gibt es keine automatischen Verknüpfungen. Mein Ziel ist es mir das Leben mit 4D im Vergleich zu SQL einfacher zu machen :-). Bei SQL muss ich (fast) immer mit Variablen hantieren.
Dynamische Variablen sind interessant, aber wenn es so funktioniert, wie ich mir das vorstelle, brauche ich mit bei der Anzeige eines Kunden gar keine. Ich mache ein relate many([Kunde]), sortiere ggfs. nach Adressart und habe alle Adressen des Kunden. Mit zwei Buttons (vor und zurück) kann ich dann durch die Adressen des Kunden navigieren.

Danke für Ihre Sichtweise.

Da war mein erster Post wohl nicht ganz eindeutig. Die erste Zeile mit den Feldnamen ist immer der Tabellenname. Ich habe in meinen Beispielen also die Adressen nicht in der Kundentabelle.

Alles in einer Tabelle ist auf den ersten Blick die schnelle einfache Lösung, bringt aber später vermutlich viele Probleme, z.B.:

  • es ist umständlich festzustellen, welcher Kunde welche Adressart hat
  • wenn ich eine Kundenadresse sauber anzeigen will muss ich vermutlich viel am (Unter-)Formular basteln.

Es widerspricht einfach dem Relationalen Datenbankmodell und ist damit ein Schwimmen gegen den Strom.

Trotzdem Danke für die Antwort. :slight_smile: