rechnung |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1.1 Weltausschnitt |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Mit diesem Beispiel wird der Aufbau einer Datenbank für den Zweck der Rechnungsstellung gezeigt. Ausgangspunkt ist dabei die in der folgenden Abbildung angegebene Rechnung (ursprünglich eine reale, die für diesen Zweck aber anonymisiert wurde), also ein Geschäftsobjekt (business object), was in der Datenmodellierung durchaus oft der Fall ist. Es gelten – neben der üblichen kaufmännischen Semantik von Rechnungen - die folgenden Bedingungen und semantischen Festlegungen: |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Die Abkürzungen bei Position 1 bedeuten:
|
|
|
|
|
| Grundsätzlich und auch bei dieser Aufgabe ist zu beobachten, dass Modellierer versuchen, auch dynamische Aspekte (Verarbeitung der Daten) mit ins Datenmodell zu integrieren. Insbesondere solche Modellierer, die gerade die Vorlesung Systemanalyse hören oder gehört haben. Dies ist falsch und geht auch nicht. Deshalb folgender Hinweis: Nur Statik, keine Dynamik! Datenbanken liefern „nur“ das informationelle Gerüst für die „auf ihr“ ablaufenden Geschäftsprozesse. Es müssen also nicht Vorgänge, Handlungen, usw. (dynamische Aspekte des Weltausschnitts) modelliert werden, dies leistet die Systemanalyse, sondern „Strukturen“ (statische Aspekte).
| Diese Aufgabe wird mit unterschiedlichem Komplexitätsgrad in drei Stufen gelöst:
| 1.2 Stufe 1
| Aufgabe Stufe 1 – Grundstruktur:
|
|
| Lösung Stufe 1
| Für die Stufe 1 sammeln wir zuerst die Attribute ein und bestimmen die Determinanten und funktionalen Abhängigkeiten (ein bei Geschäftsobjekten sinnvolles Vorgehen):
|
|
| Der Mehrwertsteuersatz wird im Programm hinterlegt, der Mehrwertsteuerbetrag wird dann daraus und aus der Rechnungssumme berechnet.
| 1.2.1 Objekte und Beziehungen finden
| Was können wir nun, auch unter Berücksichtigung der ja immer vorliegenden Objekt-/Beziehungsstruktur von den Attributen ableiten?
| Problemlos zu erkennen sind die Kunden, als Objekte, Objektklasse und als Relation. Identifiziert werden sie durch die KNr. Diese ist hier also erstmals Determinante. Voll funktional abhängig von dieser sind die folgenden Attribute:
|
|
| Für die Adressangaben gilt dies nur, weil wir uns in Stufe 1 mit der Rechnungsanschrift begnügen. Damit ergibt sich die erste Relation:
| KUNDEN (#KNr, Name, Vorname, PLZ, Ort, Straße, Telefon)
| Diese ist bereits in 5NF. Ähnlich einfach ist das Erkennen der Rechnung als Modellelement. Bei genauerem Hinsehen erkennt man aber, dass es eine Unterscheidung geben muss zwischen Rechnungskopf (identifiziert durch die RechnNr) und den Rechnungspositionen, denn es gibt pro Rechnung mehrere Positionen. Folgende funktionalen Abhängigkeiten bestehen von der Determinante RechnNr:
|
|
| Damit ergibt sich eine Relation Rechnungsköpfe:
| RECHNUNGSKÖPFE (#RechnNr, RechnDatum, Verkäufer, Tour, KVDAT)
| Auch diese ist in 5NF. Die letzten leicht erkennbaren Objekte sind die Artikel. Auch sie werden identifiziert (ArtikelNr) und beschrieben. ArtikelNr ist also Determinante mit folgenden funktional abhängigen Attributen:
|
|
| Dies führt zu folgender Relation:
| ARTIKEL (#ArtikelNr, Beschreibung, Preis, Stand)
| Auch hier gibt es keinen Verstoß gegen die 5NF.
| 1.2.2 Rechnungspositionen – kaufmännische Semantik
| Bleiben noch die übrigen Attribute. Sie bewegen sich alle um die Rechnungspositionen herum. Ihre Verarbeitung macht bei ungeübten Modellierern regelmäßig Schwierigkeiten. Hier muss erkannt werden, dass das zu modellierende Realweltphänomen (der Informationsträger) das kaufmännische Konstrukt der Rechnungspositionen ist. Wird dies erkannt, ist der Rest einfach. Rechnungspositionen werden durch eine Attributskombination identifiziert: (RechnNr, PosNr). Folgende funktionalen Abhängigkeiten bestehen:
|
|
| Damit ergibt sich folgende Relation, ebenfalls in 5NF:
| RECHNUNGSPOSITIONEN (#(RechnNr, PosNr), ArtikelNr, Anzahl)
| 1.2.3 Alternativer Weg
| Oftmals wird in Übungen obige Relation über den Zusammenhang von Rechnung und Artikeln erkannt. Da es typischerweise pro Rechnung mehrere Artikel gibt und die Artikel auch auf mehreren Rechnungen auftauchen (ein bestimmtes Sofa, das hundert mal verkauft wurde) wird dabei dann zuerst eine Verbindungsrelation mit dem Schlüssel (RechnNr, ArtikelNr) eingerichtet. Wenn dann die Modellierer die Bedeutung der Rechnungspositionen erkennen, wird dieser Ansatz schnell zur obigen Lösung weiterentwickelt.
| Zurück zur Aufgabe. Wir haben nun vier Relationen erkannt, die wesentliche Merkmale der Rechnung beschreiben. Zu prüfen sind aber noch die Schlüssel und Fremdschlüssel, d.h. die relationalen Verknüpfungen:
|
|
| RECHNUNGSKÖPFE (#RechnNr, RechnDatum, Verkäufer, Tour, KVDAT, KNr)
|
|
| RECHNUNGSPOSITIONEN (#(RechnNr, PosNr), ArtikelNr, Anzahl)
|
| RECHNUNGSPOSITIONEN (#(RechnNr, PosNr), ArtikelNr, Anzahl)
| 1.2.4 Idealstruktur
| Die funktionalen Abhängigkeiten in allen Relationen sind bereits geklärt, da ja die Attribute so zu Relationen gruppiert wurden, dass jeweils ein Schlüssel und die von ihm voll funktional abhängigen Attribute zusammen kamen. Da keine überlappenden Schlüssel auftreten, ist die BCNF auch gesichert. Da darüber hinaus die in der vierten und fünften Normalform angesprochenen Probleme nicht auftreten, befinden sich alle Relationen in 5NF.
| Die folgende Abbildung zeigt die grafische Darstellung des Datenmodells.
|
|
|
| Hier noch die textlichen Notationen – im Zusammenhang:
| KUNDEN (#KNr, Name, Vorname, PLZ, Ort, Straße, Telefon)
| RECHNUNGSPOSITIONEN (#(RechnNr, PosNr), ArtikelNr, Anzahl)
| RECHNUNGSKÖPFE (#RechnNr, RechnDatum, Verkäufer, Tour, KVDAT, KNr)
| ARTIKEL (#ArtikelNr, Beschreibung, Preis, Stand)
| 1.3 Stufe 2 - Adressen
| In Stufe 2 wird zwischen Liefer- und Rechnungsadresse unterschieden. Ein Kunde kann beliebig viele Adressen haben. Jede kann bei einer Rechnung Liefer- oder Rechnungsadresse sein.
| Die alte Relation Kunden fällt dann weg, da es mehr als eine Adresse pro Kunde gibt. Sie wird in die Relationen Kunden_Stufe2 und Adressen aufgeteilt. Einmalig pro Kunde ist weiterhin KNr, Name, Vorname, so dass daraus die neue Kundenrelation entsteht:
| Kunden_Stufe2 (#KNr, Name, Vorname
| Adressen werden zu einer eigenen Relation. Wir ergänzen einen Schlüssel Adressnummer (AdressNr), denn einen Schlüssel braucht jede Relation:
| Adressen (#AdressNr, PLZ, Ort, Straße, Telefon)
| Es fehlt noch die Verknüpfung. Die Beziehung ist n:m, denn ein Kunde hat ja mehrere Adressen und unter einer Adresse wohnen u.U. mehrere Kunden (Mehrfamilienhäuser). Wir benötigen also eine Verbindungsrelation:
| Kunden-Adressen_Stufe2 (#(KNr, AdressNr))
| Beide Attribute wurden gleich als Fremdschlüssel gekennzeichnet. Damit ist im Datenmodell die Beziehung zwischen Kunden und Adressen festgehalten. Bleibt noch zu klären, wie beim Rechnungskopf festgehalten wird, welche Adresse Liefer- und welche Rechnungsadresse ist. Bisher war einfach die KNr als Fremdschlüssel hinterlegt.
| Folgende Vorschläge werden an dieser Stelle in Modellierungsprojekten gemacht:
| Vorschlag 1: Zwei Attributskombinationen (KNr, LieferadressNr) und (KNr, RechnungsadressNr) in die Relation Rechnungsköpfe. Beide wären dann Fremdschlüssel. Da sie die KNr gemeinsam haben, könnte auch ein überlappender Fremdschlüssel gewählt werden:
| Rechnungsköpfe (#RechnNr, RechnDatum, Verkäufer, Tour, KVDAT, (LieferadressNr, (KNr), RechnungsadressNr)
| Dieser ist nicht sinnvoll, da dann in allen Fällen, in denen nur eine Adresse vorliegt, semantisch bedingte Leereinträge vorkommen [Anmerkung] .
| Vorschlag 2: Zwei Verbindungsrelationen zwischen Rechnungsköpfe und Kunden. Eine für die Erfassung der Lieferadressen, eine für die Erfassung der Rechnungsadressen:
| LIEFERADRESSEN (#(RechnNr, KNr))
| RECHNUNGSADRESSEN (#(RechnNr, KNr))
| Auch diese Lösung ist nicht sinnvoll, da hier bei der Erstellung der konkreten Rechnung zwei Relationen für die Feststellung der beiden Anschriften abgefragt werden müssen. Außerdem wird die Information, dass eine bestimmte Rechnung Liefer- oder Rechnungsanschrift ist, in die Meta-Ebene, die Relationenbezeichnung verlegt.
| Vorschlag 3: Eine einzige Verbindungsrelation, die gleichzeitig die Liefer- und Rechnungsanschrift festhält:
| LR-ADRESSEN (#(RechnNr, (KNr, AdressNr)), Adresstyp)
| Diese Lösung ist sinnvoll, da eben in vielen Rechnungen nur eine einzige Anschrift angegeben ist (die dann gleichzeitig Liefer- und Rechnungsadresse ist), manchmal aber zwei. KNr und AdressNr sind zusammen(!) Fremdschlüssel. Zusammen- Das Attribut Adresstyp hat die Ausprägungen L(ieferadresse) und R(echnungsadresse). R gibt es immer, L nur, falls es eine extra Lieferanschrift gibt. Ansonsten ist die Rechnungsanschrift gleich der Lieferanschrift. Die folgende Tabelle zeigt zur Verdeutlichung einige Beispielsdaten:
| LR-Adressen
|
|
|
| RECHNUNGSPOSITIONEN (#(RechnNr, PosNr), ArtikelNr, Anzahl)
| RECHNUNGSKÖPFE (#RechnNr, RechnDatum, Verkäufer, Tour, KVDAT)
| ARTIKEL (#ArtikelNr, Beschreibung, Preis, Stand)
| neu: KUNDEN_STUFE2 (#KNr, Name, Vorname)
| neu: ADRESSEN (#AdressNr, PLZ, Ort, Straße, Telefon)
| neu: KUNDEN-ADRESSEN_STUFE2 (#(KNr, AdressNr))
| neu: LR-ADRESSEN (#(RechnNr, (KNr, AdressNr)), Adresstyp)
| 1.4 Zeitliche Dimension
| Wir wählen hier die Methode „ Duplizieren zum Rechnungszeitpunkt“ (vgl. Kapitel 17 im Text RM).
| Dabei werden bei den Transaktionsdaten (hier die der Rechnungspositionen) die Daten dupliziert, die zum Zeitpunkt der Rechnungsstellung die richtigen sind. So wird aus dem Attribut ArtikelNr das Attribut RZ-ArtikelNr, d.h. Artikelnummer zum Zeitpunkt der Rechnungsstellung (RZ = Rechnungszeitpunkt). Insgesamt ergibt sich:
| RECHNUNGSPOSITIONEN (#(RechnNr, PosNr), RZ-ArtikelNr, RZ-Beschreibung, RZ-Preis, RZ-Stand, Anzahl)
| Die Relation Artikel bleibt unverändert:
| ARTIKEL (#ArtikelNr, Beschreibung, Preis, Stand)
| Diese Lösung hat zur Folge, dass bei der Rechnungsstellung immer eine Kopie der Stammdaten erstellt wird, auch wenn sich diese vielleicht nie verändern. Insgesamt ergibt sich bei dieser Lösung folgendes Datenmodell:
| RECHNUNGSPOSITIONEN (#(RechnNr, PosNr), RZ-ArtikelNr, RZ-Beschreibung, RZ-Preis, RZ-Stand, Anzahl).
| ARTIKEL (#ArtikelNr, Beschreibung, Preis, Stand)
| Rechnungsköpfe (#RechnNr, RechnDatum, Verkäufer, Tour, KVDAT)
| KUNDEN _Stufe2 (#KNr, Name, Vorname)
| ADRESSEN (#AdressNr, PLZ, Ort, Straße, Telefon)
| KUNDEN-ADRESSEN_Stufe2 (#(KNr, AdressNr))
| LR-ADRESSEN (#(RechnNr, (KNr, AdressNr)), Adresstyp, RZ-Name, RZ-Vorname, RZ-PLZ, RZ-Ort, RZ-Straße, RZ-Telefon)
| Dupliziert wird in die Relationen Rechnungspositionen und LR-Adressen. In diesen spiegelt sich die Transaktion wider, hier werden die zum Zeitpunkt der Transaktion aktuellen Attributsausprägungen hinterlegt.
| | | | | | | | | | | | | | | | | | | | | |