DBTraining - Datenbanktraining zu RM, ERM, SQL und OOM. 121 einführende Aufgaben und Lösungen (Entwurf 1/2024)
| |
Aufgaben und Lösungen zum Training folgender Aspekte rund um Datenbanken: |
|
- Modellierung relationaler Datenbanken
- Einrichten relationaler Datenbanken mit XAMPP/mySQL
- Abfragen und Arbeiten von Datenbanken mit SQL
- Web-Oberfläche einrichten mit PHP
- Entity Relationship - Modellierung
- Objektorientierte Modellierung nach der UML 2.5
|
|
|
|
Copyright 2024 Josef L. Staud |
|
Autor: Josef L. Staud |
|
Stand: Februar 2024 |
|
Umfang des gedruckten Textes: ca. 300 Seiten |
|
Dieser Text richtet sich an die Teilnehmer meiner Seminare und sonstige Interessenten. Geplanter Erscheinungstermin der Endfassung: 2025 |
|
Aufbereitung für's Web |
|
Diese HTML-Seiten wurden mithilfe eines von mir erstellten Programms erzeugt: WebGenerator2 (Version 2021). Es setzt Texte in HTML-Seiten um und ist noch in der Entwicklung. Die "maschinelle" Erstellung erlaubt es, nach jeder Änderung des Textes diesen unmittelbar neu in HTML-Seiten umzusetzen. Da es nicht möglich ist, nach jeder Neuerstellung alle Seiten zu prüfen, ist es durchaus möglich, dass irgendwo auf einer "abgelegenen" Seite Fehler auftreten. Ich bitte dafür um Verzeihung und um Hinweise (hs@staud.info). |
|
Die Veröffentlichung im Web erfolgt ab 2022 in zwei Versionen: Mit und ohne Frame-Technologien. Zu meinem Bedauern wird die Frame-Technologie inzwischen von den Verantwortlichen als unerwünscht angesehen und es häufen sich die Hinweise, dass bestimmte Browser Frame-basierte Seiten nicht mehr korrekt interpretieren können. Deshalb habe ich eine zweite Version meines Programms WebGenerator erstellt, die ohne Frames realisiert ist. |
|
Urheberrecht |
|
Dieser Text ist urheberrechtlich geschützt. Die dadurch begründeten Rechte, insbesondere die der Übersetzung, des Nachdrucks, des Vortrags, der Entnahme von Abbildungen und Tabellen oder der Vervielfältigung auf anderen Wegen und der Speicherung in Datenverarbeitungsanlagen, bleiben, auch bei nur auszugsweiser Verwertung, vorbehalten. Eine Vervielfältigung dieses Textes oder von Teilen dieses Textes ist auch im Einzelfall nur in den Grenzen der gesetzlichen Bestimmungen des Urheberrechtsgesetzes der Bundesrepublik Deutschland vom 9. September 1965 in der jeweils geltenden Fassung zulässig. Sie ist grundsätzlich vergütungspflichtig. Zuwiderhandlungen unterliegen den Strafbestimmungen des Urheberrechtsgesetzes. |
|
Warenzeichen und Markenschutz |
|
Alle in diesem Text genannten Gebrauchsnamen, Handelsnamen, Marken, Produktnamen, usw. unterliegen warenzeichen-, marken- oder patentrechtlichem Schutz bzw. sind Warenzeichen oder eingetragene Warenzeichen der jeweiligen Inhaber. Die Wiedergabe solcher Namen und Bezeichnungen in diesem Text berechtigt auch ohne besondere Kennzeichnung nicht zu der Annahme, dass solche Namen im Sinne der Gesetzgebung zu Warenzeichen und Markenschutz als frei zu betrachten wären und daher von jedermann benutzt werden dürften. |
|
Didaktisch motivierte Aufgaben |
|
Die hier vorgestellten didaktisch motivierten Modellierungsbeispiele dienen der Ausbildung, dem vertieften Erlernen und Einüben der jeweiligen Theorie und Methode, nichts anderem. |
|
Prof. Dr. Josef L. Staud |
|
|
|
1 Einführung |
|
1.1 Motivation |
|
Methodenwissen erlangt man am besten, indem man die Methode anwendet. Dann entsteht nach einiger Zeit Methodenkompetenz. Dies gilt auch für die verschiedenen Methoden des Datenbankdesigns und des Umgangs mit Datenbanken. |
|
Nach dem Erwerb des notwendigen Theoriewissens sollte diese Phase des Trainierens angestrebt werden. Im Kontext der Programmierung ist dies schon länger klar. Gute Lehrbücher für den Erwerb von Programmierkompetenz enthalten zahlreiche nachvollziehbare Beispiele, von einfach bis komplex. Der Verfasser hat es selbst erlebt. Vor Jahrzehnten beim Lernen von C++ mit dem legendären Buch von Stephen Prata und danach immer wieder beim Erlernen weiterer Programmiersprachen. |
|
Dieser Text will ähnliches für die Datenmodellierung und das Datenbankdesign leisten. Anhand zahlreicher Beispiele soll das Theoriewissen zur Anwendung und zu einer bestimmten Exzellenz geführt werden. Dass außerdem auch einige wichtige Theoriefragen angesprochen (wiederholt) werden, stört dabei sicher nicht. Das Motto ist: |
|
Festigung, Vertiefung und Verbreiterung der Methodenkompetenz (bzgl. Datenbankdesign) durch Anwenden der Methoden. |
|
Sozusagen als Nebeneffekt ergibt sich, dass bei der Durcharbeitung der Aufgaben die verschiedenen Ansätze zur Modellierung von Daten verglichen werden können, was erfahrungsgemäß auch beim Erlernen von Methodenwissen hilft. Wer z.B. erstmal begriffen hat, dass alle diese Modellierungsansätze weitgehend attributgeprägt sind, wird das Attributkonzept nicht mehr so stiefmütterlich behandeln, wie es heute leider an vielen Stellen in der Lehre geschieht. Wer die gängigen Muster in einem Ansatz begriffen hat, tut sich leichter im nächsten. |
Methodenvergleich |
Noch nicht vollständig gelungen ist, die Aufgaben in jedem Bereich nach Schwierigkeitsgrad zu ordnen. Dies soll aber im weiteren Ausbau geschehen. Gerne nehme ich hier Vorschläge und Wünsche entgegen. |
|
1.2 Voraussetzungen |
|
Voraussetzung für die erfolgreiche Arbeit mit dem Text sind Basiskenntnisse der folgenden Systeme und Methoden. |
|
Den größten Anteil hat das relationale Datenbankdesign, die relationale Modellierung. Anwendungsbeispiele aus vielen Anwendungsbereichen, in denen in unterschiedlichen Schwierigkeitsgraden alle Aspekte des relationalen Datenbankdesigns thematisiert werden, sollten einen umfassenden Kompetenzerwerb ermöglichen. |
Relationales Datenbankdesign |
Aber auch das Einrichten der Datenbanken, die Umsetzung relationaler Datenmodelle mittels SQL in konkrete relationale Datenbanken, wird trainiert. Mit mySQL unter XAMPP, einer hervorragenden und - das ist ja auch sehr wichtig - leicht und kostenlos verfügbaren Entwicklungsumgebung. |
mySQL, XAMPP |
Ein Kapitel enthält Aufgaben zu Abfragen und Auswertungen von Datenbanken mit SQL - ungefähr auf dem Niveau nach einer einführenden Lehrveranstaltung. Dabei wird phpMyAdmin unter XAMPP genutzt, eine leistungsstarke Bedienoberfläche für Relationale Datenbanken. |
SQL |
Für den hier letztendlich betrachteten Gesamtweg, . . . |
|
Anforderungen - Datenmodell (Schema) - Datenbank - Web-Benutzeroberfläche |
|
. . . fehlt jetzt nur noch der letzte Schritt, von der Datenbank zu einer Benutzeroberfläche ohne SQL. Dafür wird hier "das Web" genommen, da heutzutage die meisten Benutzeroberflächen für Datenbestände webbasiert sind. Die Methoden der Wahl sind dabei PHP, HTML und JavaScript. Deshalb sind hier in einem Kapitel auch Aufgaben, mit denen das Einrichten einfacher Web-Benutzeroberflächen für Datenbanken geübt wird. |
PHP, HTML |
Einige Aufgaben widmen sich auch wichtigen Aspekten der relationalen Theorie. Vor allem denen, die das Datenbankdesign unterstützen. |
Relationale Theorie |
Die semantische Modellierung gerät schon seit einiger Zeit etwas ins Vergessen, sehr zu unrecht. Sie hat weiterhin Bedeutung und ist deshalb auch hier mit einigen Aufgaben vertreten. Hauptsächlich in ihrer Ausprägung als Entity Relationship-Modellierung. |
Semantische Modellierung |
Ein weiteres Kapitel widmet sich der objektorientierten Modellierung nach der UML 2.5. Dabei geht es um die inhaltlichen und semantischen Aspekte des Anwendungsbereichs, nicht um die Klassenbildung im Rahmen der Programmentwicklung, die ja eher funktionsorientiert sein muss. Ziel ist das, was auch Objektmodell genannt wird. |
Objekt- orientierte Modellierung |
"Verschüttetes Wissen" |
|
Um zu helfen, falls das Wissen um die jeweiligen Methoden etwas in Vergessenheit geraten ist, sind im Anhang drei Kapitel, die hier benötigte wesentliche Aspekte der jeweiligen Methoden für die Wiederholung anbieten: |
|
- Kapitel 10: Etwas relationale Theorie
- Kapitel 11: Etwas HTML
- Kapitel 12: Etwas PHP - Vom Web zur Datenbank
|
|
Ausgangspunkt |
|
In diesem Text wird davon ausgegangen, dass bei der Leserin bzw. beim Leser Kenntnisse bezüglich Datenbankdesign (Datenmodellierung) vorhanden sind. Vor allem zu relationalen Datenbanken. Dazu gehört ein Verständnis von Attributen, Relationen und der elementaren Normalform (1NF). Diesbezügliche Lücken können mit Hilfe von [Staud 2021] beseitigt werden: |
|
Staud, Josef Ludwig: Relationale Datenbanken. Grundlagen, Modellierung, Speicherung, Alternativen (2. Auflage). Hamburg 2021 (tredition) |
|
Lücken bzgl. "inhaltlicher" objektorientierter Modellierung beseitigt [Staud 2019]: |
|
Staud, Josef: Unternehmensmodellierung - Objektorientierte Theorie und Praxis mit UML 2.5. (2. Auflage). Berlin u.a. 2019 (Springer Gabler) |
|
1.3 Attributbasiertheit |
|
Für sehr viele Datenbanken und ihre Methoden gilt: sie sind attributbasiert. D.h. sie beruhen auf Attributen, wie sie von den Eigenschaften der Alltagswelt abgeleitet wurden. Vgl. [Staud 2021, Abschnitt 2.4]. Dies gilt für alle relationalen Datenbanken, aber auch für objektorientierte, genauso wie für die semantische Datenmodellierung. Umso überraschender, dass der Attributsbegriff in Informatikkreisen nur stiefmütterlich behandelt wird. |
|
Bei den Modellierungsaufgaben wird mit einer Beschreibung des Anwendungsbereichs und der Anforderungen begonnen. Dabei liegen dann bereits die Attribute vor. Konzeptionelle Modellierung, der Weg von der Beschreibung des Anwendungsbereichs bis zu den Attributen und Datenmodellen, wird hier nicht betrachtet. |
Aufgaben- gestaltung |
Der Lösungsweg wird jeweils detailliert aufgezeigt. Die Vorgehensweise ist dabei unterschiedlich, um die möglichen unterschiedlichen Wege aufzuzeigen. |
|
Obwohl es vielerorts beim relationalen Datenbankentwurf nicht üblich ist, werden, wie beim objektorientierten Entwurf, Beziehungswertigkeiten angegeben. Sie werden hier Min-/Max-Angaben genannt. "Min/Max" steht für minimalen und maximalen Wert der Teilnahme an der Beziehung. Sie zeigen nicht nur, ob eine Beziehung Pflicht ist oder optional, sondern auch, welchen Umfang die Wertigkeiten haben können. |
Min/Max |
1.4 Bezeichnung der Methodenelemente |
|
Was die zu beschreibenden Elemente in der Datenmodellierung angeht, kann man einen Ausgangspunkt und drei Modellebenen unterscheiden. Der Ausgangspunkt ist der zu modellierende Anwendungsbereich, manchmal auch Weltausschnitt genannt. Die erste Modellebene ist die der Attribute, durch die Objekte und Beziehungen beschrieben werden. Die zweite die Ebene der Basiselemente im jeweiligen Ansatz (Relationen, Entitätstypen, Klassen). Die dritte Ebene ist die des gesamten Datenmodells. Um diesbezüglich im Text die Übersichtlichkeit zu erhöhen wird folgende typographische Festlegung getroffen: |
Überblick durch Typographie |
- Bezeichnungen von Anwendungsbereichen werden etwas vergrößert, in Kapitälchen und in Arial gesetzt: Hochschule, Personalwesen, WebShop. In der Web-Version sind sie zusätzlich in roter Farbe gehalten.
- Bezeichnungen von Datenmodellen und Datenbanken sind in normaler Größe, fett und in Arial gesetzt: Vertrieb, Zoo, WebShop, Datenbanksysteme (Markt für Datenbanksysteme). In der Web-Version zusätzlich in rot.
- Bezeichnungen von Relationen, Entitätstypen und Klassen (Basiselemente) sind etwas verkleinert und in Arial gesetzt: Angestellte, Abteilungen, Projekte. In der Web-Version zusätzlich in rot.
- Bezeichnungen von Attributen sind etwas verkleinert, fett und in Arial gesetzt: Gehalt, Name, Datum. Bei zusammengesetzten Benennungen wird der nachfolgende Begriff wieder groß begonnen: PersNr (Personalnummer), BezProj (Bezeichnung Projekt).
- Für die kombinierte Angabe von Attributen und Relationen: Relationenbezeichnung.Attributsbezeichnung, also z.B. Angestellte.PersNr für das Attribut PersNr der Relation Angestellte.
- Ausprägungen von Attributen werden in normaler Größe und in Courier gesetzt, z.B. Müller für das Attribut Name.
|
|
Für die Basiselemente (Relationen, Entitätstypen, Klassen) wird bei der Bezeichnung immer die Mehrzahl gewählt, da ja in der Regel mehrere Objekte bzw. Beziehungen erfasst sind. |
|
|
|
2 RelDB - Von der Anforderung zum Datenmodell |
|
Für eine umfassende Einführung in die relationale Modellierung vgl. [Staud 2021]: |
|
Staud, Josef Ludwig: Relationale Datenbanken. Grundlagen, Modellierung, Speicherung, Alternativen (2. Auflage). Hamburg 2021 (tredition) |
|
Auszüge finden sich auf http://www.staud.info/rm1/rm_t_1.htm |
|
Erster Schritt des Gesamtwegs: Anforderungen - Datenmodell (Schema) - Datenbank - Web-Benutzeroberfläche |
|
Die Aufgaben dieses Kapitel beziehen sich auf den ersten Schritt des Gesamtwegs, von der Anforderungsbeschreibung zum Datenmodell. |
|
|
|
2.1 Übung 1 |
|
Zu Beginn eines jeden Datenbankprojekts müssen aus der Beschreibung des Anwendungsbereichs und den Anforderungen die relevanten Relationen abgeleitet werden. In dieser Aufgabe geht es um diesen Schritt. Mit im Mittelpunkt sind dabei methodenbedingte Zerlegungen der Relationen. |
|
2.1.1 Anforderungsbeschreibung |
|
Im Rahmen des Datenbankdesigns für einen Sportverein wurden für die Mitglieder folgende Anforderungen formuliert: |
|
Die Mitglieder des Vereins werden durch Name, Vorname (VName), Telefon (Tel), Geburtstag (GebTag), Alter, eine Mitgliedsnummer (MiNr) und die Hauptadresse (PLZ, Ort, Straße) festgehalten. Erfasst wird außerdem der Tag des Eintritts (Eintritt) in den Verein. Bei ausgetretenen Mitgliedern ebenfalls der des Austritts (Austritt). Es kommt leider vor, dass ein Mitglied austritt und später wieder eintritt. Auch dies soll in vollem Umfang dokumentiert werden, d.h. vorherige Mitgliedschaften werden nicht gelöscht. Es entsteht so eine Dokumentation aller Ein- und Austritte eines Vereinsmitglieds. Bei verstorbenen Mitgliedern wird der Todestag (Todestag) vermerkt. |
|
Daraus sind die Relationen abzuleiten. |
|
2.1.2 Lösungsschritte |
|
Die erste Relation liegt nahe: Mitglieder mit dem Schlüssel #MiNr. Welche Attribute können ihr zugeordnet werden? Sicherlich der Name und Vorname (VName), denn diese sind eindeutig für jedes Mitglied: |
|
Mitglieder (#MiNr, Name, Vorname, . . .) |
|
Die Telefonnummer nur, falls sie auch eindeutig ist. Auf Nachfrage erfahren wir, dass die Mitglieder durchaus mehrere Telefoniermöglichkeiten haben, z.B. einen Festnetz- und einen Mobilfunkanschluss. Dies würde in Mitglieder zu Mehrfacheinträgen führen. Deshalb wird dafür eine eigene Relation eingeführt: |
|
Telefone (#(MiNr, Tel)) |
|
MiNr wird zum Fremdschlüssel. |
|
Den Geburtstag, das Alter und die Hauptadresse können wir wiederum der Relation Mitglieder hinzufügen: |
|
Mitglieder (#MiNr, Name, Vorname, GebTag, Alter, PLZ, Ort, Straße, . . .) |
|
Das Alter wird später in der Datenbank aus dem Geburtstag und dem Systemdatum regelmäßig berechnet. Solche abgeleiteten Attribute, wie sie in der ER-Modellierung genannt werden, die mittels anderer bestimmt und in die Datenbank eingetragen werden, kommen in Datenbanken durchaus vor. |
Abgeleitete Atribute |
Gäbe es mehrere Adressen je Mitglied, müsste dafür eine eigene Relation eingerichtet werden. Hier wird aber ausdrücklich auf die Hauptadresse verwiesen. Die Situation, mehrere Adressen im Datenmodell anlegen zu müssen, wird unten in den Aufgaben öfters bewältigt. |
Mehrere Adressen |
Mit den Attributen Tag des Eintritts (Eintritt) und des Austritts (Austritt) kommt die zeitliche Dimension in Form einer Zeitspanne ins Spiel. Das Attribut Eintritt kann problemlos in Mitglieder aufgenommen werden. Austritt dagegen nicht, da diese Attribut ja erst beschrieben werden kann, wenn der Austritt geschieht und solche semantisch bedingten Leereinträge sind in relationalen Datenbeständen nicht erwünscht. Es bleibt also nur eine eigene Relation mit den Austritten. Insgesamt also: |
Zeitliche Dimension |
Mitglieder (#MiNr, Name, Vorname, GebTag, Alter, PLZ, Ort, Straße, Eintritt, . . .) |
|
Austritte (#MiNr, Austritt) |
|
Es soll nicht verschwiegen werden, dass hier sehr oft die pragmatische Lösung gewählt wird, das Ende der Zeitachse zusammen mit dem Eintritt zu platzieren, obwohl damit semantisch bedingte Leereinträge entstehen: |
Pragmatik |
Mitglieder (#MiNr, Name, Vorname, GebTag, Alter, PLZ, Ort, Straße, Eintritt, Austritt, . . .) |
|
Nun findet sich aber in den Anforderungen der Wunsch, auch mehrere Ein- und Austritte eines Mitglieds zu erfassen und zu dokumentieren. Dies verändert den obigen Entwurf. Ein- und Austritte müssen wegen der Möglichkeit der Mehrwertigkeit zusammen mit der Mitgliedsnummer in eine eigene Relation Mitgliedschaften und raus aus Mitglieder: |
|
Mitglieder (#MiNr, Name, Vorname, GebTag, Alter, PLZ, Ort, Straße, . . .) |
|
Mitgliedschaften (#(MiNr, Eintritt), Austritt) |
|
Mitgliedschaften.MiNr wird Fremdschlüssel. Jetzt kann ein Mitglied alle paar Jahre aus- und später wieder einreten. Bei solchen Zerlegungen ist auf die Korrektheit des Schlüssels zu achten. Er muss jedes Tupel eindeutig identifizieren. Dies ist hier oben der Fall. |
|
Am Schluss der Anforderungsbeschreibung werden die verstorbenen Mitglieder erwähnt. Auch sie sollen erfasst werden. Den Todestag in Mitglieder zu erfassen wäre wegen der semantisch bedingten Leereinträge falsch. Bleibt auch hier nur eine eigene Relation zu den verstorbenen Mitgliedern: |
Verstorbene Mitglieder |
MitglVerstorben (#MiNr, Todestag) |
|
Wir gehen davon aus, dass die Daten zu den verstorbenen Mitgliedern in Mitglieder erhalten bleiben. Falls dem nicht so wäre, müsste MitglTot um die entsprechenden Attribute erweitert werden. |
|
2.1.3 Lösung |
|
Damit liegen mit den jeweiligen Endfassungen folgende Relationen vor. |
|
Textliche Fassung |
|
Mitglieder (#MiNr, Name, Vorname, GebTag, Alter, PLZ, Ort, Straße) |
|
Mitgliedschaften (#(MiNr, Eintritt), Austritt) |
|
MitglVerstorben (#MiNr, Todestag) |
|
Telefone (#(MiNr, Tel)) |
|
|
|
Grafische Fassung |
|
|
|
Abbildung 2.1-1: Grafische Lösung zum Anwendungsbereich Sportverein - Ausschnitt Mitglieder |
|
2.2 Übung 2 |
|
Auch in dieser Aufgabe geht es um das Erkennen der Relationen. Dabei steht das Erkennen und Bewältigen des Musters Generalisierung / Spezialisierung (vgl. [Staud 2021, Abschnitt 14.1]) im Mittelpunkt. |
|
2.2.1 Anforderungsbeschreibung |
|
Es liegt bereits eine Relation zu den Mitgliedern des Sportvereins vor: |
|
Mitglieder (#MiNr, Name, Vorname, GebTag, Alter, PLZ, Ort, Straße) |
|
Folgende zusätzlichen Anforderungen wurden formuliert : |
|
Für die Mitglieder wird erfasst, ob es sich um ein passives oder ein aktives Mitglied handelt. Für jedes aktive Mitglied wird dann noch festgehalten, welche Sportart es in welcher Leistungsstufe (LStufe) betreibt. Für die passiven Mitglieder wird erfasst, für welche ehrenamtliche Tätigkeit sie zur Verfügung stehen (BezTät). Dies können mehrere sein. |
|
2.2.2 Lösungsschritte |
|
Mal angenommen, es würde nur gefordert, dass erfasst wird, ob das Mitglied aktiv oder passiv ist. Dann würde ein Attribut AktPass mit den Ausprägungen aktiv oder passiv in Mitglieder reichen: |
|
Mitglieder (#MiNr, Name, Vorname, GebTag, Alter, PLZ, Ort, Straße, AktPass) |
|
Kommen allerdings weitere Attribute für die Untergruppen hinzu, so wie hier |
|
- Sportart und Leistungsstufe (LStufe) für die aktiven Mitglieder,
- BezTät für die passiven Mitglieder,
|
|
ändert sich die Situation. Oftmals werden dann einfach diese Attribute der Relation hinzugefügt: |
|
Mitglieder (#MiNr, Name, Vorname, GebTag, Alter, PLZ, Ort, Straße, AktPass, Sportart, LStufe, BezTät) |
|
Dies ist falsch, denn damit entstehen semantisch bedingte Leereinträge in der späteren Datenbank. Da ein Mitglied entweder aktiv oder passiv ist, gibt es immer Attribute, die keine Einträge erhalten können. Vgl. dazu das Muster Generalisierung / Spezialisierung in [Staud 2021, Abschnitt 14.1]. |
Falsch |
Die korrekte Lösung besteht darin, zwei neue Relationen anzulegen, eine für die aktiven und eine für die passiven Sportler: |
Korrekt |
MitglAktiv (#MiNr, Sportart, LStufe) |
|
MitglPassiv (#MiNr, BezTät) |
|
Das ist nun schon fast richtig. Da in der Anforderung gefordert ist, auch mehrere ehrenamtliche Tätigkeiten zu berücksichtigen, muss MitglPassiv noch angepasst werden: |
|
MitglPassiv (#(MiNr, BezTät)) |
|
Der zusammengesetzte Schlüssel erfüllt die Anforderung, MiNr wird zum Fremdschlüssel. |
|
2.2.3 Lösung |
|
Damit ergibt sich folgende relationale Lösung für die Generalisierung / Spezialisierung. |
|
Textliche Fassung |
|
Mitglieder (#MiNr, Name, Vorname, GebTag, Alter, PLZ, Ort, Straße, AktPass) //Generalisierung : |
|
MitglAktiv (#MiNr, Sportart, LStufe) //Spezialisierung 1: |
|
MitglPassiv (#(MiNr, BezTät)) //Spezialisierung 2: |
|
Mitglieder.AktPass wird von der Methode nicht verlangt, erleichtert aber die späteren Auswertungen und ist daher aus pragmatischen Gründen sinvoll. |
|
Die relationalen Verknüpfungen erfolgen über die MiNr. Zu den Karadinalitäten und Min-/Max-Angaben vgl. die Abbildung. |
|
Grafische Fassung |
|
|
|
Abbildung 2.2-1: Grafische Lösung zum Anwendungsbereich Sportverein - Ausschnitt aktiv/passiv |
|
2.3 Übung 3 |
|
Auch hier geht es um die Klärung der Relationen in einer Anforderungsbeschreibung und um deren Einbindung in das übrige Datenmodell. |
|
2.3.1 Anforderungsbeschreibung |
|
Es liegt bereits aus den obigen zwei Aufgaben ein Datenmodell vor, das ergänzt werden soll: |
|
Mitglieder (#MiNr, Name, Vorname, GebTag, Alter, PLZ, Ort, Straße, AktPass) |
|
MitglAktiv (#MiNr, Sportart, LStufe) |
|
MitglPassiv (#(MiNr, BezTät)) |
|
Mitgliedschaften (#(MiNr, Eintritt), Austritt) |
|
MitglVerstorben (#MiNr, Todestag) |
|
Telefone (#(MiNr, Tel)) |
|
Nun soll dieses Datenmodell um (Sport-)Abteilungen und Mannschaften ergänzt werden. Hier die diesbezüglichen Anforderungen: |
|
Der Sportverein ist in Abteilungen (AbtNr, AbtBez) gegliedert (Handball, Fußball, Volleyball, usw.). |
|
Jede Abteilung hat einen Leiter, dessen Mitgliedsnummer hier erfasst werden soll (AbtLeiter). Dieser zählt als aktives Mitglied. |
|
Eine Abteilung kann mehrere Mannschaften haben. Natürlich gehört eine Mannschaft zu genau einer Abteilung. |
|
Von jeder Mannschaft (MaNr, MaBez) werden mit Hilfe der Mitgliedsnummer die Spieler und der Kapitän (KapNr) festgehalten sowie die Liga, in der sie spielt (Bundesliga, usw.). |
|
Jede Mannschaft hat einen (einzigen) Trainer (TrNr). Auch dieser wird festgehalten. Er zählt als aktives Mitglied. |
|
2.3.2 Lösungsschritte |
|
Die sicherlich erste Überlegung nach der Analyse der Anforderungen ist, die Mannschaften als Relation anzulegen und dort die Abteilungszugehörigkeit zu vermerken. Dies wäre aber nicht korrekt, da die Abteilungen nicht nur identifiziert (AbtNr, AbtBez), sondern auch beschrieben werden (AbtLeiter). Deshalb wird für sie eine eigene Relation angelegt: |
|
Abteilungen (#AbtNr, #AbtBez, AbtLeiter) |
|
Da ein Abteilungsleiter aktives Mitglied ist, wird das Attribut Abteilungen.AbtLeiter zum Fremdschlüssel bzgl. der Relation MitglAktiv: |
|
Abteilungen (#AbtNr, #AbtBez, AbtLeiter) |
|
MitglAktiv (#MiNr, Sportart, LStufe) |
|
Anschließend werden in den Anforderungen die Mannschaften angesprochen. Da sie identifiziert (MaNr) und weiter beschrieben werden durch die Mitgliedsnummern des Kapitäns (KapNr), des Trainers (TrNr) und durch die Liga, in der sie spielen, wird auch für sie eine Relation angelegt: |
Mannschaften |
Mannschaften (#MaNr, MaBez, Liga, KapNr, TrNr, . . .) |
|
In den Anforderungen wurde auch das Verhältnis Abteilungen/Mannschaften beschrieben. Diese 1 :n-Beziehung kann dadurch modelliert werden, dass die Mannschaften die AbtNr als Fremdschlüssel erhalten : |
|
Mannschaften (#MaNr, #MaBez, Liga, KapNr, TrNr, AbtNr, . . .) |
|
Mehrere Schlüssel können Relationen durchaus haben. Sie werden dann Primärschlüssel und Sekundärschlüssel genannt. Im obigen Beispiel könnte die MaNr als Verknüpfungsattribut dienen und MaBez als identifizierend beschreibendes. |
Mehrere Schlüssel |
Obiger Relation fehlt allerdings noch etwas wichtiges. KapNr und TrNr sind einfach nur Nummern, erst durch die Verknüpfung mit den aktiven Mitgliedern (MitglAktiv) sind diesen Nummern die weiteren Informationen zugeordnet. Deshalb werden KapNr und TrNr hier ebenfalls zu Fremdschlüsseln : |
Kapitän, Trainer |
Mannschaften (#MaNr, MaBez, Liga, KapNr, TrNr, AbtNr) |
|
MitglAktiv (#MiNr, Sportart, LStufe) |
|
Folgende Verknüpfungen liegen bzgl. der Mannschaften damit vor : |
|
- Mannschaften.KapNr mit MitglAktiv.MiNr
- Mannschaften.TrNr mit MitglAktiv.MiNr
- Mannschaften.AbtNr mit Abteilungen.AbtNr
|
|
Bleiben noch die Spieler. Natürlich soll festgehalten werden, welche Spieler in welcher Mannschaft spielen. Wir können sicherlich davon ausgehen, dass Spieler datenbanktechnisch aktive Mitglieder sind. Würde ein aktives Mitglied nur in einer Mannschaft spielen, könnten wir die Mannschaft in MitglAktiv vermerken. Auf Nachfrage erfahren wir aber, dass ein aktives Mitglied durchaus in mehreren Mannschaften spielen kann. Das verändert das Modellfragment. |
Spieler |
Jetzt liegt eine n:m-Beziehung zwischen den beiden Relationen Mannschaften und MitglAktiv vor. Dies erfordert eine Verbindungsrelation, die AM-MA (aktive Mitglieder - Mannschaften) genannt werden soll: |
Verbindungsrelation |
AM-MA (#(MaNr, MiNr)) |
|
Die Kardinalität ist n:m, die Min-/Max-Angaben sind - von den aktiven Mitgliedern zu den Mannschaften 0,n : 0,m. |
|
Wir gehen also davon aus, dass es auch aktive Mitglieder gibt, die nicht in einer Mannschaft sind und dass wir eine Mannschaft erst in der Datenbank aufnehmen, wenn wir zumindest ein Mitglied (z.B. die Kapitänin) angeben können. |
|
2.3.3 Lösung |
|
Insgesamt liegen für dieses Fragment zum Datenmodell Sportverein damit folgende Relationen vor. |
|
Textliche Notation |
|
Abteilungen (#AbtNr, #AbtBez, AbtLeiter) |
|
MitglAktiv (#MiNr, Sportart, LStufe) |
|
Mannschaften (#MaNr, #MaBez, Liga, KapNr, TrNr, AbtNr) //Mehrere Schlüssel |
|
AM-MA (#(MaNr, MiNr)) |
|
|
|
Grafische Fassung |
|
|
|
Abbildung 2.3-1: Anwendungsbereich Sportverein - Fragment Mannschaften/Abteilungen |
|
2.4 Übung 4 |
|
Zwei Modellierungsaspekte werden hier betrachtet: |
|
- Die Modellierung von Vorgängen, von Ereignissen mit zeitlicher Dimension.
- Wiederum gilt, dass die neuen Anforderungen in ein bestehendes Datenmodell eingearbeitet werden sollen.
|
|
2.4.1 Anforderungsbeschreibung |
|
Aus den obigen Aufgaben liegt ein Datenmodell zu einem Sportverein vor, das ergänzt werden soll: |
|
Abteilungen (#AbtNr, #AbtBez, AbtLeiter) |
|
AM-MA (#(MaNr, MiNr)) |
|
Mannschaften (#MaNr, #MaBez, Liga, KapNr, TrNr, AbtNr) |
|
MitglAktiv (#MiNr, Sportart, LStufe) |
|
Mitglieder (#MiNr, Name, Vorname, GebTag, Alter, PLZ, Ort, Straße, AktPass) |
|
Mitgliedschaften (#(MiNr, Eintritt), Austritt) |
|
MitglPassiv (#(MiNr, BezTät)) |
|
MitglVerstorben (#MiNr, Todestag) |
|
Telefone (#(MiNr, Tel)) |
|
Es wurde beschlossen, auch die Begegnungen, an denen Mannschaften des Vereins teilnehmen, in der Datenbank zu erfassen. Hier die Anforderungen: |
Begegnungen |
Die Begegnungen von Mannschaften des Vereins sollen mit Datum (Tag), Spielbeginn (Beginn), gegnerischer Mannschaft (Gegner) und Ergebnis festgehalten werden. Falls im Rahmen eines Turniers zwei Mannschaften des Vereins gegeneinander spielen, wird nur ein Eintrag vorgenommen und eine der beiden Mannschaften als "gegnerische" Mannschaft eingetragen. Für diese Datenbank wird angenommen, dass eine Mannschaft mehrere Spiele an einem Tag haben kann (Turnier!). |
|
2.4.2 Lösungsschritte |
|
Die Anforderungen machen deutlich, dass die Begegnungen nicht in einer der schon bestehenden Relationen erfasst werden können. Sie werden identifiziert durch die Attribute (MaNr, Gegner, Tag, Beginn). Ein solcher Schlüssel mit zugehöriger Relation liegt bisher nicht vor, also ist eine weitere Relation nötig, die Begegnungen genannt werden soll: |
|
Begegnungen (#(MaNr, Gegner, Tag, Beginn)). |
|
Beginn ist im Schlüssel für den Fall dabei, dass tatsächlich zwei Manschaften an einem Tag zwei mal gegeneinander spielen, z.B. bei einem Vereinsturnier. |
|
Es geht nur um Begegnungen des Vereins, nicht z.B. um die einer ganzen Liga zwischen allen Mannschaften. Deshalb ist die in MaNr angesprochene Mannschaft immer die des Vereins. |
|
Dies erlaubt und verlangt die Verknüpfung von Begegnungen mit dem vorliegenden Datenmodell über die Relation Mannschaften. Begegnungen.MaNr wird zum Fremdschlüssel und dient damit der Verknüpfung mit Mannschaften.MaNr. |
|
Begegnungen (#(MaNr, Gegner, Tag, Beginn)). |
|
Mannschaften (#MaNr, #MaBez, Liga, KapNr, TrNr, AbtNr) |
|
Nun fehlt nur noch, das Ergebnis mit in die Begegnungen aufzunehmen : |
|
Begegnungen (#(MaNr, Gegner, Tag, Beginn), Ergebnis). |
|
So weit so gut. Bei der Kontrolle des Ergebnisses sollte man allerdings bemerken, dass der Schlüssel überausgestattet ist. Dies kommt von dem erfassten Zeitpunkt der Begegnung. Zeitpunkte sind alleine schon sehr identifizierend. Liegen sie vor, gilt es nur noch zu bedenken, welches zusätzliche Attribut zum Schlüsselcharakter führt. Hier ist es so, dass eine Mannschaft zu einem Zeitpunkt nur ein Spiel gestalten kann. Also genügt als Schlüssel #(MaNr, Tag, Beginn) und der Gegner wird zum deskriptiven Attribut ohne Schlüsselcharakter : |
Zeitachse, Zeitpunkte |
Begegnungen (#(MaNr, Tag, Beginn), Gegner, Ergebnis). //final |
|
2.4.3 Lösung |
|
Textliche Fassung |
|
Begegnungen (#(MaNr, Tag, Beginn), Gegner, Ergebnis). |
|
Mannschaften (#MaNr, #MaBez, Liga, KapNr, TrNr, AbtNr) |
|
Die Beziehung Begegnungen zu Mannschaften stellt eine Komposition dar. Wenn eine Mannschaft aus der Datenbank gelöscht wird, müssen (datenbanktechnisch) auch ihre Begegnungen verschwinden, da unvollständige Schlüssel nicht zulässig sind. |
Muster Komposition |
Grafische Fassung |
|
|
|
Abbildung 2.4-1: Anwendungsbereich Sportverein - Fragment Mannschaften/Begegnungen |
|
Alternative |
|
Bei solchen zusammengesetzten Schlüsseln, vor allem, wenn sie noch umfangreicher sind, wird oft ein künstlich generierter Schlüssel gewählt, der das jeweilige Geschehen eindeutig beschreibt. Hier wäre z.B. eine Zeichenkette, bestehend aus Datum, Beginn, Mannschaftsnummer, Kurzbezeichnung der gegnerischen Mannschaft, denkbar. Also z.B. |
Pragmatik |
20230505M001BayMü |
|
. . . für eine Begegnung am 5.5.2023 zwischen unserer Mannschaft M001 und Bayern München. |
|
Für die Relation ergäbe sich dann: |
|
Begegnungen (#BegebungID, MaNr, Tag, Beginn, Gegner, Ergebnis) |
|
2.5 Sportverein |
|
Einzelne Fragmente dieser Aufgabe dienten oben in den Basisübungen 1 - 4 zur Wiederholung elementarer Modellierungstechniken. Hier nun die integrierte Fassung. |
|
2.5.1 Anforderungsbeschreibung |
|
Ein Sportverein beschließt, seine Aktivitäten (Mitgliederverwaltung, Sportveranstaltungen, usw.) in Zukunft computergestützt abzuwickeln. Dazu soll eine Datenbank aufgebaut werden, für die folgende Festlegungen getroffen werden: |
|
- Die Mitglieder des Vereins werden durch Name, Vorname (VName), Telefon (Tel), Geburtstag (GebTag), eine Mitgliedsnummer (MiNr) und die Hauptadresse (PLZ, Ort, Straße) festgehalten. Erfasst wird außerdem der Tag des Eintritts (Eintritt) in den Verein. Bei ausgetretenen Mitgliedern ebenfalls der des Austritts (Austritt). Es kommt auch vor, dass ein Mitglied austritt und später wieder eintritt. Auch dies soll in vollem Umfang dokumentiert werden, d.h. vorherige Mitgliedschaften werden nicht gelöscht. Es entsteht so eine Dokumentation aller Ein- und Austritte eines Vereinsmitglieds. Bei verstorbenen Mitgliedern wird der Todestag (Todestag) vermerkt.
- Für die Mitglieder wird erfasst, ob sie passiv oder aktiv sind. Für jedes aktive Mitglied wird dann noch festgehalten, welche Sportart es in welcher Leistungsstufe (LStufe) betreibt. Dies können mehrere sein. Für die passiven Mitglieder wird erfasst, für welche ehrenamtliche Tätigkeit sie zur Verfügung stehen (BezTät). Auch dies können mehrere sein.
- Der Sportverein ist in Abteilungen (AbtNr, AbtBez) gegliedert (Handball, Fußball, Volleyball, usw.).
- Jede Abteilung hat einen Leiter (AbtLeiter). Dieser zählt als aktives Mitglied.
- Eine Abteilung kann mehrere Mannschaften haben. Natürlich gehört eine Mannschaft zu genau einer Abteilung.
- Von jeder Mannschaft (MaNr, MaBez) werden mit Hilfe der Mitgliedsnummer die Spieler und der Kapitän (KapNr) festgehalten sowie die Liga, in der sie spielt (Bundesliga, usw.).
- Jede Mannschaft hat einen (einzigen) Trainer (TrNr). Auch dieser wird festgehalten. Er zählt als aktives Mitglied.
- Die Begegnungen von Mannschaften des Vereins sollen mit Datum (Tag), Spielbeginn (Beginn), gegnerischer Mannschaft (Gegner) und Ergebnis festgehalten werden. Falls im Rahmen eines Turniers zwei Mannschaften des Vereins gegeneinander spielen, wird nur ein Eintrag vorgenommen und eine der beiden Mannschaften als "gegnerische" Mannschaft eingetragen. Für diese Datenbank wird angenommen, dass eine Mannschaft mehrere Spiele an einem Tag haben kann (Turnier!).
2.5.2 Lösungsschritte |
|
Wie sehen nun die konkreten Modellierungsschritte aus? Sinnvoll ist es, zuerst die Objekte und Objektklassen und die zugehörigen Relationen zu suchen. |
Erste Schritte |
Beginnen wir mit den Mitgliedern des Vereins. Diese erkennt man modellierungstechnisch daran, dass es sich erstens um Objekte im allgemeinen Sinn handelt und dass zweitens diese Objekte durch Attribute beschrieben werden. Zweiteres ist von zentraler Bedeutung, denn sonst kann es sich auch um ein Attribut handeln, das andere Objekte beschreibt. Es entsteht also eine Relation Mitglieder. Nehmen wir die in der Anforderung genannten deskriptiven Attribute und den Schlüssel erhalten wir folgende Relation: |
Mitglieder |
Mitglieder (#MiNr, Name, VName, Tel, GebTag, PLZ, Ort, Straße) |
|
Alle Mitglieder sind irgendwann in den Verein eingetreten. Insofern könnte man das Attribut Eintritt zur Relation mithinzunehmen. Da es aber Mitglieder gibt, die ausgetreten sind und solche, die vielleicht später wieder eintreten, stellen diese Mitglieder eine Spezialisierung dar. Die ganz korrekte Lösung wäre es, zwei Relationen anzulegen: |
Eintritt, Austritt, verstorbene Mitglieder |
MitglEintritt (#(MiNr, Datum)) |
|
MitglAustritt (#(MiNr, Datum)) |
|
Der Schlüssel ist zusammengesetzt, da dasselbe Mitglied ja jeweils mehrere Einträge haben kann. |
|
Vertretbar ist aber auch die hier gewählte pragmatische Lösung, die Ein- und Austritte zusammen zu verwalten, auch wenn dabei inhaltlich begründete Leereinträge entstehen, denn das Austrittsdatum wird erst beschrieben, wenn das Mitglied tatsächlich austritt: |
|
Mitgliedschaften (#(MiNr, Eintritt), Austritt) |
|
Auch hier ist der Schlüssel wieder zusammengesetzt aus Mitgliedsnummer und Eintrittsdatum, da nur diese Attributkombination differenziert. In beiden Fällen ist es daher möglich, dass ein Mitglied mehrfach ein- und wieder austritt. |
|
Auch die verstorbenen Mitglieder müssen als Spezialisierung erfasst werden, da diese Eigenschaft und den Todestag die anderen Mitgleider nicht teilen: |
Verstorbene Mitglieder |
MitglVerstorben (#MiNr, Todestag) |
|
Dies macht nochmals deutlich, dass ein Attribut genügt, zu um einer spezialisierten Relation zu kommen. |
|
Bleibt noch die Modellierung der Eigenschaft, aktives oder passives Vereinsmitglied zu sein. Ginge es nur um diese Eigenschaft, würde einfach ein Attribut "aktiv/passiv" mit diesen zwei Eigenschaften an die Relation Mitglieder angefügt. Nun ist es hier aber so, dass für die aktiven und passiven Mitglieder jeweils unterschiedliche Attribute festgehalten werden sollen. Deshalb müssen diese Teilgruppen der Mitglieder getrennt als Spezialisierungen erfasst werden: |
Aktiv / Passiv - Muster Gen/Spez |
MitglAktiv (#MiNr, Sportart, LStufe) |
|
MitglPassiv (#(MiNr, BezTät)) |
|
Die passiven Mitglieder erhalten einen zusammengesetzten Schlüssel. Damit kann datenbanktechnisch ein Mitglied auch mehrere ehrenamtliche Tätigkeiten übernehmen. |
|
Oftmals wird in die "oberste" Relation ganz pragmatisch noch ein Attribut eingefügt, das angibt, zu welcher Spezialisierung das Objekt gehört. Hier könnte z.B. ein Attribut Status in Mitglieder angeben, ob es sich um ein aktives, passives oder verstorbenes Mitglied handelt. Dies erleichtert die Abfragen und Auswertungen sehr stark, denn dadurch kann ohne Abfragen der Spezialisierungen gleich die entsprechende Auswahl getroffen werden. |
Pragmatik |
Insgesamt erhalten wir damit für die Mitglieder folgende Relationen: |
|
Mitglieder (#MiNr, Name, VName, Tel, GebTag, PLZ, Ort, Straße, Status) |
|
MitglEinAus (#(MiNr, Eintritt), Austritt) |
|
MitglVerstorben (#MiNr, Todestag) |
|
MitglAktiv (#MiNr, Sportart, LStufe) |
|
MitglPassiv (#(MiNr, BezTät)) |
|
Hier die grafische Darstellung dieses Modellfragments: |
|
|
|
Abbildung 2.5-1: Mitglieder im Datenmodell Sportverein |
|
Hilfestellung zum Lesen der Wertigkeiten |
|
In der relationalen Verknüpfung zwischen Mitglieder und MitglAktiv kommt eine bestimmte MiNr aus Mitglieder maximal einmal vor, eine bestimmte MiNr aus MitglAktiv genau ein Mal. |
|
In semantischen und objektorientierten Modellen ist es möglich auszudrücken, dass alle Objekte der übergeordneten Einheit (Entitätstyp, Superklasse) an den Spezialisierungen teilhaben. Dies kann in relationalen Modellen nicht ausgedrückt werden. Falls es gewünscht wird, muss es auf andere Weise festgehalten und durch das Anwendungsprogramm sichergestellt werden. |
Totale Beteiligung |
Betrachten wir nun die Mannschaften. Sie tauchen mit folgenden Beschreibungen auf: |
Die Mannschaften |
- Jede Abteilung hat mehrere Mannschaften, insofern könnte "Mannschaft" ein Attribut von Abteilung sein.
- Von jeder Mannschaft werden die Bezeichnung (MaBez), die Spieler, der Kapitän, die Liga, der Trainer und ihre Begegnungen festgehalten.
|
|
Letzteres macht die Mannschaften zu Klassen und dann zu Relationen, da sie durch weitere Attribute beschrieben werden. Trainer und Kapitän sind aktive Mitglieder und werden somit durch einen Fremdschlüssel erfasst. Die Abteilungszugehörigkeit wird im nächsten Schritt geklärt. Damit ergibt sich folgender erster Entwurf: |
|
Mannschaften (#MaNr, #MaBez, Liga, TrNr, KapNr) |
|
Schlüssel, Sekundärschlüssel und Fremdschlüssel |
|
MaNr: Mannschaftsnummer |
|
MaBez: Mannschaftsbezeichnung |
|
TrNr: Trainernummer |
|
KapNr : Kapitänsnummer |
|
Die Zuordnung der Spieler schieben wir auf, da eine Mannschaft mehrere Spieler hat. Die Begegnungen werden ebenfalls später geklärt, da sie durch weitere Attribute zu einer eigenständigen Existenz kommen. |
|
Jetzt müssen noch die Abteilungen betrachtet werden. Für sie wurde oben festgehalten, dass der Verein in Abteilungen gegliedert ist (Handball und Fußball), dass jede Abteilung eine/n Leiter/in und mehrere Mannschaften hat. |
Abteilungen |
In Konfrontation mit den schon erstellten Modellfragmenten lässt sich damit festhalten, dass Abteilungen zu einer Relation mit den Attributen AbtBez und AbtLeiter wird. Die Tatsache, welche Mannschaft zu welcher Abteilung gehört, ist eine 1:n-Beziehung (z.B. als 1,1 : 1,n) und wird daher durch den Fremdschlüssel AbtNr in Mannschaften festgehalten. |
|
Abteilungen (#AbtNr, #AbtBez, AbtLeiter) |
|
Mannschaften (#MaNr, MaBez, Liga, TrNr, KapNr, AbtNr) |
|
Eine Mannschaft hat mehrere Spieler, ein Spieler kann in mehreren Mannschaften sein. Damit liegt eine n:m-Beziehung zwischen Aktiven Mitgliedern (AM) und Mannschaften (MA) vor: |
Spieler |
AM-MA (#(MaNr, MiNr)) |
|
Im beschreibenden Text wurde festgelegt, dass alle Begegnungen von Mannschaften des Vereins mit Tagesdatum, Gegner und Ergebnis festgehalten werden sollen. Da die Mannschaften in einer anderen Relation beschrieben sind, werden sie hier durch den Fremdschlüssel MaNr repräsentiert: |
Begegnungen |
MaNr, Tag, Gegner, Ergebnis |
|
Fehlt noch ein Schlüssel. Dieser könnte realisiert werden, indem bei jeder Begegnung der Beginn des Spiels miterfasst wird. Denn eine Mannschaft kann zwar u.U. an einem Tag mehrere Begegnungen haben, aber nicht mit demselben Startpunkt. Damit werden (MaNr, Tag, Beginn) zu einem Schlüssel und die Relation ergibt sich wie folgt: |
|
Begegnungen (#(MaNr, Tag, Beginn), Gegner, Ergebnis) |
|
Die Beziehung Begegnungen zu Mannschaften stellt eine Komposition dar. Wenn eine Mannschaft aus der Datenbank gelöscht wird, müssen (datenbanktechnisch) auch ihre Begegnungen verschwinden, da unvollständige Schlüssel nicht zulässig sind. |
Muster Komposition |
Zu beachten ist, dass es nur um die Spiele des betrachteten Vereins geht, nicht um alle Spiele einer Liga, was die Situation verändern würde. Oben wurde schon angemerkt, was geschieht, falls ausnahmsweise im Rahmen eines Turniers zwei Mannschaften des Vereins gegeneinander spielen. |
|
2.5.3 Lösung |
|
Insgesamt ergibt sich damit das folgende Datenmodell. |
|
Textliche Fassung |
|
Mitglieder (#MiNr, Name, VName, Tel, GebTag, PLZ, Ort, Straße, Status) |
|
Mitgliedschaften (#(MiNr, Eintritt), Austritt) |
|
MitglVerstorben (#MiNr, Todestag) |
|
MitglAktiv (#MiNr, Sportart, LStufe) |
|
MitglPassiv (#(MiNr, BezTät)) |
|
Begegnungen (#(MaNr, Tag, Beginn), Gegner, Ergebnis) |
|
AM-MA (#(MaNr, MiNr)) |
|
Abteilungen (#AbtNr, AbtBez, AbtLeiter) |
|
Mannschaften (#MaNr, MaBez, Liga, TrNr, KapNr, AbtNr) |
|
Anmerkung: |
|
Folgende Abweichungen gegenüber der Modellierung der Fragmente in den Basisübungen liegen vor: |
|
- Attribut Mitglieder.Status. Es erfasst auch die verstorbenen Mitglieder (Attributsausprägungen aktiv, passiv, verstorben). |
|
- Hier wurde nur ein einziger Telefonanschluss modelliert. Dadurch wird Tel ein ganz normales deskriptives Attribut. |
|
Grafische Fassung |
|
|
|
Abbildung 2.5-2: Gesamtmodell Sportverein |
|
AbtNr: Abteilungsnummer |
|
AbtLeiter: Abteilungsleiter |
|
MaNr: Mannschaftsnummer |
|
MiNr: Mitgliedsnummer |
|
TrNr: Trainernummer |
|
KapNr: Kapitänsnummer |
|
LStufe: Leistungsstufe |
|
BezTät: Bezeichnung der ehrenamtlichen Tätigkeit |
|
|
2.6 Obst |
|
2.6.1 Anforderungsbeschreibung |
|
Ein Einzelhändler möchte seine Obstlieferanten und Obstlieferungen in einer Datenbank verwalten. Für alle Lieferanten erfasst er die Zuverlässigkeit (ZV; Skala von 1 bis 6) und die Art der Abrechnung (AbrArt; sofort, Monatsende, Saisonende, ...). Bezüglich der Landwirte, die ihm Obst liefern, erfasst er Name, Vorname (VName), Typ (biologisch, konventionell, ...), Postleitzahl (PLZ), Ort, Straße, Telefon (nur eines; Tel), Mailadresse (E-Mail) und welche Obstsorten (z.B. Golden Delicious) (SortBez) sie ihm in den einzelnen Monaten typischerweise liefern können ("Lieferbarkeit"). Natürlich bezieht er dieselbe Obstsorte u.U. von unterschiedlichen Landwirten und von einem Landwirt mehrere Obstsorten, z.B. eine Sorte Äpfel, mehrere Sorten Birnen, usw., alles was in der Region wächst. |
|
Bezüglich der Obstgroßhändler erfasst er Firmenname (FName), Land (Deutschland, Österreich, Schweiz, Niederlande, ...) Postleitzahl (PLZ), Ort (Ort), Straße, Telefon (nur eines) (Tel), Fax (Fax), Mailadresse (E-Mail) und - genau wie bei den Landwirten - welche Obstsorten (SortBez) in welchem Zeitraum typischerweise lieferbar sind (z.B. Erdbeeren von Januar bis März, da aus Übersee). Alle Lieferanten (Landwirte oder Großhändler) erhalten eine Lieferantennummer (LiefNr). Aus pragmatischen Gründen erhält jede Obstsorte auch eine identifizierende Nummer (Sortennummer, SortNr). Für jede Obstsorte wird auch festgehalten, wie lagerfähig sie ist (LagFäh), d.h. wieviele Wochen man sie gekühlt aufheben kann. |
|
Weiter sollen konkrete Lieferungen (von Landwirten oder Großhändlern) erfasst werden mit Obstsorte, Menge (Menge), Liefertag (LTag), Lieferant (Landwirt oder Großhändler) und Kilopreis (KPreis). Ein Lieferant liefert höchstens einmal pro Tag, da aber u.U. mehrere Obstsorten. Aus statistischen Gründen wird auch festgehalten, wieviel (in kg) von jeder Obstsorte umgesetzt wurde (Umsatz). Diese Berechnung erfolgt in jedem Jahr neu ab Jahresanfang. |
|
2.6.2 Lösungsschritte |
|
Beim Lesen der Anforderungsbeschreibung sollte man erkennen, dass die Beschreibung der Lieferanten zu der Struktur führt, die man Generalisierung / Spezialisierung nennt. Da gibt es zum einen Landwirte, zum anderen Großhändler und beide haben teilweise identische Attribute. Da beide Gruppen identifiziert und beschrieben werden, ist für sie jeweils eine Relation anzulegen. Für die identischen Attribute ist ebenfalls eine eigene Relation anzulegen. Die erste Annäherung ergibt: |
Generalisierung / Spezialisierung |
- Attribute für alle Lieferanten (Generalisierung): LiefNr, ZV, AbrArt
- Attribute für Landwirte (Spezialisierung 1): Name, VNameTyp, PLZ, Ort, Straße, Tel, E-Mail, SortBez (mehrere)
- Attribute für Großhändler (Spezialisierung 2): FName, Land, PLZ, Ort, Straße, Telefon, Fax, E-Mail
|
|
Schauen wir obige drei Relationenkandidaten an, sehen wir, dass die beiden Spezialisierungen noch identische Attribute aufweisen. Dies muss geändert werden, schließlich sollen Generalisierung und Spezialisierungen bis auf verknüpfende Attribute nur verschiedene haben. Wir nehmen also im nächsten Schritt alle weiteren Attribute, die für alle Lieferanten vorliegen, in die entsprechende Relation: |
|
Lieferanten (#LiefNr, ZV, AbrArt, PLZ, Ort, Straße, E-Mail, Tel) |
|
Natürlich kommen wir gleich ins Grübeln, was die Adressen angeht. Da aber nicht verlangt ist, mehrere Adressen pro Lieferant zu erfassen, können wir es so belassen. |
|
Für die Landwirte bleiben dann noch folgende Attribute übrig: |
|
Landwirte (#LiefNr, Name, Vorname, Typ) |
|
Für die Großhändler: |
|
Großhändler (#LiefNr, FName, Land, Fax) |
|
Wie üblich bei einer Generalisierung / Spezialisierung erhalten alle drei Relationen denselben Schlüssel. Für Anmerkungen zur Verknüpfung vgl. unten. |
|
Pragmatik. Die relationale Theorie verlangt es nicht, aber aus pragmatischen Gründen nimmt man bei einer Gen/Spez oftmals ein Attribut in die Generalisierung, das für jeden Eintrag festhält, zu welcher Spezialisierung er gehört. Das macht SQL-Abfragen sehr viel einfacher, z.B. wenn auf die Spezialisierungen zugegriffen werden soll. Wir ergänzen hier also in Lieferanten ein Attribut Typ mit den zwei Ausprägungen Landwirt (LW) und Großhändler (GH). |
|
Lieferanten (#LiefNr, Typ, ZV, AbrArt, PLZ, Ort, Straße, E-Mail, Tel) |
|
Betrachten wir nun die Lieferbarkeit. Hier deutet die Anforderungsbeschreibung an, dass Landwirte und Großhändler gleich behandelt werden. Folgende Tabelle fasst die beschriebene Semantik zusammen. |
Lieferbarkeit und Obstsorten |
Beispiele für Lieferbarkeit |
|
LiefNr |
SortBez |
Monat |
100 |
Äpfel xyz |
August |
100 |
Äpfel xyz |
September |
100 |
Birnen xyz |
Oktober |
101 |
Birnen xyz |
Oktober |
... |
... |
... |
| |
- Ein Lieferant kann mehrere Obstsorten liefern und dies jeweils in verschiedenen Monaten.
- Eine Obstsorte kann von verschiedenen Lieferanten geliefert werden und dies wiederum in verschiedenen Monaten.
|
|
Wir haben also eine Dreierbeziehung, die durch einen Schlüssel mit drei Attributen bewältigt wird: |
|
Lieferbarkeit (#(LiefNr, ObstNr, Monat)) |
|
Wer da Probleme hat, dem hilft die Überlegung, dass erst durch das Attribut Monat jedes Tupel eindeutig wird. Die Unterstreichungen kennzeichnen Fremdschlüssel und deuten Verknüpfungen an. Dazu unten mehr. |
|
Auch für die Obstsorten liegen identifizierende und beschreibende Attribute vor, so dass eine entsprechende Relation entsteht: |
|
Obstsorten (#ObstNr, SortBez, LagFäh) |
|
Die Beziehungen ergeben sich zum Teil methodisch, zum Teil semantisch. Methodisch sind es die zwischen der Generalisierung Lieferanten und den Spezialisierungen Landwirte und Großhändler. Dies wurde oben schon durch den Schlüssel LiefNr umgesetzt. Die Kardinalität einer Beziehung zwischen Generalisierung und Spezialisierung ist 1:1. Da aber in jeder Spezialisierung nur eine Teilmenge der Generalisierung vorliegt, sind die Min-/Max-Angaben (für Landwirte/Lieferanten bzw. Großhändler/Lieferanten) 1,1 : 0,1. |
Beziehungen klären |
Eine semantische Basis haben die "konkreten Lieferungen" (KonkreteLief). Sie verknüpfen Lieferanten und Obstsorten. Wegen der angeführten Wertigkeiten können wir eine Relation mit einem zusammengesetzten Schlüssel anlegen: |
|
KonkreteLief (#(LiefNr, ObstNr)) |
|
Es fehlt aber noch der Liefertag (LTag). Da jeder Lieferant höchstens einmal pro Tag liefert, können wir LTag noch zum Schlüssel hinzunehmen: |
|
KonkreteLief (#(LiefNr, ObstNr, LTag)) |
|
Wenn wir die beschreibenden Attribute noch hinzufügen erhalten wir die folgende Relation: |
|
KonkreteLief (#(LiefNr, ObstNr, LTag), Menge, KPreis) |
|
Die beiden Fremdschlüssel zeigen die notwendigen relationalen Verknüpfungen zwischen Lieferanten und Obstsorten auf. Die Kardinalität ist n:m, die Min-/Max-Angaben sollen auf 0,n : 0,m festgelegt werden. D.h., wir wollen auch Lieferanten erfassen, von denen noch keine Lieferungen kamen und Obstsorten, die noch nicht geliefert wurden. |
|
Etwas Nachdenken verlangen die abschließenden Ausführungen zu den Jahresmengen. Es ist verlangt, in jedem Jahr für jede Obstsorte den Umsatz im Zeitverlauf hochzurechnen. Dies kann nicht in vollem Umfang durch die Datenmodellierung gelöst, sondern nur vorbereitet werden. Dazu dient die folgende Relation: |
|
Jahresumsätze (#(Jahr, ObstNr), Umsatz) |
|
Eine Verknüpfung kann mit Obstsorten angelegt werden. Die Kardinalität ist (von Obstsorten ausgehend) 1:n, da es nach mehreren Jahren mehrere Jahresumsätze je Obstsorte gibt. Die Min-/Max-Angaben sind, wenn wir annehmen, dass neue Obstsorten nicht gleich in die Messung geraten, 0,n : 1,1. |
|
Durch Datenbankprogrammierung (Trigger, usw.) muss sichergestellt werden, dass bei jedem Eintrag in KonkreteLief in der Relation Jahresumsätze ein Fortschreiben des entsprechenden Umsatzes erfolgt. Am Jahresende muss die Datenbankprogrammierung sicherstellen, dass neue Tupel für das neue Jahr angelegt werden. |
|
Die Relationen sind in der höchsten Normalform: Die BCNF ist erfüllt und es liegen keine Verstöße gegen die 4NF und 5NF vor. Das auftretende Muster (Gen/Spez) wurde eingearbeitet. Weitere liegen nicht vor. Die automatisierte Bestimmung der Jahresumsätze muss mittels Datenbankprorammierung erfolgen. |
Schlussbemerkung |
2.6.3 Lösung |
|
Textliche Fassung |
|
Großhändler (#LiefNr, FName, Land, Fax) |
|
Jahresumsätze (#(Jahr, ObstNr), Umsatz) |
|
KonkreteLief (#(LiefNr, ObstNr, LTag), Menge, KPreis) |
|
Landwirte (#LiefNr, Name, Vorname, Typ) |
|
Lieferanten (#LiefNr, ZV, AbrArt, PLZ, Ort, Straße, E-Mail, Tel) |
|
Lieferbarkeit (#(LiefNr, ObstNr, Monat)) |
|
Obstsorten (#ObstNr, SortBez, LagFäh) |
|
|
|
Grafische Fassung |
|
|
|
Abbildung 2.6-1: Relationales Datenmodell Obst |
|
2.7 Angestellte |
|
Diese Aufgabe gehört mit 18 Relationen und zahlreichen Modellmerkmalen (auch zu Zeitaspekten) zu den ausführlichen. |
|
2.7.1 Anforderungsbeschreibung |
|
In diesem Anwendungsbereich geht es um Angestellte eines Unternehmens, ihre Ausstattung mit PC, ihre Mitarbeit in Abteilungen und Projekten, usw. Ausschnitte aus diesem didaktisch motivierten Datenmodell dienen in den Theoriekapiteln von [Staud 2021] als Beispiele. Folgendes soll festgehalten werden: |
|
(1) Für die Angestellten die Personalnummer (PersNr), der Name (Name), Vorname (VName) und Geburtstag (GebTag). Außerdem werden die Adressen erfasst mit Strasse, PLZ, Ort und einer zweiten Adresszeile (AdrZ2). Jeder Angestellte kann mehrere Adressen haben und unter einer Adresse können mehrere Angestellte wohnen.
|
|
(2) Das Vorgesetztenverhältnis. Wer ist wem unter- bzw. überstellt?
|
|
(3) Für die Projekte die Bezeichnung (Bez), der Einrichtungstag (TagEinr), die Dauer (Dauer) und das Budget (Budget). Ein Projekt kann auf mehrere Standorte verteilt sein. Dies wird auch erfasst.
|
|
(4) Die Standorte werden mit einer identifizierenden Information (OrtId), ihrer Bezeichnung (Bez), ihrer Adresse und der Anzahl Mitarbeiter am Standort (AnzMitarb) erfasst.
|
|
(5) Ein Angestellter kann in mehreren Projekten mitarbeiten und ein Projekt hat typischerweise mehrere Mitarbeiter.
|
|
(6) Für die Abteilungen wird die Abteilungsbezeichnung (AbtBez), der Abteilungsleiter (AbtLeiter) und der Standort festgehalten. Eine Abteilung ist immer genau an einem Standort, an einem Standort können mehrere Abteilungen sein.
|
|
(7) In einer Abteilung sind mehrere Angestellte, ein Angestellter gehört aber zu einem Zeitpunkt genau zu einer Abteilung. Im Zeitverlauf können Angestellte auch die Abteilung wechseln, was mit BeginnZ(ugehörigkeit) und EndeZ ebenfalls erfasst wird.
|
|
(8) Festgehalten wird auch, welche Funktion ein Angestellter in einer Abteilung hat. Dies geschieht mit Hilfe der Funktionsbezeichnung (BezFu), dem Beginn (Beginn) und Ende (Ende) der Funktionsübernahme. Es ist durchaus möglich, dass ein Angestellter im Zeitablauf auch unterschiedliche Funktionen in einer Abteilung übernimmt. Zu einem Zeitpunkt aber immer nur eine.
|
|
(9) Für die von den Angestellten benutzten PC wird die Inventarnummer, (InvNr), das Kaufdatum (Kauf), die Bezeichnung (Bez) und der Typ (Standard, Entwickler-PC, Server, . . .) erfasst. Ein PC kann mehreren Angestellten zugeordnet sein, ein Angestellter nutzt zu einem Zeitpunkt maximal einen PC. Bei der Übernahme eines PC durch einen Angestellten wird die Art der Nutzung (Art; "Entwickler, Office-Nutzer, Superuser"), der Beginn (Beginn) und das Ende (Ende) festgehalten. Natürlich nutzt ein Angestellter im Zeitverlauf mehrere PC, diesbezüglich soll die gesamte Historie festgehalten werden.
|
|
(10) Für die Programmiersprachen, die von den Angestellten beherrscht werden, wird die Bezeichnung der Sprache (BezPS), die Bezeichnung des Compilers (BezComp) und der Preis (PreisLiz) für eine Lizenz festgehalten. Wegen der Bedeutung der Programmiererfahrung wird außerdem festgehalten, wieviel Jahre Programmierpraxis (ErfPS) jeder Angestellte in seinen Programmiersprachen hat. Es gibt auch Angestellte, die nicht programmieren und keine Programmiersprache beherrschen.
|
|
(11) Für die Entwickler unter den Angestellten wird die von ihnen genutzte Entwicklungsumgebung (EntwU) und ihre hauptsächlich genutzte Programmiersprache festgehalten (HauptPS). Für die Mitarbeiter des Gebäudeservices die Funktion (Funktion) und die Schicht (Schicht), in der sie arbeiten. Für das Top-Management der Bereich in dem sie tätig sind (Bereich) und das Entgeltmodell, nach dem sie ihr Gehalt bekommen (Entgelt).
|
|
2.7.2 Lösungsschritte |
|
Punkt 1 deutet eine Relation zu Angestellten an. Der Schlüssel und zahlreiche weitere Attribute sind bereits angeführt: |
Relationen festlegen |
Angestellte (#PersNr, Name, VName, GebTag) |
|
Mit ihnen kommen die Adressen und der Semantikaspekt, dass jeder Angestellte mehrere Adressen haben kann und unter einer Adresse mehrere Angestellte wohnen können. Hier legen wir schon mal die Adressrelation an, der weitergehende Semantikaspekt wird unten betrachtet. Wir ergänzen einen Schlüssel für die Adressen (AdrId). |
|
Adressen (#AdrId, PLZ, Ort, AdrZ2, Strasse) |
|
Der nächste Punkt gibt einen Hinweis auf das zu erfassende Vorgesetztenverhältnis. Dazu unten mehr. Dann die Projekte (3). Sie werden identifiziert und beschrieben, also können wir eine Relation anlegen : |
|
Projekte (#Bez, TagEinr, Dauer, Budget) |
|
Die Projektmitarbeit setzt Angestellte und Projekte in eine Beziehung. Sie wird deshalb unten modelliert. |
|
Auch die Standorte (Punnkt 4) sind identifiziert und beschrieben, wobei die Klärung der Adressangaben unten erfolgt. Damit ergibt sich erstmal: |
|
Standorte (#OrtId, Bez, AnzMitarb) |
|
Die in (6) angesprochenen Abteilungen sind ebenso sofort als Relationen erkennbar. Es werden eine Bezeichnung und weitere beschreibende Attribute genannt. Für den Standort ergänzen wir ein Attribut Ort: |
|
Abteilungen (#AbtBez, AbtLeiter, Ort) |
|
Das Verhältnis Abteilung/Standort klären wir unten. Auch die nächsten beiden Punkte klären Beziehungsfragen und werden deshalb unten betrachtet. |
|
Danach folgt in (9) die Beschreibung der PC. Beim Lesen dieses Punktes sollte man erkennen, dass hier Einzelgeräte erfasst werden. Diese werden wie folgt beschrieben: |
|
PC (#InvNr, Kauf, Typ, Bez) |
|
Die Zuordnung der PC ist wiederum eine Beziehungsfrage und wird unten umgesetzt. |
|
Der vorletzte Punkt deutet an, dass Software in diesem Unternehmen eine große Rolle spielt. Die Programmiersprachen werden identifiziert und beschrieben, finden also in eine Relation: |
|
PS (#BezPS, BezComp, PreisLiz) |
|
Die Sache mit der Programmiererfahrung gehört wiederum in den nächsten Punkt. |
|
Der letzte Punkt deutet eine Generalisierung / Spezialisierung an. Entwickler, Gebäudeservice und Manager haben als Spezialisierungen jeweils eigene Attribute, zusätzlich zu denen der Generalisierung (Angestellte). Damit ergeben sich folgende Relationen : |
Generalisierung / Spezialisierung |
Entwickler (#PersNr, EntwU, HauptPS) |
|
TopMan (#PersNr, Bereich, Entgelt) |
|
GebService (#PersNr, Funktion, Schicht) |
|
Der Schlüssel ist, wie bei einer Generalisierung / Spezialisierung üblich, derjenige der Generalisierung. |
|
Beziehungen klären |
|
Beginnen wir bei der Präzisierung der Beziehungen wieder mit dem ersten Punkt der Anforderungsbeschreibung. Hier geht es um die Beziehung zwischen Angestellten und Adressen: |
Angestellte / Adressen |
Adressen (#AdrId, PLZ, Ort, AdrZ2, Strasse) |
|
Angestellte (#PersNr, Name, VName, GebTag) |
|
Die Semantik beschreibt eine n:m-Beziehung. Dies erfordert eine Verbindungsrelation AngAdr mit einem zusammengesetzten Schlüssel: |
|
AngAdr (#(PersNr, AdrNr)) |
|
Die Kardinalität ist n:m. Die Min-/Max-Angaben sind 1,n : 1,m, wenn man die Adressangabe zu einer Pflichtangabe macht (d.h., in der Datenbank gibt es keinen Angestellten ohne Adresse und keine Adresse ohne Angestellten). Denkbar wären aber auch 0,n : 0,m und andere Kombinationen (vgl. Abbildung). |
|
|
|
Abbildung 2.7-1: N:m-Beziehung mit AngAdr und alternativen Min-/Max-Angaben. |
|
Im zweiten Punkt ist gefordert, dass das Vorgesetztenverhältnis zwischen den Angestellten erfasst wird. Dies ist eine rekursive Beziehung (vgl. auch [Staud 2021, Abschnitt 14.3]), die in der relationalen Modellierung durch eine weitere Relation Vorgesetzte gelöst werden muss: |
Vorgesetzte |
Vorgesetzte (#(PersNrV, PersNrU)) |
|
Angestellte (#PersNr, Name, VName, GebTag) |
|
Damit steht in jedem Tupel von Vorgesetzte an erster Stelle die Personalnummer des Vorgesetzten, an zweiter Stelle die einer untergebenen Person. Beide Attribute sind Fremdschlüssel bzgl. Angestellte.PersNr. Jedes Tupel hält somit ein Vorgesetztenverhältnis fest. In dieser Relation können auch Hierarchien abgebildet werden. Dies ist eine schlichte Lösung des Problems, mehr an Semantik muss in die Anwendungsprogrammierung. |
|
Erinnerung: Angestellte.PersNr bedeutet: Attribut PersNr der Relation Angestellte. |
|
Die nächste zu klärende Beziehung betrifft die zwischen Projekten und Standorten (Punkt 3). Da ein Projekt auf mehrere Standorte verteilt sein kann und da - wie wir auf Nachfrage erfuhren [Anmerkung] - an einem Standort mehrere Projekte angesiedelt sein können, liegt hier eine n:m-Beziehung zwischen Projekten und Standorten vor. Hier die Lösung, ergänzt um die beiden verknüpften Relationen: |
Projekte / Standorte |
ProjOrte (#(BezProj, OrtId)) |
|
Projekte (#Bez, TagEinr, Dauer, Budget) |
|
Standorte (#OrtId, Bez, AnzMitarb) |
|
Die Min-/Max-Angaben ergeben sich zu 1,n : 1,m, wenn wir festlegen, dass jedes Projekt ab Einrichtung mindestens einen Standort haben muss und ein Standort erst in die Datenbank aufgenommen wird, wenn mindestens 1 Projekt dort angesiedelt ist. |
|
Auch die Projektmitarbeit (Punkt (5)) hat die Struktur einer n:m-Beziehung. Ein Angestellter kann in mehreren Projekten mitarbeiten, ein Projekt kann mehrere zugeordnete Angestellte haben. Mit den verknüpften Relationen ergibt sich: |
Projekt-mitarbeit |
ProjMitarb (#PersNr, BezProj)) |
|
Angestellte (#PersNr, Name, VName, GebTag) |
|
Projekte (#Bez, TagEinr, Dauer, Budget) |
|
Was die Min-/Max-Angaben angeht, können wir davon ausgehen, dass sicherlich nicht alle Angestellten in Projekten tätig sind. Außerdem sei es so, dass ein Projekt datenbanktechnisch schon eingerichtet sein kann, bevor ihm Personal zugewiesen wurde. Damit ergeben sich die Min-/Max-Angaben 0,n : 0,m. |
|
Als nächster Beziehungsaspekt werden in Punkt (6) die Abteilungsstandorte angeführt. So wie es gefordert ist, stellt es eine 1:n-Beziehung dar (Standorte/Abteilungen). Da eine Abteilung nicht ohne Standort existieren kann, wird das Attribut OrtId zu einem Fremdschlüssel in Abteilungen. Wir nehmen an, dass es Standorte auch geben kann, ohne dass dort eine Abteilung angesiedelt ist (weil dort z.B. nur Projekte sind). Dies erfordert die Min-/Max-Angaben 1,n : 0,n. Zusammen mit der beteiligten Relation ergibt sich damit: |
Abteilungen / Standorte |
Abteilungen (#AbtBez, AbtLeiter, OrtId) |
|
Standorte (#OrtId, Bez, AnzMitarb) |
|
Punkt (7) spricht die Abteilungszugehörigkeit an. Nach der Beschreibung ist dies eine 1:n-Beziehung, die durch einen Fremdschlüssel AbtBez in Angestellte modelliert werden könnte. Hier ist aber zusätzlich verlangt, dass die zeitliche Zugehörigkeit ebenfalls erfasst wird mit Anfang (BeginnZ) und Ende (EndeZ) der Zugehörigkeit. Damit ist ein Zeitaspekt zu modellieren: die Zeitabschnitte der Abteilungszugehörigkeit. Da es durchaus vorkommen kann, dass jemand eine Abteilung verlässt und später wieder in sie zurückkommt (vielleicht sogar mehrfach), liegt hier eine n:m-Beziehung mit zeitlicher Dimension zwischen Abteilungen und Angestellten vor. |
Abteilungs-zugehörigkeit |
Da ein Angestellter zu jedem Zeitpunkt einer Abteilung angehören sollte (extreme Sonderfälle sollen mal nicht betrachtet werden), und da eine Abteilung erst eingerichtet wird, wenn zumindest die Abteilungsleiterin feststeht (so soll es hier sein), sind die Min-/Max-Angaben für die Richtung Angestellte/Abteilungen 1,n : 1,m. |
|
Dafür richten wir eine Relation AngAbtZug (Angestellen/Abteilung/Zugehörigkeit) ein, in die neben PersNr und AbtBez auch BeginnZ und EndeZ rein müssen. |
|
Mit der Aufnahme von Beginn und Ende der Zugehörigkeit, können die unterschiedlichen Phasen erfasst werden. Z.B. kann eine Angestellte vom 1.1.2020 bis zum 20.6.2023 und vom 4.5.2021 bis zur Gegenwart in einer bestimmten Abteilung gewesen sein. Um Eindeutigkeit zu erreichen, muss ein Zeitpunkt in den Schlüssel. Wir nehmen hier BeginnZ. |
|
Die zeitliche Dimension führt im Fall von Zeiträumen dazu, dass gegen die "reine" relationale Lehre verstoßen werden muss. Denn dabei entsteht ein Attribut (hier: EndeZ), das semantikbedingt leere Einträge hat (bis zum Ende des Zeitraums, hier: der Zugehörigkeit) und dies sollte in relationalen Datenbanken nicht sein. Eine eigene Relation für EndeZ wäre möglich, darauf wird aber aus pragmatischen Gründen i.d.R. verzichtet. |
Zeitliche Dimension |
Der Schlüssel enthält zum einen PersNr und AbtBez, muss zum anderen um BeginnZ erweitert werden. Insgesamt wird diese Beziehung dann durch folgende Relationen beschrieben: |
|
AngAbtZug (#(PersNr, AbtBez, BeginnZ), EndeZ) |
|
Abteilungen (#AbtBez, AbtLeiter, OrtId) |
|
Angestellte (#PersNr, Name, VName, GebTag) |
|
In Punkt (8) wird gefordert, dass auch die Funktionen, die Angestellte in Abteilungen übernehmen, in der Datenbank erfasst werden. Basis ist wieder die 1:n-Beziehung zwischen Angestellten und Abteilungen. Hier muss sie ergänzt werden um die Attribute der Funktionsbeschreibung: BezFu, BeginnF, EndeF. Da auch hier ein wiederholtes Beenden und Wiederaufnehmen möglich ist und zu einem Zeitpunkt nur eine einzige Funktion übernommen wird, ist die folgende Relation AngAbtFu korrekt. |
|
Zur Wertigkeit liegen keine Angaben vor. Wir nehmen daher an, dass eine Angestellte in einer Abteilung in einem Zeitraum nur jeweils eine Funktion übernimmt und dass eine Abteilung keine, eine oder mehrere Funktionen zu vergeben hat. Damit ergibt sich die Kardinalität n:m und die Min-/Max-Angaben 0,1 : 0,m. |
|
AngAbtFu (#(PersNr, AbtBez, BeginnF), EndeF, BezFu)) |
|
Die Funktionsübernahme kann damit vollständig in die Relation AngAbtFu aufgenommen werden. Der Schlüssel muss BeginnF enthalten (möglich wäre auch EndeF), dadurch sind auch mehrere zeitlich verschobene Funktionsübernahmen möglich. |
|
Die Struktur wäre durch leichte semantische Änderungen eine andere, z.B. wenn mehr als eine Funktion in einem Zeitraum übernommen werden könnte. |
|
Punkt (9) klärt die Zuordnung von PC zu Angestellten. In der Beschreibung wird eine 1:n-Beziehung deutlich, was normalerweise einfach zu einem Fremdschlüssel führt. Hier ist aber wieder für diese PC-Nutzung Beginn, Ende und Art der Nutzung zu erfassen und dies so, dass auch mehrere Nutzungsphasen modelliert werden können. |
PC und Angestellte |
Wir müssen also die einfache Relation |
|
PC-Nutzung (#(PersNr, InvPC)) |
|
oder |
|
PC-Nutzung(#InvPC, PersNr) |
|
(wenn eine Person nur einen PC hat) ergänzen. Zum einen machen wir PersNr und Beginn gemeinsam zum Schlüssel. Damit erfasst diese Relation nicht mehr nur Personen, sondern Zeiträume. Hinzu muss auch Ende zur Beschreibung des Zeitraums und Art für die Nutzung sowie InvPC als Fremdschlüssel, damit festgehalten wird, um welchen PC es sich handelt. |
|
Die Min-/Max-Angaben ergeben sich (von PC zu Angestellte) zu 0,n : 0,1, wenn PC auch erfasst werden sollen, bevor sie zugewiesen sind und man die Möglichkeit bestehen lassen will, dass es Angestellte (in der Datenbank) gibt, die noch keinen PC zugewiesen bekommen haben. |
|
Zusammen mit den verknüpften Relationen ergibt sich dann: |
|
AngPC (#(PersNr, Beginn), InvNrPC, Art, Ende) |
|
PC (#InvNr, Kauf, Typ, Bez) |
|
Angestellte (#PersNr, Name, VName, GebTag) |
|
Bei den Programmiersprachen zielt die weitere Beschreibung in Punkt 10 auf die Erfassung der Programmiererfahrung. Es soll also ganz grundsätzlich die Beziehung zwischen Angestellten und Programmiersprachen festgehalten werden ("wer kann in Java programmieren?") und die Anzahl der Erfahrungsjahre. |
|
Durch die Mehrzahl bei Programmiersprachen ist die die Kardinalität n:m. Die Min-/Max-Angaben sind 0,n : 0,m, da ja Angestellte dabei sind, die nicht programmieren und wir auch Programmiersprachen in der Datenbank erfassen wollen, die zwar angeschafft wurden, aber noch nicht eingesetzt werden. |
|
Dies erfordert wieder eine eigene Relation AngPS für diese Beziehung zwischen PS und Angestellte. |
|
AngPS (#(BezPS, PersNr)) |
|
PS (#BezPS, BezComp, PreisLiz) |
|
Angestellte (#PersNr, Name, VName, GebTag) |
|
Sehr oft gibt es in Anforderungsbeschreibungen nur indirekte Hinweise auf Beziehungen. Ein Beispiel ist hier die Beziehung zwischen Abteilungen und Abteilungsleitern. Nehmen wir folgendes an: |
Vergessene Anforderungen |
- Eine Angestellte kann keine, eine oder in Ausnahmefällen auch mal mehr Abteilungen leiten.
- Eine Abteilung wird immer genau von einem Angestellten geleitet und auch erst eingerichtet, wenn ein solcher ernannt ist.
|
|
Damit ist die Kardinalität (Angestellte/Abteilungen) 0:n und Abteilung.AbtLeiter wird zum Fremdschlüssel. Die Min-/Max-Angaben sind 0,m : 1,1. |
|
Abteilungen (#AbtBez, AbtLeiter, OrtId) |
|
Restliche Prüfung |
|
Dadurch, dass bei der Bildung der Relationen auf die Einhaltung der Struktur "ein Schlüssel und nur davon abhängige Attribute" geachtet wurde, war die höchste Normalform gesichert. Das führte auch zu den Lösungen rund um die Muster, z.B. indem Spezialisierungen in eigene Relationen mit dem Schlüssel der Generalisierung kommen. Auch Verstöße gegen die 4NF und 5NF liegen hier nicht vor. |
|
Gegen die Grundlagen der relationalen Theorie verstoßen die Attribute, die erstmal keine Werte aufweisen können ("Ende Zeitraum"), weil ihre Werte erst später anfallen. Streng nach der reinen Lehre wären hier eigene Relationen nötig. |
|
2.7.3 Lösung |
|
Insgesamt gehören zum Datenmodell nun folgende Relationen. |
|
Textliche Fassung |
|
Abteilungen (#AbtBez, AbtLeiter, OrtId) |
|
Adressen (#AdrId, PLZ, Ort, AdrZ2, Strasse) |
|
AngAbtFu (#(PersNr, AbtBez, BeginnF), EndeF, BezFu)) |
|
AngAbtZug (#(PersNr, AbtBez, BeginnZ), EndeZ) |
|
AngAdr (#(PersNr, AdrNr)) |
|
Angestellte (#PersNr, Name, VName, GebTag) |
|
AngPC (#(PersNr, Beginn), InvNrPC, Art, Ende)) |
|
AngPS (#(PersNr, BezPS), ErfPS) |
|
Entwickler (#PersNr, EntwU, HauptPS) |
|
GebService (#PersNr, Funktion, Schicht) |
|
PC (#InvNr, Kauf, Typ, Bez) |
|
Projekte (#Bez, TagEinr, Dauer, Budget) |
|
ProjMitarb (#PersNr, BezProj)) |
|
ProjOrte (#(BezProj, OrtId)) |
|
PS (#BezPS, BezComp, PreisLiz) |
|
Standorte (#OrtId, Bez, AnzMitarb, AdrId) |
|
TopMan (#PersNr, Bereich, Entgelt) |
|
Vorgesetzte (#(PersNrV, PersNrU)) |
|
|
|
Grafische Fassung |
|
|
|
Abbildung 2.7-2: Relationales Datenmodell zum Anwendungsbereich Angestellte |
|
2.8 Sprachenverlag |
|
Diese Aufgabe gehört mit 15 Relationen, zahlreichen Modellmerkmalen und Mustern zu den ausführlichen. |
|
2.8.1 Anforderungsbeschreibung |
|
Es geht um die Produkte eines Verlages, der Wörterbücher (z.B. von Deutsch nach Englisch), digital oder auch gedruckt, herstellt und verkauft und der seit einiger Zeit auch Übersetzungsprogramme anbietet. Seine Produkte sollen in einer Datenbank verwaltet werden. Zu erfassen sind die nachfolgend angeführten Sachverhalte: |
|
(1) Alle Produkte, d.h. alle Wörterbücher und Volltextübersetzer (Programm zur automatischen Übersetzung von Text) mit ihrer Produktnummer (ProdNr) und Bezeichnung (Bez), mit ihrem Listenpreis (LPreis) und den Sprachen, die abgedeckt sind (z.B. deutsch nach englisch und englisch nach deutsch, deutsch nach französisch und französisch nach deutsch).
|
|
(2) Für jedes gedruckte Wörterbuch wird auch festgehalten, wieviele Einträge es hat (Einträge), für welche Zielgruppe es gedacht ist (Schüler, Studierende, "Anwender", "Profi-Anwender", Übersetzer) (Zielgruppe), wann es auf den Markt gebracht wurde (ErschDat), wieviele Seiten es hat (AnzSeit).
|
|
(3) Für jedes digitale Wörterbuch wird auch festgehalten, wann es auf den Markt gebracht wurde (ErschDat), welche Speichertechnik (SpeichTech) bei ihm verwendet wurde, wieviele Einträge es umfasst (Einträge) und für welche Zielgruppe es gedacht ist (Schüler, Studierende, "Anwender", "Profi-Anwender", Übersetzer) (Zielgruppe).
|
|
(4) Die digitalen Produkte des Verlags beruhen jeweils auf einem Übersetzungsprogramm (BezProg). Es kann sein, dass eines mit verschiedenen Programmen angeboten wird (z.B. zielgruppenspezifisch). Natürlich dient ein Programm u.U. mehreren digitalen Produkten. Für diese Programme wird festgehalten, welche Dokumentarten (DokArt) sie auswerten können (Word, PDF, Bildformate, usw.; mehrere) und ob es möglich ist, die Programmleistung in Textprogramme zu integrieren (IBK: Integrierbarkeit).
|
|
(5) Für jeden Volltextübersetzer wird auch festgehalten, welche Sprachen abgedeckt sind, wieviele Einträge das Systemlexikon hat (Einträge), für welche Zielgruppe das Produkt gedacht ist und wann es auf den Markt gebracht wurde (ErschDatum). Festgehalten wird außerdem, ob man den Käufern anbietet, es durch Internetzugriffe regelmäßig aktualisieren zu lassen. Falls ja, wie lange dies möglich ist (AktJahre), z.B. 5 Jahre ab Kauf.
|
|
(6) Für alle Programme werden außerdem die Softwarehäuser, die an der Erstellung mitgearbeitet haben, mit ihrer Anschrift (nur die der Zentrale) festgehalten. Es wird auch die zentrale E-Mail-Adresse erfasst. Es kommt durchaus vor, dass ein Programm in Kooperation von mehreren Softwarehäusern erstellt wird. Natürlich bietet ein bestimmtes Softwarehaus u.U. mehrere Programme an, z.B. für verschiedene Sprachen. Es wird bzgl. eines jeden Programms der Beginn und das Ende der Zusammenarbeit vermerkt.
|
|
(7) Für alle digitalen Produkte werden außerdem die Systemvoraussetzungen festgehalten, abhängig vom eingesetzten Programm. Welche minimale Hardwareanforderung gegeben ist (anhand des Prozessors, Proz), wieviel Arbeitsspeicher sie benötigen (ArbSp), wieviel freier Plattenspeicher (PlattSp) nötig ist (in MB) und welche Betriebssystemversion (BS) genutzt werden kann (Windows Vista, 7, 8; LINUX). Dies sind in der Regel mehrere.
|
|
(8) Erfasst werden auch die konkreten Geräte, auf denen die digitalen Produkte lauffähig sind mit ihrer Bezeichnung (Bez) und dem Gerätetyp (Typ; Smartphone, Pad, Tablet, Laptop, usw.). Auf einem Gerät sind natürlich mehrere digitale Produkte lauffähig, dagegen werden die digitalen Produkte am Ende ihrer Entwicklung auf genau ein Gerät zugeschnitten. Besteht das jeweilige Gerät nicht mehr, wird auch das zugehörige digitale Produkt überflüssig.
|
|
(9) Die Entwicklung der Programme findet so statt, dass jedes Programm mit unterschiedlichen grafischen Bedienoberflächen (GUI; graphical user interface) kombiniert werden kann. Für die GUIs wird ein Schlüssel (GUIId), der Typ (Fenster, Kacheln, ...) und die Programmiersprache (PS), mit der sie entwickelt wurde, festgehalten. Ein konkretes vom jeweiligen Softwarehaus angebotenes Programm enthält dann genau eine GUI, d.h. die Programme sind nach ihren GUIs differenziert.
|
|
2.8.2 Lösungsschritte |
|
Hier nun die schrittweise Umsetzung des Textes in ein relationales Datenmodell. Sie erfolgt, indem die Anforderungen nacheinander Absatz für Absatz bearbeitet werden. |
|
Anforderung Teil 1 |
|
Alle Produkte, d.h. alle Wörterbücher und Volltextübersetzer (Programm zur automatischen Übersetzung von Text) mit ihrer Produktnummer (ProdNr) und Bezeichnung (Bez), mit ihrem Listenpreis (LPreis) und den Sprachen, die abgedeckt sind (z.B. deutsch nach englisch und englisch nach deutsch, deutsch nach französisch und französisch nach deutsch). |
|
Dem Text kann entnommen werden, dass es Produkte gibt und dass diese (erstmal) aus Wörterbüchern und Volltextübersetzern bestehen. Nennen wir sie auch Produkte und geben ihnen den Schlüssel ProdNr. Außerdem wird auf die abgedeckten Sprachen hingewiesen. Da dies immer zwei sind, legen wir zwei Attribute Sprache1 und Sprache2 an. Z.B. also mit den Einträgen Italienisch und Deutsch. |
|
Produkte (#ProdNr, Bez, LPreis, Sprache1, Sprache2) |
|
Anforderung Teil 2 |
|
Für jedes gedruckte Wörterbuch wird auch festgehalten, wieviele Einträge es hat (Einträge), für welche Zielgruppe es gedacht ist (Schüler, Studierende, "Anwender", "Profi-Anwender", Übersetzer) (Zielgruppe), wann es auf den Markt gebracht wurde (ErschDat), wieviele Seiten es hat (AnzSeit). |
|
Das Wort "auch" macht deutlich, dass es sich um eine Variante handelt, die evtl. zusätzliche Attribute hat. Dies ist hier auch der Fall, so dass eine Spezialisierung für gedruckte Wörterbücher eingerichtet werden muss. Sie wird WBGedr genannt und hat (erstmal) die folgenden Attribute. |
|
WBGedr (#ProdNr, Einträge, Zielgruppe, ErschDat, AnzSeiten) |
|
Anforderung 3 |
|
Für jedes digitale Wörterbuch wird auch festgehalten, wann es auf den Markt gebracht wurde (ErschDat), welche Speichertechnik (SpeichTech) bei ihm verwendet wurde, wieviele Einträge es umfasst (Einträge) und für welche Zielgruppe es gedacht ist (Schüler, Studierende, "Anwender", "Profi-Anwender", Übersetzer) (Zielgruppe). |
Generalisierung / Spezialisierung |
Wieder taucht in der Anforderungsformulierung das Wort "auch" auf. Die neue Produktvariante hat dann auch eine Spezialisierung: Digitale Wörterbücher. Diese Relation wird WBDig genannt: |
|
WBDig (#ProdNr, Einträge, Zielgruppe, ErschDat, SpeichTech) |
|
Da in WBDig zum Teil dieselben Attribute wie in WBGedr vorliegen, kann eine Generalisierung dieser beiden Relationen mit Einträge, ErschDatum und Zielgruppe gebildet werden. Dieses Muster Gen/Spez muss man nun erkennen, z.B. anhand der Semantik ("Ähnlichkeit") oder der identischen Attribute. Die Bereinigung ergibt eine Relation für Wörterbücher und je eine "abgeschlankte" für die digitalen und gedruckten Wörterbücher. |
|
Damit entstehen folgende neue bzw. veränderte Relationen: |
|
WB (#ProdNr, Einträge, Zielgruppe, ErschDat) |
|
WBDig (#ProdNr, SpeichTech) |
|
WBGedr (#ProdNr, AnzSeiten) |
|
WB ist Spezialisierung von Produkte, WBDig und WBGedr sind Spezialisierungen von WB. Von der Generalisierung ausgehend ist die Kardinalität 1:1 und die Min-/Max-Angaben sind 0,1 : 1,1. |
|
Will man eine nicht simple Gen/Spez-Struktur durchdringen, lohnt sich die Anlage einer Tabelle mit den Attributen der beteiligten Relationen, wie es die folgenden Abbildungen zeigen. In der Kopfzeile sind die einzelnen Produkte angesiedelt, darunter zeilenweise die Attribute. Die obersten Zeilen geben die Attribute an, die alle Produkte haben, darunter dann die für die einzelnen Spezialisierungen. |
|
Gen/Spez-Tabelle 1: Produkte und ihre Spezialisierungen - Version 1-A |
|
Produkte |
WB |
WBGedr |
WBDig |
ProdNr |
ProdNr |
ProdNr |
ProdNr |
Bez |
Bez |
Bez |
Bez |
LPreis |
LPreis |
LPreis |
LPreis |
Sprache1 |
Sprache1 |
Sprache1 |
Sprache1 |
Sprache2 |
Sprache2 |
Sprache2 |
Sprache2 |
|
Einträge |
Einträge |
Einträge |
|
Zielgruppe |
Zielgruppe |
Zielgruppe |
|
ErschDat |
ErschDat |
ErschDat |
|
|
AnzSeiten |
|
|
|
|
SpeichTech |
| |
Schon diese Tabelle zeigt die Gen/Spez-Struktur auf. Noch übersichtlicher wird es, wenn man in jeder Spalte die Attribute weg lässt, die in der übergeordneten Generalisierung enthalten sind: |
|
Gen/Spez-Tabelle 1: Produkte und ihre Spezialisierungen - Version 1-B |
|
Produkte |
WB |
WBGedr |
WBDig |
ProdNr |
|
|
|
Bez |
|
|
|
LPreis |
|
|
|
Sprache1 |
|
|
|
Sprache2 |
|
|
|
|
Einträge |
|
|
|
Zielgruppe |
|
|
|
ErschDat |
|
|
|
|
AnzSeiten |
|
|
|
|
SpeichTech |
| |
Hier ist jetzt der Spezialisierungszusammenhang klar erkennbar. WBDig "erbt", wie es in der objektorientierten Programmierung genannt wird, die Attribute von WB und von Produkte. |
|
Anforderung Teil 4 |
|
Die digitalen Produkte des Verlags beruhen jeweils auf einem Übersetzungsprogramm (BezProg). Es kann sein, dass eines mit verschiedenen Programmen angeboten wird (z.B. zielgruppenspezifisch). Natürlich dient ein Programm u.U. mehreren digitalen Produkten. Für diese Programme wird festgehalten, welche Dokumentarten (DokArt) sie auswerten können (Word, PDF, Bildformate, usw.; mehrere) und ob es möglich ist, die Programmleistung in Textprogramme zu integrieren (IBK: Integrierbarkeit). |
Digitale Produkte |
Anforderung 4 beschreibt die digitalen Produkte näher. Der erste Teil legt außerdem auch eine n:m-Beziehung zwischen Produkten und Programmen fest, so dass sich die Relation ProdDig ergibt. Die Programme werden durch die beiden Attribute DokArt und IBK datenbanktechnisch existent, wegen der n:m-Beziehung zwischen Programmen und Dokumentart sogar in zwei Relationen. |
|
Damit kommen folgende Relationen dazu: |
|
Programme (#BezProg, IBK) |
|
ProgDokArt (#(BezProg, DokArt)) |
|
ProdDig (#(ProdNr, BezProg)) |
|
Die Kardinalitäten und Min-/Max-Angaben sind wie folgt: |
|
- Von Produkte zu ProdDig: 1:n bzw. 0,n : 1,1
- Von Programme zu ProdDig: 1:n bzw. 0,n : 1,1, da wir davon ausgehen, dass es auch (datenbanktechnisch) Programme geben kann, die noch nicht in einem digitalen Produkt verarbeitet sind.
- Von Programme zu ProgDokArt: 1:n bzw. 0,1 : 1,n.
|
|
Anforderung Teil 5 |
|
Für jeden Volltextübersetzer wird auch festgehalten, welche Sprachen abgedeckt sind, wieviele Einträge das Systemlexikon hat (Einträge), für welche Zielgruppe das Produkt gedacht ist und wann es auf den Markt gebracht wurde (ErschDatum). Festgehalten wird außerdem, ob man den Käufern anbietet, es durch Internetzugriffe regelmäßig aktualisieren zu lassen. Falls ja, wie lange dies möglich ist (AktJahre), z.B. 5 Jahre ab Kauf. |
|
2.8.3 Lösung durch Umbenennung |
|
Die Beschreibung der Produkte geht damit weiter und die Volltextübersetzer (VTÜ) werden als Relation eingeführt. Die hier genannten Attribute der Volltextübersetzer sind aber bis auf eines in WB enthalten. Deshalb ändern wir den Namen von WB in WB+VTÜ (Wörterbücher und Volltextübersetzer). Dies ist eine pragmatische aber angemessene Lösung, denn normalerweise gibt es keine zwei Relationen mit identischem Schlüssel. Für die Volltextübersetzer mit Aktualisierungsmöglichkeit wird eine neue Relation VTÜAkt angelegt: |
|
WB+VTÜ (#ProdNr, Einträge, Zielgruppe, ErschDat) |
|
VTÜAkt (#ProdNr, AktJahre) |
|
Auch die Gen/Spez-Tabelle ändert sich damit (die bei den anderen Produkten vorkommenden Attribute wurden gleich weggelassen): |
|
Gen/Spez-Tabelle 2: Produkte und ihre Spezialisierungen |
|
Produkte |
WB+VTÜ |
WBGedr |
WBDig |
VTÜAkt |
ProdNr |
|
|
|
|
Bez |
|
|
|
|
LPreis |
|
|
|
|
Sprache1 |
|
|
|
|
Sprache2 |
|
|
|
|
|
Einträge |
|
|
|
|
Zielgruppe |
|
|
|
|
ErschDat |
|
|
|
|
|
AnzSeiten |
|
|
|
|
|
SpeichTech |
|
|
|
|
|
AktJahre |
| |
Um nicht den Überblick zu verlieren und um die Gen/Spez-Struktur ganz deutlich zu machen, hier die an diesem Fragment beteiligten Relationen, textlich und grafisch. |
|
Produkte (#ProdNr, Bez, Lpreis, Sprache1, Sprache2) |
|
VTÜAkt (#ProdNr, AktJahre) |
|
WB+VTÜ (#ProdNr, Einträge, Zielgruppe, ErschDat) |
|
WBDig (#ProdNr, SpeichTech) |
|
WBGedr (#ProdNr, AnzSeiten) |
|
Die Kardinalitäten und Min-/Max-Angaben sind damit jetzt wie folgt: |
|
- Von WB+VTÜ zu WBGedr: 1:1 bzw. 0,1 : 1,1
- Von WB+VTÜ zu WBDig: 1,1 bzw. 0,1 : 1,1
- Von WB+VTÜ zu VTÜAkt: 1,1 bzw. 0,1 : 1,1
- Von Produkte zu WB+VTÜ: 1,1 bzw. 0,1 : 1,1. Wir lassen also datenbanktechnisch Produkte zu, die weder Wörterbücher (WB) noch Volltextübersetzer (VTÜ) sind.
|
|
|
|
Abbildung 2.8-1: Generalisierung / Spezialisierung rund um Produkte |
|
Anforderung Teil 6 |
|
Für alle Programme werden außerdem die Softwarehäuser, die an der Erstellung mitgearbeitet haben, mit ihrer Anschrift (nur die Zentrale) festgehalten. Es wird auch die zentrale E-Mail-Adresse erfasst. Es kommt durchaus vor, dass ein Programm in Kooperation von mehreren Softwarehäusern erstellt wird. Natürlich bietet ein bestimmtes Softwarehaus u.U. mehrere Programme an, z.B. für verschiedene Sprachen. Es wird bzgl. eines jeden Programms der Beginn und das Ende der Zusammenarbeit vermerkt. |
|
Hier werden nun die Softwarehäuser zu Datenbankobjekten. Da für sie gleich auch noch Attribute vorliegen, kann eine Relation angelegt werden. Außerdem auch für die Beziehung zwischen den Softwarehäusern und den Programmen. Diese ist vom Typ n:m und hat eine Zeitkomponente (Zeitabschnitte). Es genügt, den Beginn der Zusammenarbeit in den Schlüssel aufzunehmen, damit können mehrere solche Phasen unterschieden werden. Daraus folgen weitere Relationen: |
Zeitaspekt in Beziehung |
SWHäuser (#SWHNr, PLZ, Ort, Straße, eMail) |
|
SWHProg (#(SWHNr, BezProg, Beginn), Ende) |
|
Programme (#BezProg, IBK) |
|
Die Kardinalitäten und Min-/Max-Angaben sind wie folgt: Von Programme über SWHProg zu SWHäuser: n:m bzw. 1,n : 1,m |
|
Anforderung Teil 7 |
|
Für alle digitalen Produkte werden außerdem die Systemvoraussetzungen festgehalten, abhängig vom eingesetzten Programm. Welche minimale Hardwareanforderung gegeben ist (anhand des Prozessors, Proz), wieviel Arbeitsspeicher sie benötigen (ArbSp), wieviel freier Plattenspeicher (PlattSp) nötig ist (in MB) und welche Betriebssystemversion (BS) genutzt werden kann (Windows 7, 8, 10, 11; LINUX). Dies sind in der Regel mehrere. |
|
Zuerst scheint der Text eine Erweiterung der Beschreibung der digitalen Produkte zu enthalten. Die Formulierung "abhängig vom eingesetzten Programm" zeigt aber, dass Objekte gemeint sind, die durch die Kombination aus Produkt und Programm identifiziert sind. Deshalb wird die Relation ProdDig hier um die drei Attribute Proz, ArbSp und PlattSp ergänzt. |
|
Bleiben noch die Betriebssysteme. Da u.U. mehrere Betriebssysteme für ein digitales Produkt tauglich sind, muss eine Relation erstellt werden, die das Attribut BS mit im Schlüssel hat: ProdDigBS. Dadurch kommt es zu einer eher seltenen Konstellation: einem Fremdschlüssel, der aus zwei Attributen besteht. ProdDig hat den Schlüssel #(ProdNr, BezProg), ProdDigBS den Fremdschlüssel (ProdNr, BezProg). Zusammen mit Programme liegen dann folgende geänderten und neuen Relationen vor: |
|
ProdDig (#(ProdNr, BezProg), Proz, ArbSp, PlattSp) |
|
ProdDigBS (#((ProdNr, BezProg), BS) //innere Klammer nur wegen derAnschaulichkeit |
|
Programme (#BezProg, IBK) |
|
Die Kardinalitäten und Min-/Max-Angaben sind wie folgt: Von ProdDig zu ProdDigBS: 1:n bzw. 1,n : 1,m |
|
Anforderung Teil 8 |
|
Erfasst werden auch die konkreten Geräte, auf denen die digitalen Produkte lauffähig sind mit ihrer Bezeichnung (Bez) und dem Gerätetyp (Typ; Smartphone, Pad, Tablett, Laptop, usw.). Auf einem Gerät sind natürlich mehrere digitale Produkte lauffähig, dagegen werden die digitalen Produkte am Ende ihrer Entwicklung auf genau ein Gerät zugeschnitten. Besteht das jeweilige Gerät nicht mehr, wird auch das zugehörige digitale Produkt überflüssig. |
|
Damit ergibt sich eine Relation zu Geräten. Außerdem kann die Gerätebezeichnung als Teilschlüssel in den Schlüssel von ProdDig aufgenommen werden, denn ein Gerät ist auf mehreren digitalen Produkten lauffähig. Dies führt zu neuen bzw. veränderten Relationen: |
|
Geräte (#Bez, Typ) |
|
ProdDig (#(ProdNr, BezProg, BezGerät), Proz, ArbSp, PlattSp) |
|
Ist das wirklich korrekt? Bei näherem Hinsehen entsteht ein leichtes Unbehagen. Wird nicht Proz, ArbSp und PlattSp alleine durch ProdNr und BezProg bestimmt? Was tut dann, diesbezüglich, BezGerät im Schlüssel. Würden die drei beschreibenden Geräte auch durch das jeweilige Gerät mit bestimmt, wäre das in Ordnung. Nach der Beschreibung ist dies aber nicht anzunehmen. Der Bedarf an Hardwarekapazitäten wird wohl geräteunabhängig bestimmt. Um ein solches Unbehagen zu beseitigen, ist ein FA-Diagramm gut geeignet: |
Unbehagen |
|
|
Abbildung 2.8-2: FA-Diagramm der Relation ProdDig_1NF |
|
Das macht die Problematik klar. Die Relation ist nicht mal in 2NF. Deshalb muss normalisiert werden. Es entstehen die folgenden Relationen (als FA-Diagramme). |
|
|
|
Abbildung 2.8-3: FA-Diagramm der Relationen ProdProgGer_5NF und ProdDig_5NF |
|
Damit ergibt sich eine veränderte Relation ProdDig (die der "vorletzten" Fassung entspricht) und eine neue Relation zu der Beziehung von Produkten, Programmen und Geräten. Sie hält fest, in welcher konkreten Konstellation die drei Komponenten zusammengefügt werden können: |
|
ProdDig (#(ProdNr, BezProg), Proz, ArbSp, PlattSp) |
|
ProdProgGer (#(ProdNr, BezProg, BezGerät)) |
|
Es soll an dieser Stelle nicht verschwiegen werden, dass ProdProgGer in der Praxis ein Kandidat für die Einführung eines Schlüssels wäre, der in seiner Zusammensetzung die jeweils konkrete Konstellation ausdrückt, z.B. PPGId (ProduktProgrammGerätId). Dann würden die drei Attribute a) zu einem Sekundärschlüssel und b) zu beschreibenden Attributen: |
Konstruierter Schlüssel. |
ProdProgGer-Alternative (#PPGId, (ProdNr, BezProg, BezGerät)) |
|
Wir belassen es hier aber bei der obigen Lösung, so dass sich folgende Relationen ergeben: |
|
Geräte (#Bez, Typ) |
|
ProdDig (#(ProdNr, BezProg), Proz, ArbSp, PlattSp) |
|
ProdProgGer (#(ProdNr, BezProg, BezGerät)) |
|
Betrachten wir noch die Kardinalitäten und Min-/Max-Angaben: |
|
- Für Produkte - ProdProgGer - Geräte ergibt sich die Kardinalität n:m und die Min-/Max-Angaben 1,n : 1,n, wenn wir festlegen, dass nur Produkte bzw. Geräte datenbankmäßig erfasst werden, die auch zum Einsatz kommen.
|
|
Anforderung Teil 9 |
|
Die Entwicklung der Programme findet so statt, dass jedes Programm mit unterschiedlichen grafischen Bedienoberflächen (GUI; graphical user interface) kombiniert werden kann. Für die GUIs wird ein Schlüssel (GUIId), der Typ (Fenster, Kacheln, ...) und die Programmiersprache (PS), mit der sie entwickelt wurde, festgehalten. Ein konkretes vom jeweiligen Softwarehaus angebotenes Programm enthält dann genau eine GUI, d.h. die Programme sind nach ihren grafischen Bedienoberflächen differenziert. |
|
Nun wird die Einbindung der grafischen Bedienoberflächen (Graphical User Interface, GUI) in das Datenmodell geklärt. Sie werden durch Identifikation und Beschreibung datenbanktechnisch existent in der Relation GUI. Dem Text kann außerdem entnommen werden, dass ein bestimmtes Programm genau eine ganz bestimmte GUI hat, so dass hier eine 1:n-Beziehung vorliegt. Entsprechend wird der Schlüssel von GUI in Programme als Fremdschlüssel eingefügt: |
|
GUI (#GUIId, Typ, PS) |
|
Programme (#BezProg, IBK, GUIId) |
|
2.8.4 Lösungen |
|
Textliche Fassung |
|
Geräte (#Bez, Typ) |
|
GUI (#GUIId, Typ, PS) |
|
Programme (#BezProg, IBK, GUIId) |
|
ProdDig (#(ProdNr, BezProg), Proz, ArbSp, PlattSp) |
|
ProdDigBS (#((ProdNr, BezProg), BS) |
|
ProdProgGer (#(ProdNr, BezProg, BezGerät)) |
|
Produkte (#ProdNr, Bez, LPreis, Sprache1, Sprache2) |
|
ProgDokArt (#(BezProg, DokArt)) |
|
SWHäuser (#SWHNr, PLZ, Ort, Straße, eMail) |
|
SWHProg (#(SWHNr, BezProg, Beginn), Ende) |
|
VTÜAkt (#ProdNr, AktJahre) |
|
WB+VTÜ (#ProdNr, Einträge, Zielgruppe, ErschDat) |
|
WBDig (#ProdNr, SpeichTech) |
|
WBGedr (#ProdNr, AnzSeiten) |
|
|
|
Grafische Fassung |
|
|
|
Abbildung 2.8-4: Relationales Datenmodell Sprachenverlag |
|
Abkürzungen für Attribute: |
|
AktJahr: Zahl der Jahre, in denen das Programm aktualisiert wird |
|
ArbSp: Arbeitsspeicher |
|
BS: Bezeichnung Betriebssystemversion |
|
ErschDatum: Erscheinungsdatum |
|
Geräte.Bez: Bezeichnung des Geräts |
|
Geräte.Typ: Gerätetyp |
|
GUI.Typ: Typ der grafischen Bedienoberfläche |
|
GUIId: Schlüssel für die grafische Bedienoberfläche |
|
LPreis: Listenpreis |
|
PlattSp: Speichergröße der Festplatte |
|
ProdDig.BezProg: Bezeichnung des Übersetzungsprogramms |
|
ProdNr : Produktnummer |
|
Produkte.Bez: Bezeichnung Produkt |
|
Proz: Bezeichnung des Prozessors bei digitalen Produkten |
|
PS: Programmiersprache, mit der die GUI entwickelt wurde |
|
SWHProg.Beginn: Beginn der Zusammenarbeit |
|
SWHProg.Ende: Ende der Zusammenarbeit |
|
WBVTÜ. Einträge: Zahl der Einträge in gedruckten Wörterbüchern und Volltextübersetzern |
|
Zielgruppe: anvisierte Kundengruppe |
|
|
|
Abkürzungen für Relationen: |
|
Geräte: Geräte, auf denen das digitale Produkt einsetzbar ist |
|
GUI: grafische Bedienoberfläche |
|
ProdDig: digitale Produkte |
|
ProdDigBS: digitale Produkte in Kombination mit Betriebssystemen |
|
ProdProgGer: Kombination Produkte - Programme - Geräte |
|
Produkte: die vom Sprachenverlag hergestellten Produkte |
|
ProgDokArt: Dokumentarten, die von den Programmen ausgewertet werden können |
|
Programme: die eingesetzten Programme |
|
SWHäuser: Softwarehäuser, die mit dem Sprachenverlag zusammenarbeiten |
|
SWHProg: Kombination Softwarehäuser und Programme |
|
VTÜAkt: Angabe zur Aktualisierung bei Volltextübersetzern |
|
WB+VTÜ: Attribute zu Volltextübersetzern und Wörterbüchern |
|
WBDig: digitale Wörterbücher |
|
WBGedr: Gedruckte Wörterbücher |
|
2.9 Lehre 1 |
|
Aufgabenstellung: Prof. Dr. Josef L. Staud |
|
Lösung: stud. oec. inf. Karolin Staud |
|
2.9.1 Anforderungsbeschreibung |
|
Für den Lehrbetrieb einer Hochschule soll eine Datenbank erstellt werden. Dazu wird ein relationales Datenmodell erstellt, für das die folgenden Anforderungen festgelegt wurden. Zu erfassen sind: |
|
(1) Lehrveranstaltungen: Jede Veranstaltung mit einer identifizierenden Nummer (LVNr), Bezeichnung (BezLV), der Zahl der Semesterwochenstunden (SWS) und in welchem Semster sie nach der SPO angeboten werden müssen (SemPlan).
|
|
(2) Studierende mit Matrikelnummer (MatrNr), Namen, Vornamen (VName) und einem E-Mail-Postfach (E-Mail).
|
|
(3) Der Besuch von Lehrveranstaltungen durch Studierende. Es kommt durchaus vor, dass ein Studierender eine bestimmte Lehrveranstaltung mehrfach besuchen muss.
|
|
(4) Dozenten: Jeder Dozent, der Lehrveranstaltungen gibt, mit Namen und Vornamen.
|
|
(5) Die Lehrtätigkeit der Dozenten. Festgehalten wird, welcher Dozent eine bestimmte Veranstaltung in welchem Semester gehalten hat. An dieser (kleinen) Hochschule wird jede Veranstaltung pro Semester nur einmal gehalten. Allerdings kommt es vor, dass mehrere Dozenten in einem Semester zusammen eine Lehrveranstaltung durchführen.
|
|
2.9.2 Lösungsschritte |
|
Anforderung 1 |
|
Unschwer kann die erste Relation erkannt werden: Lehrveranstaltungen (LV). Sie werden identifiziert (LVNr) und beschrieben, sind also datenbanktechnisch relevant: |
|
LV (#LVNr, #BezLV, SWS, SemPlan) |
|
Da die Bezeichnung der Lehrveranstaltung auch eindeutig sein dürfte, wird BezLV zu einem Sekundärschlüssel. |
|
Anforderung 2 |
|
Hier werden die Studierenden angesprochen. Da ein Schlüssel vorliegt (MatrNr) und beschreibende Attribute, entsteht eine Relation: |
|
Studierende (#MatrNr, Name, VName, E-Mail) |
|
Anforderung 3 |
|
Für den Besuch von Lehrveranstaltungen (LVBesuch) müssen obige Relationen verknüpft werden. Geht man davon aus, dass Vorlesungen semesterweise besucht werden, ist die erste Lösung g wie folgt: |
|
LVBesuch (#(MatrNr, LVNr), Semester) |
|
Durch den Hinweis, dass Lehrveranstaltungen durchaus auch mehrfach besucht werden (müssen), ergibt sich aber eine Änderung. Das Attribut Semester muss in den Schlüssel, sonst wäre der Schlüssel im Fall von Wiederholungsn nicht eindeutig: |
|
LVBesuch (#(MatrNr, LVNr, Semester)) |
|
Anforderung 4 |
|
Die hier angesprochenen Dozenten können, wenn man einen Schlüssel ergänzt (DozNr), ebenfalls als Relation angelegt werden: |
|
Dozenten (#DozNr, Name, VName) |
|
Anforderung 5 |
|
Der abschließende Punkt betrifft die Lehrtätigkeit (Lehre). Gehen wir von der realistischen Annahme aus, dass ein Dozent keine (Freisemester), eine oder (meist) mehrere Lehrveranstaltungen gibt, ergibt sich folgende Lösung: |
|
Lehre ((DozNr, LVNr, Sem), . . .//Sem = Semester |
|
Wäre verlangt, dass eine bestimmte Lehrveranstaltung pro Semester vom selben Dozenten mehrfach gehalten werden kann, müsste die Relation verändert werden. |
|
Nun ist noch gefordert, dass auch der Fall erfasst wird, dass mehrere Dozenten zusammen eine Lehrveranstaltung durchführen. Dies ist mit obiger Relation möglich. Dann gibt es z.B. folgende Tupel: |
|
1007, DBS1, SS2023
|
|
1008, DBS1, SS2023
|
|
Die Lösung ist aber nur richtig, weil in der Anforderungsbeschreibung ausgeführt ist, dass in jedem Semester jede Vorlesung nur einmal gehalten wird. Das drücken auch die Min-/Max-Angaben aus: |
|
Min-/Max-Angaben für Dozenten - Lehre - LV: 0,n : 1,1 |
|
2.9.3 Lösung |
|
Textliche Fassung |
|
LV (#LVNr, #BezLV, SWS, SemPlan) |
|
Studierende (#MatrNr, Name, VName, E-Mail) |
|
LVBesuch (#(MatrNr, LVNr, Semester)) |
|
Dozenten (#DozNr, Name, VName) |
|
Lehre ((DozNr, LVNr, Sem)) |
|
|
|
Grafische Fassung |
|
|
|
Abbildung 2.9-1: Relationales Datenmodell Lehre 1 |
|
2.10 Lehre 2 |
|
Aufgabenstellung: Prof. Dr. Josef L. Staud |
|
Lösung: stud. oec. inf. Karolin Staud |
|
2.10.1 Anforderungsbeschreibung |
|
Diese Aufgabe baut auf obiger auf. Die zusätzlichen Anforderungen sind mit "ZUSÄTZLICH:" markiert. Entwerder also die obige Lösung übernehmen und als Ausgangsbasis nehmen oder einfach als Ganzes lösen. Erfasst weden sollen: |
|
(1) Lehrveranstaltungen: Jede Veranstaltung mit einer identifizierenden Nummer (LVNr), Bezeichnung (BezLV), der Zahl der Semesterwochenstunden (SWS) und in welchem Semster sie nach der SPO angeboten werden müssen (SemPlan).
|
|
(2) Studierende mit Matrikelnummer (MatrNr), Namen, Vornamen (VName) und einem E-Mail-Postfach (E-Mail). ZUSÄTZLICH: Von jedem Studierenden wird die Hauptadresse, die der Kommunikation mit der Hochschule dient, mit PLZ, Ort, Straße erfasst.
|
|
(3) Der Besuch von Lehrveranstaltungen durch Studierende. Es kommt durchaus vor, dass ein Studierender eine bestimmte Lehrveranstaltung mehrfach besuchen muss.
|
|
(4) Dozenten: Jeder Dozent, der Lehrveranstaltungen gibt, mit Namen und Vornamen. ZUSÄTZLICH: Für interne Dozenten wird noch festgehalten, in welchem Raum der Hochschule sie ihr Büro haben und wann ihre Sprechstunde ist. Für externe Dozenten wird festgehalten von welcher Organisation sie kommen (einem Unternehmen, einer anderen Hochschule, usw.).
|
|
(5) Die Lehrtätigkeit der Dozenten (Lehre). Festgehalten wird, welcher Dozent eine bestimmte Veranstaltung in welchem Semester gehalten hat. An dieser (kleinen) Hochschule wird jede Veranstaltung pro Semester nur einmal gehalten. Allerdings kommt es vor, dass mehrere Dozenten in einem Semester zusammen eine Lehrveranstaltung durchführen.
|
|
(6) ZUSÄTZLICH: Jede einzelne Veranstaltungsstunde (VTermine) mit Tag, Beginn, Ende und Raum. Als Schlüssel für die Termine dient eine Konstruktion aus Tag und Anfangszeit, also z.B. 20230602_0830 für eine Lehrveranstaltung, die am 2.6.2023 um 8.30 Uhr begann.
|
|
(7) ZUSÄTZLICH: Der Besuch der Veranstaltungstermine durch die Studierenden. An dieser Hochschule ist es üblich, die Anwesenheit zu kontrollieren. Deshalb wird für jeden Veranstaltungstermin einer Lehrveranstaltung festgehalten, welche Studierenden anwesend waren.
|
|
2.10.2 Lösungsschritte |
|
Anforderung 1 |
|
Unschwer kann die erste Relation erkannt werden: Lehrveranstaltungen (LV). Sie werden identifiziert (LVNr) und beschrieben, sind also datenbanktechnisch relevant: |
|
LV (#LVNr, #BezLV, SWS, SemPlan) |
|
Da die Bezeichnung der Lehrveranstaltung auch eindeutig sein dürfte, wird BezLV zu einem Sekundärschlüssel. |
|
Anforderung 2 |
|
Hier werden die Studierenden angesprochen. Da ein Schlüssel vorliegt (MatrNr) und beschreibende Attribute, entsteht eine Relation mit Name, VName und Email. Da von den Studierenden nur eine einzige Adresse erfasst wird, können die Adressinformkationen auch in diese Relation eingefügt werden. Somit entsteht: |
|
Studierende (#MatrNr, Name, VName, E-Mail, PLZ, Ort, Straße) |
|
Anforderung 3 |
|
Für den Besuch von Lehrveranstaltungen müssen obige Relationen verknüpft werden. Geht man davon aus, dass Vorlesungen semesterweise besucht werden, ist die Lösung wie folgt: |
|
LVBesuch (#(MatrNr, LVNr), Semester) |
|
Durch den Hinweis, dass Lehrveranstaltungen durchaus auch mehrfach besucht werden (müssen), ergibt sich aber eine Änderung. Das Attribut Semester muss in den Schlüssel, sonst wäre der Schlüssel nicht eindeutig: |
|
LVBesuch (#(MatrNr, LVNr, Semester)) |
|
Anforderung 4 |
|
Die hier angesprochenen Dozenten können, wenn man einen Schlüssel ergänzt (DozNr), ebenfalls als Relation angelegt werden: |
|
Dozenten (#DozNr, Name, VName) //vorläufig |
|
Nun werden aber für interne und externe Dozenten jeweils spezifische Attribute genannt. Das führt zu Spezialisierungen von Dozenten. Wird Dozenten in DozAllg (Dozenten allgemein) umbenannt und für die Spezialisierungen DozIntern und DozExtern eingeführt, entstehen folgende Relationen: |
|
DozAllg (#DozNr, Name, Vorname, Typ) |
|
DozIntern (#DozNr, EMail, BüroNr, SprStunde) |
|
DozExtern (#DozNr, Org) |
|
Das Attribut DozAllg.Typ wurde aus pragmatischen Gründen hinzugenommen. Es gibt an, ob der Dozent ein interner oder ein externer ist und erleichtert damit die Abfragen. |
|
Anforderung 5 |
|
Dieser Punkt betrifft die Lehrtätigkeit (Lehre). Dafür werden Dozenten und Lehrveranstaltungen verknüpft. Gehen wir von der realistischen Annahme aus, dass ein Dozent keine (Freisemester), eine oder (meist) mehrere Lehrveranstaltungen gibt, ist die Lösung wie folgt: |
|
Lehre ((DozNr, LVNr, Sem), . . .//Sem = Semester |
|
Die Min-/Max-Angaben für Dozenten - Lehre - LV sind 0,n : 1,1. |
|
Anforderung 6 - Termine! |
|
Neben den Lehrveranstaltungen ist auch die Erfassung der einzelnen Termine der Lehrveranstaltung gefordert. Entsprechend den Anforderungen wird für die Termine ein konstruierter Schlüssel TerminNr angelegt. Als beschreibende Attribute kommen Tag, Beginn, Ende und Raum hinzu: |
|
LVTermine (#TerminNr, Tag, Beginn, Ende, Raum, . . .//vorläufig |
|
Etwas wichtiges fehlt da noch, die Lehrveranstaltung um die es geht. Diese kann mit Hilfe der LVNr hinzugefügt werden. Dies sollte im Schlüssel geschehen, da es mit Sicherheit Lehrveranstaltungen gibt, die zum selben Zeitpunkt stattfinden. Die LVNr ist dann auch Fremdschlüssel. Damit ergibt sich: |
|
LVTermine (#TerminNr, LVNr), Tag, Beginn, Ende, Raum) //final |
|
Der konstruierte Schlüssel könnte aus der LVNr und zeitlichen Angaben bestehen. Also z.B. 1220_20230602_0830 für einen Lehrveranstaltungstermin mit der Nummer 1220, die am 2.6.2023 um 8.30 Uhr beginnt. Will man keinen konstruierten Schlüssel, könnte man den zeitlichen Aspekt mittels Tag und Beginn erfassen, insgesamt also zum Schlüssel #(LVNr, Tag, Beginn) finden. |
|
Anforderung 7 |
|
Hier soll auch noch der Besuch der Termine durch die Studierenden festgehalten werden ("Anwesenheitsliste"). Dafür muss eine Relation "Lehrveranstaltungsbesuchtermine" (LVBesTermine) angelegt werden. Als Attribute werden die TerminNr und die MatrNr. Benötigt. Es handelt sich um eine n:m-Beziehung, so dass folgende Relation entsteht: |
|
LVBesTermine (#(TerminNr, MatrNr)) |
|
Als Min-/Max-Angabe soll für "Studierende - LVBesTermine - LVTermine" 0,n : 3,n angenommen werden mit der Erkenntnis/Semantik: Es gibt Studierende, die gar keinen Termin wahrnehmen, ein Termin findet nur statt, wenn mindestens drei Studierende anwesend sind (zum Beispiel). |
|
2.10.3 Lösung |
|
Textliche Fassung |
|
DozAllg (#DozNr, Name, Vorname, Typ) |
|
DozExtern (#DozNr, Org) |
|
DozIntern (#DozNr, EMail, BüroNr, SprStunde) |
|
Lehre ((DozNr, LVNr, Sem) |
|
LV (#LVNr, #BezLV, SWS, SemPlan) |
|
LVBesTermine (#(TerminNr, MatrNr)) |
|
LVBesuch (#(MatrNr, LVNr, Semester)) |
|
LVTermine (#TerminNr, LVNr), Tag, Beginn, Ende, Raum) |
|
Studierende (#MatrNr, Name, VName, E-Mail, PLZ, Ort, Straße) |
|
|
|
Grafische Fassung |
|
|
|
Abbildung 2.10-1: Relationales Datenmodell Lehre 2 |
|
2.11 Lehre 3 |
|
Dies ist die umfangreichste Aufgabe zum Vorlesungsbetrieb an Hochschulen. Hier wird in den Lösungsschritten, stärker als oben, die schrittweise Entwicklung des Datenmodells anhand von Modellfragmenten dargestellt. Außerdem wird das Muster Generalisierung / Spezialisierung intensiv thematisiert. |
|
2.11.1 Anforderungsbeschreibung |
|
Hier wird der Anwendungsbereich Vorlesungsbetrieb einer Hochschule (HS) betrachtet. Folgendes soll erfasst werden: |
|
(1) Für die Lehrveranstaltungen eine Veranstaltungsnummer (LVNr), ihre Bezeichnung (BezLV), der Typ des zugehörigen Studienganges (Master, Bachelor, Diplom) (TypSG), die Bezeichnung des Studienganges (WI, AI, ...), der die Lehrveranstaltung durchführt (BezSG), die Credit Points (cp) und die Anzahl Semesterwochenstunden (SWS). Außerdem, in welchem Studiensemester die Lehrveranstaltung abzuhalten ist (SemPlan). Für jeden konkreten Termin der Lehrveranstaltungen wird festgehalten an welchem Tag er statt fand (Tag), wann er begann (Beginn) und wann er endete (Ende). Also z.B. Mittwochs, 8.00 - 9.30 Uhr. Die Räume werden ebenfalls erfasst, mit einer Typisierung (ArtRaum; DV-Raum, Vorlesungsraum, Labor, ...), der Größe (Groesse), der Ausstattung mit Beamern und Intranet (BeamerJN, IntranetJN) und dem Gebäude, in dem sie sich befinden (GebBez). Dabei geht man davon aus, dass in einem Semester eine Lehrveranstaltung immer in demselben Raum stattfindet. In verschiedenen Semestern kann die Lehrveranstaltung aber natürlich in jeweils anderen Räumen sein.
|
|
(2) Die Studierenden werden durch ihre Matrikelnummer (MatrNr), den Namen, Vornamen (VName) und ein E-Mail-Postfach (E-Mail) erfasst. Für sie wird außerdem festgehalten, in welchem Semester sie welche Lehrveranstaltung besucht haben. Es kommt durchaus vor, dass ein Studierender eine bestimmte Lehrveranstaltung mehrfach besuchen muss. Sozusagen in den "Stammdaten" der Studierenden ist außerdem vermerkt, wann das Studium begann (BegStudium), wann es endet(e) (EndeStudium), in welchem Studiengang (SG) sie eingeschrieben sind und in welchem Fachsemester sie sich befinden (FachSem). Für die Studierenden werden beliebig viele Adressen (PLZ, Ort, Strasse) zugelassen. Eine davon muss als die gekennzeichnet sein, zu der die Mitteilungen der Hochschule gesandt werden.
|
|
(3) Die Dozenten werden durch eine Dozentennummer (DozNr), den Namen, Vornamen (VName), die Anrede sowie ein E-Mail-Postfach erfasst. Für die Dozenten der Hochschule sollen zusätzlich auch die Nummer ihres Büros (BüroNr), ihre interne Telefonnummer (IntTel), ihre Sprechstunde (SprSt), ihre Fakultät und die Angabe des Gebäudes, in dem sich das Büro befindet (GebBez), angegeben werden. Für diese Gebäude wird noch festgehalten, in welchem Ort sie sich befinden (Ort), welche Straßenadresse sie haben (Straße, z.B. Hauptstr. 8) und welcher DV-Betreuer für das Gebäude zuständig ist (Straße, DVBetr). Es gibt an dieser Hochschule auch externe Dozenten. Für diese wird die Adresse erfasst (nur eine), welchen akademischen Abschluss sie haben (AkAb) und in welcher Organisation (Unternehmen, andere Hochschule, ...) welcher Branche sie arbeiten. Deren Adresse wird, für die Zusendung von Lehraufträgen usw., ebenfalls erfasst.
|
|
(4) Zum Lehrbetrieb soll in der Datenbank festgehalten werden, welcher Dozent welche Lehrveranstaltung gehalten hat. Üblicherweise hält ein Dozent mehrere Lehrveranstaltungen in einem Semester und dieselbe Lehrveranstaltung kann in verschiedenen Semestern von unterschiedlichen Dozenten gehalten werden. Kein Dozent hält in einem Semester eine Lehrveranstaltung mehrfach. Auch der Besuch von Lehrveranstaltungen durch Studierende wird mit Angabe des Semesters erfasst. Es soll möglich sein, dass ein Studierender mehrfach für eine Lehrveranstaltung eingeschrieben ist (Wiederholungen).
|
|
(5) Alle Prüfungen beziehen sich immer auf genau eine Lehrveranstaltung. Jeder wird eine Prüfungsnummer (PrüfNr) und eine Bezeichnung (Bez) zugewiesen. Bei allen Prüfungen wird der Prüfungstag festgehalten (Datum). Bei Klausuren (KL) und mündlichen Prüfungen (MP) auch die Länge. Bei mündlichen Prüfungen zusätzlich der Prüfer (dies ist immer nur genau einer; PrüfPersNr). Dieser kann interner oder auch externer Dozent sein. Praktische Arbeiten (PA) sind Leistungen wie Erstellung eines Datenmodells, Modellierung eines Prozesses, usw. Laborarbeiten (LA) sind solche, für die ein Labor und die Unterstützung des zuständigen Laborbetreuers benötigt wird. Beide finden in einem bestimmten Zeitraum statt, der ebenfalls in der Datenbank erfasst werden soll (Start, Ende). Bei Laborarbeiten sind zusätzlich die Laborbezeichnung (LabBez; EBUS-Labor, Mikrocomputerlabor, ERP-Labor, ...) und der Laborbetreuer mit Namen und Vornamen zu erfassen (LabBetrN, LabBetrVN).
|
|
(6) Der Besuch einer Prüfung bezieht sich immer auf eine Lehrveranstaltung. Festgehalten wird zu jeder Prüfung das Semester, in dem sie stattfindet (Sem), das genaue Datum, um welchen Versuch es sich handelt (1. Versuch, 2. Versuch, ...) und welche Note erzielt wurde.
|
|
2.11.2 Lösungsschritte |
|
Anforderung Teil 1 |
|
Für die Lehrveranstaltungen eine Veranstaltungsnummer (LVNr), ihre Bezeichnung (BezLV), der Typ des zugehörigen Studienganges (Master, Bachelor, Diplom) (TypSG), die Bezeichnung des Studienganges (WI, AI, ...), der die Lehrveranstaltung durchführt (BezSG), die Credit Points (cp) und die Anzahl Semesterwochenstunden (SWS). Außerdem, in welchem Studiensemester die Lehrveranstaltung abzuhalten ist (SemPlan). Für jeden konkreten Termin der Lehrveranstaltungen wird festgehalten an welchem Tag er war (Tag), wann er begann (Beginn) und wann er endete (Ende). Also z.B. Mittwochs, 8.00 - 9.30 Uhr. Die Räume werden ebenfalls erfasst, mit einer Typisierung (ArtRaum; DV-Raum, Vorlesungsraum, Labor, ...), der Größe (Groesse), der Ausstattung mit Beamern und Intranet (BeamerJN, IntranetJN) und dem Gebäude, in dem sie sich befinden (GebBez). Dabei geht man davon aus, dass in einem Semester eine Lehrveranstaltung immer in demselben Raum stattfindet. In verschiedenen Semestern kann die Lehrveranstaltung aber natürlich in jeweils anderen Räumen sein. |
|
Auf Grund der Beschreibung kann angenommen werden, dass es nicht um fixe Wochenpläne geht, sondern um flexible, also um Einzeltermine. Dass trotzdem die meisten dann in jeder Woche zum selben Zeitpunkt stattfinden, soll nicht stören. |
|
Die Lehrveranstaltungen (LV) selbst sind sofort als Relationen erkennbar, da sie identifiziert und durch zahlreiche Attribute beschrieben werden (mit BezLV, TypSG, BezSG, SemPlan, cp, SWS). Der Schlüssel ist LVNr. Für die Termine der Lehrveranstaltungen ergibt sich ein Schlüssel, wie er oft bei zeitlich fixierten Vorgängen auftritt. Der eigentliche Gegenstand, hier die Veranstaltungstermine, muss mit einem "Zeitstempel" versehen werden. Dabei genügen hier Tag und Beginn, da damit der Schlüssel eindeutig wird (LVTermine mit #(LVNr, Tag, Beginn), Ende). |
|
Auch die Räume sind oben angesprochen. Ihre Modellierung bereitet keine Probleme: (#RaumNr, ArtRaum, Groesse, BeamerJN, IntranetJN, GebBez). Bei den Gebäuden muss geprüft werden, ob sie später noch beschrieben werden. Da dies hier der Fall ist, wurde die Gebäudebezeichnung als Fremdschlüssel aufgenommen. |
|
Die Ausführungen in der Anforderung zu den Räumen für die Lehrveranstaltungen sind etwas unklar und müssen präzisiert werden. Nimmt man die Räume zu den Terminen hinzu entsteht Redundanz, denn es ist ja in einem Semester immer derselbe Raum, in dem die Lehrveranstaltung stattfindet. Deshalb muss eine eigene Relation eingerichtet werden, die an einer einzigen Stelle für eine Lehrveranstaltung und ein ganzes Semester den Raum mittels RaumNr festhält: LVRäume mit (#(LVNr, Sem), RaumNr). Das Attribut RaumNr stellt als Fremdschlüssel die Verknüpfung mit Räume her. |
|
Damit ergeben sich folgende Relationen: |
|
LV (#LVNr, BezLV, TypSG, BezSG, SemPlan, cp, SWS) |
|
LVRäume (#(LVNr, Sem), RaumNr) |
|
LVTermine (#(LVNr, Tag, Beginn), Ende) |
|
Räume (#RaumNr, ArtRaum, Groesse, BeamerJN, IntranetJN, GebBez) |
|
Die Kardinalitäten und Min-/Max-Angaben sind wie folgt (hier mal ausnahmsweise zusätzlich auch mit Einzelangaben zur n:m-Verknüpfung): |
|
- Von LV über LVRäume zu Räume: n:m bzw. 1,n : 0,n. Weil eine Lehrveranstaltung in mehreren Semestern in verschiedenen Räumen abgehalten werden kann und wenn wir annehmen, dass es auch Räume für Lehrveranstaltungen gibt, die noch nicht eingesetzt wurden.
- Von LV zu LVRäume: 1:m bzw. 1,n : 1,1 (Teil von oben).
- Von Räume zu LVRäume: 1:n bzw. 0,n : 1,1 (Teil von oben).
- Von LV zu LVTermine: 1:n bzw. 1,n : 1,1.
|
|
Die folgende Abbildung zeigt diesen Modellausschnitt in grafischer Form. |
|
|
|
Abbildung 2.11-1: Relationales Datenmodell HS - Ausschnitt Lehrveranstaltungen |
|
Nicht verwirren lassen: Die Beziehung LV - Räume ist hier nicht nur jeweils für ein Semester, sondern über die Semester hinweg erfasst. Deshalb n:m und nicht 1:n. |
|
Anforderung Teil 2 |
|
Die Studierenden werden durch ihre Matrikelnummer (MatrNr), den Namen, Vornamen (VName) und ein E-Mail-Postfach (E-Mail) erfasst. Für sie wird außerdem festgehalten, in welchem Semester sie welche Lehrveranstaltung besucht haben. Es kommt durchaus vor, dass ein Studierender eine bestimmte Lehrveranstaltung mehrfach besuchen muss. Sozusagen in den "Stammdaten" der Studierenden ist außerdem vermerkt, wann das Studium begann (BegStudium), wann es endet(e) (EndeStudium), in welchem Studiengang (SG) sie eingeschrieben sind und in welchem Fachsemester sie sich befinden (FachSem). Für die Studierenden werden beliebig viele Adressen (PLZ, Ort, Strasse) zugelassen. Eine davon muss als die gekennzeichnet sein, zu der die Mitteilungen der Hochschule gesandt werden. |
|
Hieraus ergeben sich mehrere Relationen. Die erste zu den Studierenden. Sie werden durch die Matrikelnummer identifiziert und durch die angegebenen weiteren Attribute beschrieben. Die Aufnahme von EndeStudium verstößt ja eigentlich gegen eine derGrundregeln relationaler Datenmodellierung (weil diese Angabe ja erst mal nicht zur Verfügung steht), wird aber aus pragmatischen Gründen akzeptiert: (#MatrNr, Name, VName, E-Mail, BegStudium, EndeStudium, SG, FachSem). |
|
Die zweite erfasst den Besuch von Lehrveranstaltungen. Es ist eine n:m-Verknüpfung, so dass eine Verbindungsrelation entsteht (LVBesuch), allerdings mit einem zusätzlichen Zeitstempel, der Semesterangabe (Sem). |
|
Abschließend werden oben die Adressangaben der Studierenden angesprochen. Der Text lässt auf eine 1:n-Beziehung zwischen Studierenden und Adressen schließen. Da aber unter einer Adresse auch mehrere Studierende wohnen können (Wohnheim, Wohngemeinschaft), gilt auch umgekehrt eine 1:n-Beziehung. Insgesamt ensteht also also eine n:m-Beziehung. Diese führt zur Relation StudAdr. Mit dem Attribut Art kann festgehalten werden, ob es sich um die Adresse für die Mitteilungen an die Studierenden handelt. |
|
Die neuen Relationen: |
|
Studierende (#MatrNr, Name, VName, E-Mail, BegStudium, EndeStudium, SG, FachSem) |
|
LVBesuch (#(MatrNr, LVNr, Sem)) |
|
Adressen (#AdrNr, Ort, PLZ, Strasse) |
|
StudAdr (#(MatrNr, AdrNr), Art) |
|
Nehmen wir LV dazu, sind die Kardinalitäten und Min-/Max-Angaben wie folgt: |
|
- Von Studierende über LVBesuch zu LV: n:m bzw. 0,n : 3,n. Wenn man annimmt, dass ein Studierender auch mal keine Lehrveranstaltung besucht und dass eine Lehrveranstaltung nur durchgeführt wird, wenn mindestens drei Studierende anwesend sind.
- Von Studierende über StudAdr zu Adressen: n:m bzw. 1,n : 1,m.
|
|
Die folgende Abbildung zeigt diesen Ausschnitt des Datenmodells: |
|
|
|
Abbildung 2.11-2: Relationales Datenmodell HS - Auschnitt Studierende und Lehrveranstaltungen |
|
Anforderung Teil 3 |
|
Die Dozenten werden durch eine Dozentennummer (DozNr), den Namen, Vornamen (VName), die Anrede sowie ein E-Mail-Postfach erfasst. Für die Dozenten der Hochschule sollen zusätzlich auch die Nummer ihres Büros (BüroNr), ihre interne Telefonnummer (IntTel), ihre Sprechstunde (SprSt), ihre Fakultät und die Angabe des Gebäudes, in dem sich das Büro befindet (BezGeb), angegeben werden. Für diese Gebäude wird noch festgehalten, in welchem Ort sie sich befinden (Ort), welche Straßenadresse sie haben (Straße, z.B. Hauptstr. 8) und welcher DV-Betreuer für das Gebäude zuständig ist (Straße, DVBetr). Es gibt an dieser Hochschule auch externe Dozenten. Für diese wird die Adresse erfasst (nur eine), welchen akademischen Abschluss sie haben (AkAb) und in welcher Organisation (Unternehmen, andere Hochschule, ...) welcher Branche sie arbeiten. Deren Adresse wird, für die Zusendung von Lehraufträgen usw., ebenfalls erfasst. |
|
Dozenten mit Generalisierung / Spezialisierung. Die Lehrkräfte der Hochschule erscheinen hier als externe und interne Dozenten. Da es Attribute für alle Dozenten gibt und spezifische für die beiden Untergruppen liegt eine Generalisierung / Spezialisierung vor. Die gemeinsamen Attribute sind Name, VName, Anrede und E-Mail, sie kommen in die Generalisierung (DozAllgemein). |
|
Den externen Dozenten (DozExt) wird nach Übernahme eines Lehrauftrags eine Dozentennummer (DozNR) zugewiesen. Diese entspricht modelltechnisch der Personalnummer (DozExtern) der internen Dozenten (DozHS). Für die externen Dozenten wird neben dem akademischen Abschluss (AkAb) eine einzige Adresse erfasst, somit genügt für das Festhalten der Adresse ein Fremdschlüssel in der Relation (AdrNr). Für die Organisationszugehörigkeit wird ebenfalls ein Fremdschlüssel (OrgNr) angelegt (zur Organisation vgl. unten). Bei den Dozenten der Hochschule wird angenommen, dass sie nur ein einziges Büro haben. Dessen Gebäude kann als Fremdschlüssel in DozHS erfasst werden. |
|
Alle drei Relationen zu Dozenten erhalten denselben Schlüssel. Dies ist bei einer Generalisierung / Spezialisierung immer der Fall und wirkt auf den ersten Blick befremdlich, da im allgemeinen in der relationalen Modellierung gilt: Es gibt keine Relationen mit demselben Schlüssel. Dies ist eine der Ausnahmen. |
|
Auch die Gebäude können mit einem Schlüssel (#BezGeb), dem Ort und der Straße sowie dem zuständigen DV-Betreuer (DVBetr) erfasst werden. |
|
Bleiben noch die Organisationen. Sie haben eine Bezeichnung und eine Adresse, Außerdem wird ihre Branche festgehalten und ein Schlüssel (OrgNr) vergeben. Damit kann eine Relation Organisationen angelegt werden. Mit dem Fremdschlüssel AdrNr wird diese Relation mit der zu den Adressen verknüpft. |
|
Die neuen Relationen und ihr Umfeld: |
|
DozAllg (#DozNr, Name, VName, Anrede, E-Mail) |
|
DozExt (#DozNr, AkAb, OrgNr, AdrNr) |
|
DozHS (#DozNr, Fakultät, BüroNr, BezGeb, IntTel, SprSt, E-Mail) |
|
Gebäude (#BezGeb, Ort, Straße, DVBetr) |
|
Räume (#RaumNr, ArtRaum, Groesse, BeamerJN, IntranetJN, GebBez) |
|
Organisationen (#OrgNr, Bez, AdrNr, Branche) |
|
Adressen (#AdrNr, Ort, PLZ, Strasse) |
|
Die Kardinalitäten und Min-/Max-Angaben sind wie folgt: |
|
- Von DozAllg zu DozExt: 1:1 bzw. 0,1 : 1,1. Genauso für DozAllg zu DozHS.
- Von Gebäude zu DozHS: 1:n, bzw. 0,n : 1,1.
- Von Organisationen zu DozExt: 1:n bzw. 1,n : 0,1. Wenn man festlegt, dass eine Organisation nur erfasst wird, wenn sie mindestens einen Dozenten "schickt" und nicht jeder externe Dozent von einer Organiation kommt ("Privatier").
- Von Adressen zu Organisationen: 1:1 bzw. 0,1 : 1,1 1:1 bzw. 0,1 : 1,1.
- Von Gebäude zu Räume: 1:n bzw. 1,n : 1,1
|
|
Hier die grafische Fassung dieses Modellausschnitts: |
|
|
|
Abbildung 2.11-3: Relationales Datenmodell HS - Auschnitt Dozenten |
|
Anforderung Teil 4 |
|
Zum Lehrbetrieb soll in der Datenbank festgehalten werden, welcher Dozent welche Lehrveranstaltung gehalten hat. Üblicherweise hält ein Dozent mehrere Lehrveranstaltungen in einem Semester und dieselbe Lehrveranstaltung kann in verschiedenen Semestern von unterschiedlichen Dozenten gehalten werden. Kein Dozent hält in einem Semester eine Lehrveranstaltung mehrfach. Auch der Besuch von Lehrveranstaltungen durch Studierende wird mit Angabe des Semesters erfasst. Es soll möglich sein, dass ein Studierender mehrfach für eine Lehrveranstaltung eingeschrieben ist (Wiederholungen). |
|
Der Lehrbetrieb wird einfach durch eine Verbindungsrelation mit Angabe des Semesters erfasst. Mit dieser Lösung kann ein Dozent mehrere Lehrveranstaltungen pro Semester halten (was ja meist der Fall ist) und dieselbe Lehrveranstaltung kann in einem Semester von mehreren Dozenten gehalten werden, was allerdings normalerweise nicht der Fall ist. Genau gleich ist die Lösung für den Besuch von Lehrveranstaltungen. Durch das Schlüsselattribut Semester sind auch Wiederholungen erfassbar. |
|
Damit ergeben sich folgende neuen Relationen mit "Zeitstempel": |
|
Lehrbetrieb (#(DozNr, VeranstNr, Sem)) |
|
LVBesuch (#(MatrNr, LVNr, Sem)) |
|
Die Kardinalitäten und Min-/Max-Angaben sind wie folgt: |
|
- Von LV über Lehrbetrieb zu DozAllg: n:m bzw. 1,n : 0,n. Da ein neuer Dozent auch erfasst werden soll, bevor er oder sie die erste Lehrveranstaltung hält.
- Von LV über LVBesuch zu Studierende: n:m, bzw. 3,n : 0,n. Da eine Lehrveranstaltung mindestens drei Teilnehmer braucht und Studierende zu Beginn des Studiums noch keine LV besucht haben.
|
|
Für die grafische Gestaltung vgl. das Gesamtmodell. |
|
Anforderung Teil 5 |
|
Alle Prüfungen beziehen sich immer auf genau eine Lehrveranstaltung. Jeder wird eine Prüfungsnummer (PrüfNr) und eine Bezeichnung (Bez) zugewiesen. Bei allen Prüfungen wird der Prüfungstag festgehalten (Datum). Bei Klausuren (KL) und mündlichen Prüfungen (MP) auch die Länge. Bei mündlichen Prüfungen zusätzlich der Prüfer (dies ist immer nur genau einer; PrüfPersNr). Dieser kann interner oder auch externer Dozent sein. Praktische Arbeiten (PA) sind Leistungen wie Erstellung eines Datenmodells, Modellierung eines Prozesses, usw. Laborarbeiten (LA) sind solche, für die ein Labor und die Unterstützung des zuständigen Laborbetreuers benötigt wird. Beide finden in einem bestimmten Zeitraum statt, der ebenfalls in der Datenbank erfasst werden soll (Start, Ende). Bei Laborarbeiten sind zusätzlich die Laborbezeichnung (LabBez; EBUS-Labor, Mikrocomputerlabor, ERP-Labor, ...) und der Laborbetreuer mit Namen und Vornamen zu erfassen (LabBetrN, LabBetrVN). |
|
. Auch bei den Prüfungen zeichnet sich eine Generalisierung / Spezialisierung ab. Alle erhalten eine Prüfungsnummer (PrüfNr), eine Bezeichnung (Bez), ein Prüfungsdatum (Datum) und den Verweis auf die Lehrveranstaltung , auf die sie sich beziehen. Da sich jede Prüfung auf genau eine Lehrveranstaltung bezieht, ist diese Lösung mit einem Fremdschlüssel korrekt. Für die Klärung der Gen/Spez-Hierarchie wird eine Tabelle erstellt, genau nach den oben formulierten Anforderungen. |
Mehrstufige Gen/Spez zu Prüfungen |
Prüfungsunterschiede |
|
Klausuren (KL) |
Mündliche Prüfungen (MP) |
Praktische Arbeit (PA) |
Laborarbeit (LA) |
PrüfNr |
PrüfNr |
PrüfNr |
PrüfNr |
Bez |
Bez |
Bez |
Bez |
Datum |
Datum |
Datum |
Datum |
Versuch |
Versuch |
Versuch |
Versuch |
Länge |
Länge |
|
|
|
|
Start |
Start |
|
|
Ende |
Ende |
|
PrüfPersNr |
|
|
|
|
|
LabBez |
|
|
|
LabBetrN |
|
|
|
LabBetrVN |
| |
Damit sind die Spezialisierungen klar. PrüfAllg ist die "oberste" Generalisierung und enthält die Attribute, die alle Relationen aufweisen. Dazu gehört auch ein Fremdschlüssel für die zugehörige Lehrveranstaltung (LVNr). Die ersten Spezialisierungen sind PrüfPALA für die gemeinsamen Attribute von PA und LA (Start und Ende) sowie PrüfKLMP für das gemeinsame Attribut von KL und MP (Länge). Es folgen die Spezialisierungen PrüfLA von PrüfPALA und PrüfMP von PrüfKL+MP. PrüfLA erhält die Attribute zur Laborbetreuung (LabBez, LabBetrN, LabBetrVN), PrüfMP die zur prüfenden Person (PrüfPersNr), die auch Fremdschlüssel ist. |
|
Die Relationen PrüfPALA und PrüfKLMP sind "nach oben" Spezialisierungen und "nach unten" Generalisierungen. Die Abbildung mit dem Datenmodell unten verdeutlicht dieses Strukturmerkmal. In dieser Abbildung sind die relationalen Verknüpfungen entlang dieser Spezialisierungshierachie eingezeichnet. Natürlich können aber in relationalen Datenbanken mit SQL alle Relationen einer Gen/Spez über ihre (gleichen) Schlüssel verknüpft werden. |
|
Die neuen Relationen: |
|
PrüfAllg (#PrüfNr, Bez, Datum, Versuch, ArtPrüf, LVNr) |
|
PrüfPALA (#PrüfNr, Start, Ende) |
|
PrüfKLMP (#PrüfNr, Länge) |
|
PrüfLA (#PrüfNr, LabBez, LabBetrN, LabBetrVN) |
|
PrüfMP (#PrüfNr, PrüfPersNr) |
|
Die Kardinalitäten und Min-/Max-Angaben sind wie folgt: |
|
- Von PrüfAllg zu PrüfPALA: 1,1 bzw 0,1 : 1,1. Genauso sind die übrigen Gen/Spez-Wertigkeiten .
- Von DozAllg zu PrüfMP: 1:n bzw. 0,n : 1,1. Da es sicher Dozenten gibt, die nicht an einer mündlichen Prüfung teilgenommen haben und da jede mündliche Prüfung genau einen Prüfer hat.
|
|
Anforderung Teil 6 |
|
Der Besuch einer Prüfung bezieht sich immer auf eine Lehrveranstaltung. Festgehalten wird zu jeder Prüfung das Semester, in dem sie stattfindet (Sem), das genaue Datum, um welchen Versuch es sich handelt (1. Versuch, 2. Versuch, ...) und welche Note erzielt wurde. |
|
Der letzte Teil der Anforderungen klärt die Erfassung des Prüfungsbesuchs. Dies ist wieder eine n:m-Beziehung (zwischen Studierenden und Prüfungen). Als Schlüssel dient neben der Matrikel- und Prüfungsnummer auch die Semesterangabe. Die anderen drei beschreibenden Attribute werden als Nichtschlüsselattribute eingefügt. |
|
Damit ergibt sich folgende Relation: |
|
PrüfBesuch (#(MatrNr, PrüfNr, Sem), Datum, Versuch, Note) |
|
Die Kardinalität und die Min-/Max-Angaben sind wie folgt: |
|
- Von Studierende über PrüfBesuch zu PrüfAllg: n:m bzw. 0,n : 1,m. Da ein Studierender zu Beginn des Studiums noch keine Prüfung besucht hat und da man davon ausgehen kann, dass eine Prüfung nur stattfindet, wenn mindestens ein Prüfling kommt.
|
|
Damit sind die einzelnen Anforderungen modelliert und können nun zusammengefügt werden. |
|
2.11.3 Lösung |
|
Textliche Fassung |
|
Adressen (#AdrNr, Ort, PLZ, Strasse) |
|
DozAllg (#DozNr, Name, VName, Anrede, E-Mail) |
|
DozExt (#DozNr, AkAb, OrgNr, AdrNr) |
|
DozHS (#DozNr, Fakultät, BüroNr, BezGeb, IntTel, SprSt, E-Mail) |
|
Gebäude (#BezGeb, Ort, Straße, DVBetr) |
|
Lehrbetrieb (#(DozNr, VeranstNr, Sem)) |
|
LV (#LVNr, BezLV, TypSG, BezSG, SemPlan, cp, SWS) |
|
LVBesuch (#(MatrNr, LVNr, Sem)) |
|
LVRäume (#(LVNr, Sem), RaumNr) |
|
LVTermine (#(LVNr, Tag, Beginn), Ende) //für jeden Termin |
|
Organisationen (#OrgNr, Bez, AdrNr, Branche) |
|
PrüfAllg (#PrüfNr, Bez, ArtPrüf, LVNr) |
|
PrüfBesuch (#(MatrNr, PrüfNr, Sem), Datum, Versuch, Note) |
|
PrüfKLMP (#PrüfNr, Länge) |
|
PrüfLA (#PrüfNr, LabBez, LabBetrN, LabBetrVN) |
|
PrüfMP (#PrüfNr, PrüfPersNr) |
|
PrüfPALA (#PrüfNr, Start, Ende) |
|
Räume (#RaumNr, ArtRaum, Groesse, BeamerJN, IntranetJN, GebBez) |
|
StudAdr (#(MatrNr, AdrNr), Art) |
|
Studierende (#MatrNr, Name, VName, E-Mail, BegStudium, EndeStudium, SG, FachSem) |
|
|
|
Grafische Fassung |
|
|
|
Abbildung 2.11-4: Relationales Datenmodell Vorlesungsbetrieb |
|
2.12 Fachliteratur |
|
Angesichts von 20 Relationen und zahlreichen methodischen und semantischen Strukturmerkmalen gehört diese Aufgabe zu den umfangreichen und komplexen. |
|
2.12.1 Anforderungsbeschreibung |
|
Im Anwendungsbereich Fachliteratur sollen alle wichtigen Typen von Fachliteratur erfasst werden. Zweck der Datenbank ist es, die Literatur zu erfassen, die Suche nach Fachliteratur zu ermöglichen und von Zeit zu Zeit eine Literaturliste wie die nachfolgende zu erstellen (z.B. für eine Bachelor- oder Masterarbeit). |
|
Die wichtigsten Arten von Fachliteratur sind: |
|
- Monographien (Mono). Dies sind Bücher, die ein zusammenhängendes Werk darstellen und die von einem Autor oder mehreren verfasst sind.
- Sammelbände (SB). Auch diese sind Bücher. Allerdings hat hier jedes Kapitel einen eigenen Autor oder mehrere. Die Autoren des Sammelbandes insgesamt werden Herausgeber genannt.
- Die Beiträge in einem Sammelband (SBB). Dies sind die einzelnen Kapitel in Sammelbänden. Da diese ja spezielle Themen betreffen und eigene Autoren haben, werden sie als eigenständige Werke in der Datenbank erfasst. Zum Beispiel, um sie bei einer inhaltlichen Suche zu finden.
- Artikel in Fachzeitschriften (Zeitschriftenartikel, ZSA). Dies sind Werke, die in einer Zeitschrift erschienen sind.
- Internetquellen (IQU). Dies sind Werke von Internetseiten, z.B. Forschungsberichte, Firmenmitteilungen, usw.
|
|
Ergänzend werden Zeitschriften (ZS) erfasst, als Trägermedium der Zeitschriftenartikel (ZSA). |
|
Diese Unterscheidung von Literaturarten ist wichtig, weil sie unterschiedlich beschrieben werden. Zum Beispiel in einer Literaturliste, wie sie bei einer akademischen Abschlussarbeit meist anfällt: |
Bibliographische Angaben |
Beispiele für Monographien (Mono) |
|
Scheer, August-Wilhelm: Wirtschaftsinformatik. Referenzmodell für industrielle Geschäftsprozesse (5. Auflage), Berlin et al. 1994 (Springer-Verlag) |
|
Österle, H.; Brenner, W.; Hilbers, K. et al.: Unternehmensführung und Informationssystem, Stuttgart 1992 (XYZ-Verlag) |
|
Staud, Josef Ludwig: Relationale Datenbanken. Grundlagen, Modellierung, Speicherung, Alternativen (2. Auflage). Hamburg 2021 |
|
Also: Name; Vorname; Titel; Ort (des Verlags); Erscheinungsjahr; Verlag, bei dem das Buch erschienen ist. Die Gestaltung mit Punkten, Strichpunkten, Kommata und die Einordnung der Verlagsangabe ist nur eine Empfehlung. Bei KI-Programmen als Autoren steht Name für die Bezeichnung der Software. |
|
Beispiel für Sammelbände (SB) |
|
Reussner, Ralf; Hasselbring, Wilhelm (Hrsg.), Handbuch der Software-Architektur (2. Auflage). Heidelberg 2009 (dpunkt) |
|
Becker, Jörg; Kugeler, Martin; Rosemann, Michael (Hrsg.): Prozessmanagement. Ein Leitfaden zur Prozessorientierten Organisationsgestaltung (5. Auflage). Berlin u.a. 2005 (Springer) |
|
Also: Namen und Vornamen; Hinweis auf die Herausgeberschaft; Titel; Untertitel, falls vorhanden; Hinweis auf Auflage, falls nicht die erste; Verlagsort(e); Erscheinungsjahr; Angabe Verlag, falls möglich. |
|
Beispiele für Beiträge in einem Sammelband (SBB) |
|
Hansmann, Holger; Laske, Michael; Luxem, Redmer: Einführung der Prozesse - Prozess-Roll-out. In: [Becker, Kugeler, Rosemann (Hrsg.) 2005], S. 269 - 298. |
|
Baier, Achim; Becker, Steffen; Jung, Martin u.a.: Modellgetriebene Software-Entwicklung . In: [Reussner, Hasselbring (Hrsg.) 2009], S. 93 - 122 |
|
Also: Namen und Vornamen, bei mehr als drei Autoren der Zusatz "u.a." (und andere) oder "et al"; Titel; das Wort "In", das verdeutlicht, dass jetzt das übergeordnete Werk (der SB) folgt; bibliographische Angaben des Sammelbandes, in dem der SBB enthalten ist; Seitenangaben: erste und letzte Seite des SBB. |
|
Falls in einer Literaturliste ein Beitrag aus einem Sammelband angeführt wird, muss auch der Sammelband enthalten sein. |
|
Beispiele für einen Artikel in einer Zeitschrift (ZSA) |
|
Wirth, N.: Gedanken zur Software-Explosion. In: Informatik Spektrum, Februar 1994, S. 5 - 10. |
|
Czarski, Carsten: Richtig gefragt. Konstrukte für komplexe Datenbank-Queries. In: iX, Januar 2013, S. 154 - 157. |
|
Schulz, Hajo: Objektorientiert programmieren mit Smalltalk. In: c’t kompakt Programmieren, Heft 03/2012, S. 146 - 152 |
|
Also: Namen und Vornamen; Titel, evtl. Untertitel; Bezeichnung der Zeitschrift, Angaben zum konkreten Heft der Zeitschrift; erste und letzte Seite des Artikels. |
|
2.12.2 Lösungsschritte |
|
Grundstruktur: Werke, Autoren, Autorenschaft |
|
Bevor wir in die eigentliche Modellierung einsteigen, hier einige Ausführungen zur Modellierung dieses Anwendungsbereichs. Zu jeder Fachliteratur, egal ob sie als Buch, Zeitschriftenaufsatz oder sonstwie erscheint, gehört ein Text, dieser wird Werk genannt. Er soll hier durch eine WerkNr identifiziert werden: |
Im Mittelpunkt: das Werk . . . |
Werke (#WerkNr, ...) |
|
Ein Werk stammt meist von einer oder mehreren natürlichen Personen. Oftmals werden auch Organisationen (Forschungseinrichtungen, Behörden, ...) als Autoren genannt. Inzwischen kann auch ein KI-Programm Texte erstellen und sollte dann als Autor genannt werden. Diese Autoren werden ebenfalls erfasst und durch eine Autorennummer identifiziert (AutorNr). Da es drei Gruppen von Autoren mit teilweise abweichenden Attributen gibt, müssen dafür drei verschiedene Relationen angelegt werden, Organisationen als Autoren (AutOrg), Personen als Autoren (AutPers) und KI-Programme als Autoren: |
. . . und seine Autoren |
AutPers (#AutorNr, Name, VName, . . .) |
|
In dieser ersten Fassung der Relation wurden, abgeleitet aus den obigen Beispielen, die Attribute Name und Vorname (VName) eingefügt. |
|
AutOrg(#AutorNr, BezOrg, BezOrg2, . . .) |
|
Hier wurde die Bezeichnung der Organisation (BezOrg) und die zweite Zeile der Organiationsbezeichnung (BezOrg2) angelegt. |
|
AutKI(#AutorNr, BezKI, Besitzer, . . .) |
|
Für die KI-Programme werden in der ersten Fassung ihre Bezeichnung (BezKI), z.B. Chatxyz, und der Besitzer (z.B. Google) erfasst. |
|
Hier bietet sich eine Generalisierung / Spezialisierung an. Die Generalisierung wird Autoren genannt. Sie erhält neben der AutorNr ein Attribut Typ mit den Ausprägungen Mensch, Organisation und KI sowie ein Attribut Id1 für Name (bei Menschen), BezOrg (bei Organisationen) bzw. BezKI (bei KI-Programmen): |
Generalisierung / Spezialisierung |
Autoren (#AutorNr, Id1, Typ, . . .) |
|
Diese Generalisierung hat zwar erst mal wenig Attribute, erleichtert aber Abfrage und Verknüpfung. Vielleicht kommen ja noch Attribute dazu. |
|
Hier gilt ganz grundsätzlich: |
Autorenschaft |
Ein Autor kann mehrere Werke veröffentlichen, ein Werk kann mehrere Autoren haben. |
|
Werke und Autoren sind durch die Autorenschaft verbunden: Diese hält fest, wer welches Werk verfasst hat. Da es sich um eine n:m-Verknüpfung handelt, ergibt sich eine Verbindungsrelation. |
|
Nehmen wir noch dazu, dass bei Werken mit mehreren Autoren die Reihenfolge der Autorennennungen wichtig ist, ergibt sich für die Relation Autorenschaft ein beschreibendes Attribut Rang (an welcher Stelle der Autorenliste kommt er oder sie). Insgesamt liegen dann in textlicher Form folgende Relationenfragmente vor: |
|
AutKI(#AutorNr, BezKI, Besitzer, . . .) |
|
Autoren (#AutorNr, Id1, Typ, . . .) |
|
Autorenschaft (#(AutorNr, WerkNr), Rang) |
|
AutOrg(#AutorNr, BezOrg, BezOrg2, . . .) |
|
AutPers (#AutorNr, Name, VName, . . .) |
|
Werke (#WerkNr, ...) |
|
Das folgende Modellfragment gibt diesen "Kern" des Datenmodells an. |
|
|
|
Abbildung 2.12-1: Autorenschaft im Anwendungsbereich Fachliteratur |
|
Modellierung der Literaturtypen |
|
Die obige Liste von Werken machte den weitergehenden Aufbau der verschiedenen Literaturarten deutlich. In der folgenden Tabelle sind diese Informationen zusammengefasst. Es handelt sich hier um eine Generalisierung / Spezialisierung (vgl. Abschnitt 2.4.2 sowie [Staud 2021, Abschnitt 14.1]). |
Typen bewältigen durch Gen/Spez. |
Werke und ihre Attribute aus der Gen/Spez-Hierarchie |
|
|
|
Mono |
SB |
SBB |
ZSA |
IQU |
A |
Autoren: Personen oder Organisationen, u.U. mehrere |
Ja |
Ja |
Ja |
Ja |
ja |
B |
Titel ggf. Untertitel: UTitel |
Ja |
Ja |
Ja |
Ja |
ja |
C |
ISBN-Nummer: ISBN |
Ja |
Ja |
- |
- |
- |
D |
Auflage |
Ja |
Ja |
- |
- |
- |
E |
Erscheinungsjahr: Jahr |
Ja |
Ja |
- |
- |
- |
F |
Verlagsort/e, u.U. mehrere: Ort |
Ja |
Ja |
- |
- |
- |
G |
Verlagsbezeichnung: BezVerlag U.U. mehrere |
Ja |
Ja |
- |
- |
- |
H |
Von (erste Seite des SBBs bzw. ZSAs) |
- |
- |
Ja |
Ja |
- |
I |
Bis (letzte Seite des SBBs bzw. ZSAs) |
- |
- |
Ja |
Ja |
- |
J |
Quelle (SB + Kapitel, in dem der SBB enthalten ist): WerkNr, KapitelNr |
- |
- |
Ja |
- |
- |
K |
Quelle (Name und Heft der Zeitschrift, in dem der ZSA enthalten ist): ZSBez, HeftNr |
- |
- |
- |
Ja |
- |
L |
URL |
- |
- |
- |
- |
ja |
M |
Tag des Abrufs: AbrTag |
- |
- |
- |
- |
ja |
N |
Anzahl der Kapitel in Sammelbänden: AnzKap |
- |
Ja |
- |
- |
- |
| |
Zeile A ... |
|
sagt, dass alle Werke Autoren haben, die entweder Personen oder Organisationen sind. Dies wurde schon angelegt. |
|
Zeile B ... |
|
gibt den Hinweis auf ein Attribut, das alle verschiedenen Werke haben, den Titel. Außerdem auf eine Spezialisierung von Werke, nämlich Werke mit Untertiteln: |
|
Werke (#WerkNr, Titel, . . .) |
|
WerkeUT (#WerkNr, UT) |
|
Zeilen C bis G ... |
|
zeigen, dass MONographien (Mono) und SammelBände (SB) die 5 Attribute ISBN, Auflage, Jahr, Ort und BezVerlag gemeinsam haben, womit eine weitere Spezialisierung von Werke entsteht. In die Spezialisierung kommen aber nur drei Attribute, da die Verlagsangaben mehrfach vorkommen können, wenn ein einzelnes Werk von mehreren Verlagen herausgegeben wird. Dazu unten mehr. |
|
Mono+SB (#WerkNr, ISBN, Auflage, Jahr) |
|
Zeilen F und G: vgl. unten |
|
Zeilen H und I ... |
|
geben Attribute an, die nur SBB und ZSA besitzen. Für sie entsteht also eine Spezialisierung: |
|
SBB+ZSA (#WerkNr, Von, Bis) |
|
Zeile J ... |
|
zeigt, dass Sammelbandbeiträge (SBB) eine weitere spezifische Information haben, die Angabe, von welchem Sammelband sie stammen (Quelle). Sie besteht aus zwei Attributen: Werknummer des Sammelbandes (WerkNrSB) und die KapitelNr im Sammelband. Somit entsteht die folgende Relation: |
|
SBB (#WerkNr, WerkNrSB, KapitelNr) |
|
Komposition zwischen SBB und SB als 1:n-Beziehung |
|
Damit liegt eine Komposition zwischen Sammelbandbeiträgen und Sammelbänden vor. Falls ein Sammelband aus dem Buchbestand und damit aus der Datenbank entfernt wird, müssen auch die Sammelbandbeiträge dieses Sammelbands entfernt werden. Die Gestaltung des Schlüssels ergibt sich daraus, dass jeder SBB eine eindeutige Werknummer erhält und auch nur in genau einem SB enthalten ist. So sollte es zumindest sein. Es kommt aber natürlich vor, dass ein Autor sein Werk in mehreren Sammelbänden unterbringt. |
Muster Komposition |
Zeile K ... |
|
zeigt, dass die Zeitschriftenaufsätze ebenfalls eine spezifische Information haben, die Quellenangabe. Sie besteht (im einfachsten Fall) aus zwei Attributen, Zeitschriftenbezeichnung (ZSBez) und Heftnummer (HeftNr): |
|
ZSA (#WerkNr, ZSBez, HeftNr) |
|
Zeilen L, M und N ... |
|
führen zu weiteren Spezialisierungen von Werke, zu Internetquellen (IQU) und zu Sammelbänden (SB). Für die Internetquellen wird die URL und der Tag des Abrufs (AbrTag) angegeben, für die Sammelbände die Anzahl der Kapitel, die sie enthalten (AnzKap): |
|
IQU (#WerkNr, URL, AbrTag) |
|
SB (#WerkNr, AnzKap) |
|
Insgesamt ergibt sich damit folgendes Datenmodell: |
|
IQU (#WerkNr, URL, AbrTag) |
|
ZSA (#WerkNr, ZSBez, HeftNr) |
|
AutOrg(#AutorNr, BezOrg2, BezOrg3) |
|
Autoren (#AutorNr, Id1) |
|
Autorenschaft (#(AutorNr, WerkNr), Rang) |
|
AutPers (#AutorNr, VName, Anrede) |
|
Mono+SB (#WerkNr, ISBN, Auflage, Jahr) |
|
SB (#WerkNr, AnzKap) |
|
SBB (#WerkNr, WerkNrSB, KapitelNr) |
|
SBB+ZSA (#WerkNr, Von, Bis) |
|
Werke (#WerkNr, Titel) |
|
WerkeUT (#WerkNr, UT) |
|
Wertigkeiten |
|
Die folgende Abbildung mit dem Ausschnitt zur Gen/Spez der Werke und zur Komposition zwischen SBB und SB verdeutlicht dieses Strukturmerkmal. Die Beziehungswertigkeiten zeigen zum einen die zwischen jeder Spezialisierung und ihrer Generalisierung (Kardinalität 1:1, Min-/Max-Angaben 0,1 : 1,1), zum anderen die bei einer Komposition, hier zwischen SB und SBB. Die Null bei der Wertigkeit bedeutet, dass es auch Sammelbände gibt, von denen keine Sammelbandbeiträge erfasst sind. Der Fremdschlüssel Fach in Werke wird unten erläutert. |
|
|
|
Abbildung 2.12-2: Gen/Spez zu Literaturarten und Muster Komposition im Anwendungsbereich Fachliteratur |
|
Noch mehr Anforderungen |
|
Erfasst werden soll außerdem, welches Werk von welchem Verlag verfasst wurde. Es kommt auch vor, dass mehrere Verlage zusammen ein Buch publizieren. Bei den Verlagen wird der Ansprechpartner (AnsprV), die allgemeine Telefonnummer (Tel) und die des Ansprechpartners (TelAP) erfasst, für die Adressen der Verlage und die Adressen der Autoren PLZ, Ort und Straße. Von einem Verlag wird nur die Hauptadresse erfasst, von einem Autor mehrere. Es gibt auch Adressen, unter denen mehrere Autoren wohnen. Daraus ergeben sich die folgenden Relationen. Die Veröffentlichungstätigkeit wird als n:m-Verbindung zwischen Verlagen und Werken angesetzt. Die Adressen der Verlage werden durch einen Fremdschlüssel in Verlage integriert. Für die Adressen der Autoren gibt es eine Verbindungsrelation. |
Verlage und Publikationen |
Neue und veränderte Relationen |
|
Verlage (#VerlNr, #BezVerlag,Tel, AnsprV, TelAP, AdrNr) |
|
Publikationen (#(VerlNr, WerkNr)) |
|
Adressen (#AdrNr, PLZ, Ort, Straße) |
|
AutOrg(#AutorNr, BezInst2, BezInst3, AdrNr) |
|
AutPersAdr (#(AutorNr, AdrNr)) |
|
Für die Literatursuche sollen die Werke auch inhaltlich erschlossen werden. Dazu werden für jedes Werk ein Schlagwort (BezSchl) oder mehrere erhoben, z.B. Softwareentwicklung, Datenbankdesign, HTML 5, NoSQL. Jedes Schlagwort wird kurz beschrieben (Beschr), um die exakte Bedeutung zu klären. Dies führt zu folgenden neuen Relationen. |
Inhaltliche Erschließung |
WSchl (#(WerkNr, BezSchl)) |
|
Schlagw (#BezSchl, Beschr) |
|
"Wieviele Werke liegen zu jedem Fachgebiet vor" |
|
Ebenfalls erfasst werden soll ein Fachgebiet pro Werk. D.h. jedes Werk erhält eine Fachgebietszuordnung (Medizin, Technik, Informatik, ...). Diese werden regelmäßig ausgezählt, die Ergebnisse werden auch in der Datenbank verwaltet. |
|
AnzFG (#Fachgebiet, Anzahl) |
|
2.12.3 Lösung |
|
Textliche Fassung |
|
Insgesamt ergeben sich damit folgende Relationen: |
|
Adressen (#AdrNr, PLZ, Ort, Straße) |
|
AnzFG (#Fachgebiet, Anzahl) //Anzahl Werke in den Fachgebieten |
|
Autoren (#AutorNr, Id1, Typ) //Name bzw. Organisationsbezeichnung |
|
Autorenschaft (#(AutorNr, WerkNr), Rang) |
|
AutOrg(#AutorNr, BezInst2, BezInst3, AdrNr) //Organisationen als Autoren |
|
AutPers (#AutorNr, VName, Anrede) //Personen als Autoren |
|
AutPersAdr (#(AutorNr, AdrNr)) //n:m, Autorenadressen |
|
IQU (#WerkNr, URL, AbrTag) //Internetquellen |
|
Mono+SB (#WerkNr, ISBN, Auflage, Jahr) //Monographien und Sammelbände |
|
Publikationen (#(VerlNr, WerkNr)) //Verlage und Veröffentlichungen |
|
SB (#WerkNr, AnzKap) //Sammelbände |
|
SBB (#WerkNr, WerkNrSB, KapitelNr) //Beiträge in Sammelbänden |
|
SBB+ZSA (#WerkNr, Von, Bis) //Seitenzahlen |
|
Schlagw (#BezSchl, Beschr) //Schlagworte |
|
Verlage (#VerlNr, #BezVerlag,Tel, AnsprV, TelAP, AdrNr) //Verlage |
|
Werke (#WerkNr, Titel, Fach) //Textliche Werke (Fachliteratur) |
|
WerkeUT (#WerkNr, UT) //Werke mit Untertiteln |
|
WSchl (#(WerkNr, BezSchl)) //Verschlagwortung |
|
ZSA (#WerkNr, ZSBez, HeftNr) //Zeitschriftenaufsätze |
|
|
|
Grafische Fassung |
|
Die folgende Abbildung zeigt die grafische Darstellung des Datenmodells. Einige beispielhafte Wertigkeiten wurden auch eingefügt. Ein Beispiel für die Wertigkeiten einer n:m-Verknüpfung ist bei Autorenschaft angegeben. Die Min-/Max-Angaben signalisieren, dass nur Autoren aufgenommen werden, die auch mindestens 1 Werk in der Datenbank aufweisen und dass Werke nicht ohne zugehörigen Autor erfasst werden. |
|
|
|
Abbildung 2.12-3: Relationales Datenmodell zum Anwendungsbereich Fachliteratur |
|
Abkürzungen in den Datenmodellen zur Fachliteratur: |
|
ZS: Zeitschriften |
|
ZSA: Zeitschriftenartikel |
|
SB: Sammelbände |
|
SBB: Beiträg in einem Kapitel eines Sammelbandes |
|
Mono: Monographien |
|
IQU: Internetquellen |
|
2.13 Rechnung Stufe 1 |
|
2.13.1 Anforderungsbeschreibung |
|
Mit dieser Aufgabe soll ein relationales Datenmodells für den Zweck der Rechnungsstellung erstellt werden. Ausgangspunkt ist dabei die in der folgenden Abbildung angegebene anonymisierte Rechnung, also ein Geschäftsobjekt (business object), was in der Datenmodellierung durchaus oft der Fall ist. |
Rechnungen |
Um die Rechnung aus dem Datenbestand reproduzieren zu können, soll folgendes festgehalten werden: |
|
- Die Kunden werden mit Namen (Name), Vornamen (VName) und Anrede erfasst. Außerdem wird ein identifizierendes Attribut (KuNr) angelegt.
- Ein Kunde wird zuerst mit nur einer Adresse erfasst. Später dann mit beliebig vielen.
- Ein Kunde kann mehrere Telefonanschlüsse haben.
- In der Datenbank wird auch festgehalten, wer die Kundschaft bedient hat (Verkäufer). Dies wird auf der Rechnung ausgegeben.
- Die Information TOUR. Sie bezeichnet das Auslieferungsteam (Tour).
- Die Information KVDAT. Sie gibt den Tag an, an dem die Kundschaft im Möbelhaus war und die Ware bestellt hat (Kvdat).
- Das Datum der Lieferung (DatumLief).
- Der Betrag der Mehrwertsteuer (MWStBetrag).
- Es gilt: Eine Rechnung bezieht sich auf genau einen Auftrag
- Die angegebene Telefonnummer ist die der Rechnungsanschrift
|
|
Die Abkürzungen bei Position 1 bedeuten: |
|
889999: Artikelnummer (ArtNr)
|
|
B/00/EG: Standort der Ware im Lager (Standort)
|
|
COUCHTISCH 1906 EICHE NATUR - MIT LIFT 125x71 cm: Artikelbezeichnung (ArtBez)
|
|
Ansonsten gilt die übliche kaufmännischen Semantik von Rechnungen. |
|
|
|
Abbildung 2.13-1: Geschäftsobjekt Rechnung (Typ Möbelhaus) |
|
2.13.2 Lösungsschritte |
|
Relationale Datenmodellierung kann auch so gelöst werden, dass zuerst die Attribute mit ihren Determinanten und funktionalen Abhängigkeiten bestimmt werden: |
|
- Name: des Kunden
- VNname
- PLZ: der Rechnungsanschrift
- Ort
- Straße
- Tel: Telefonnummer
- KuNr: Kundennummer. Diese ergänzen wir gleich, da die Erfassung der Kunden ohne eine Kundennummer nicht sinnvoll ist.
- ReNr: Rechnungsnummer
- ReDatum: Rechnungsdatum
- Verkäufer: die Angabe des Verkäufers erfolgt auf der Rechnung
- KVDAT: Hierbei handelt es sich um das Kaufvertragsdatum.
- Tour: Bezeichnung des Teams, das mit seinem Fahrzeug die Möbel ausliefert. Eine tiefere Semantik liegt nicht vor.
- PosNr: Rechnungspositionsnummer
- ArtNr: wird bei den Rechnungspositionen angegeben.
- Anzahl der Artikel pro Position
- Standort: Standort der Ware im Lager. Wird bei den Rechnungspositionen angegeben.
- ArtBez: Artikelbezeichnung
- DatumLief: Datum der Lieferung
- MWStB: Betrag der Mehrwertsteuer
- ZV: Zahlungsvereinbarung
- LiPreis: Listenpreis. Der Preis für die gesamte Position wird berechnet aus Anzahl und Preis.
|
|
Für einige Artikel liegt noch eine Beschreibung vor (Beschr), die aber nicht auf der Rechnung ausgegeben wird. In der Datenbank soll sie trotzdem erfasst werden. |
|
Datenbankdesigner haben es nicht gerne, Informationen im Anwendungsprogramm zu hinterlegen oder in separaten (neben der Datenbank befindlichen) Tabellen und dies obwohl der neueste Datenbank-Ansatz (NoSQL) sehr viel Semantik im Programm umsetzt. Und doch kann es manchmal sinnvoll sein. Hier soll dies beispielhaft mit dem Mehrwertsteuersatz geschehen. Er wird im Programm hinterlegt, der Mehrwertsteuerbetrag (MWStB) wird dann daraus und aus der Rechnungssumme berechnet. |
Informationen im Programm |
Universalrelation |
|
Das folgende muss man nicht machen, es hilft aber in komplexen Situationen gerade zu Beginn der Modellierung. Wir betrachten alle Attribute und bestimmen alle funktionalen Abhängigkeiten, z.B. durch FA-Diagramme. |
|
Nach einigen langen Besprechungen ergab sich über die gesamte Universalrelation das folgende FA-Diagramm. |
|
|
|
Abbildung 2.13-2: FA-Diagramm zur Universalrelation Rechnungen |
|
Grundlage der Betrachtung der funktionalen Abhängigkeiten im FA-Diagramm ist die Kenntnis der Semantik des Anwendungsbereichs. Neben den funktionalen Abhängigkeiten sind auch gleich die Determinaten zu bestimmen. Hier sind dies, wie die Abbildung anschaulich zeigt, KuNr, (ReNr, PosNr), ReNr, ArtNr. Dies sind Kandidaten für die Schlüssel der zu findenden Relationen. |
|
Welche Relationen können wir daraus ableiten? Sie sind in obiger Abbildung leicht zu erkennen. Alle Determinanten mit ihren funktional abhängigen Attributen werden normalerweise zu Relationen. Die Determinanten werden dann zu Schlüsseln. |
|
Problemlos zu erkennen sind die Kunden: Identifiziert werden sie durch die KuNr. Voll funktional abhängig von dieser sind die folgenden Attribute: |
Kunden |
- KuNr => Name
- KuNr => VName
- KuNr => PLZ
- KuNr => Ort
- KuNr => Straße
|
|
Für die Adressangaben gilt dies nur, weil wir uns in Stufe 1 mit der Rechnungsanschrift begnügen. Damit ergibt sich die erste Relation: |
|
|
|
Abbildung 2.13-3: FA-Diagramm von Kunden |
|
Kunden (#KuNr, Name, VName, PLZ, Ort, Straße) |
|
Die Telefonanschlüsse wurden oben weggelassen, da ja jeder Kunde mehrere haben kann. Dies ist dann keine funktionale Abhängigkeit. Hier können wir sie wieder dazutun, in einer eigenen Relation: |
|
KuTel(#(KuNr, Tel)) |
|
KuNr ist Fremdschlüssel und dient der Verknüpfung mit Kunden. |
|
Oben fällt der Attributsblock auf, der von ReNr funktional abhängig ist. Dies sind Attribute, mit denen die Rechnung beschrieben wird. In Abgrenzung zu den Rechnungspositionen soll er Rechnungsköpfe (ReKöpfe) genannt werden. |
Rechnungsköpfe |
Die kaufmännische Semantik und die relationale Theorie sagen uns, dass es eine Unterscheidung geben muss zwischen Rechnungskopf (identifiziert durch die Rechnungsnummer (ReNr)) und den Rechnungspositionen, denn es gibt pro Rechnung mehrere Positionen. Letztere werden durch (ReNr, PosNr) identifiziert. |
|
Folgende funktionalen Abhängigkeiten bestehen von der Determinante ReNr, die - spätestens nach der Normalisierung - zum Schlüssel wird. |
|
- ReNr => ReDatum: Es gibt genau ein Rechnungsdatum pro Rechnung bzw. von der Rechnungsnummer kann auf das Rechnungsdatum geschlossen werden.
- ReNr => Verkäufer: Da immer nur einer für einen Kaufvertrag zuständig ist und nur einer auf der Rechnung erscheint.
- ReNr => Tour: Es gibt ein Auslieferungsteam je Rechnung.
- ReNr => KVDAT: Es gibt hier genau ein Kaufvertragsdatum je Rechnung.
- ReNr => MWStB: Es gibt nur einen Mehrwertsteuerbetrag je Rechnung.
- ReNr => DatumLief: Für jede Rechnung gibt es genau ein Lieferdatum.
- ReNr => ZV: Die Zahlungsvereinbarung ist je Rechnung eindeutig. Trotz Nachfragen konnte auch keine weitere Semantik (z.B. Abhängigkeit vom gekauften Produkt) festgestellt werden.
|
|
Damit ergibt sich folgende Relation zu den Rechnungsköpfen: |
|
|
|
Abbildung 2.13-4: FA-Diagramm von Rechnungsköpfen (ReKöpfe) |
|
ReKöpfe (#ReNr, ReDatum, KVDAT, Tour, Verkäufer, DatumLief, ZV, MWStB) |
|
Auch diese ist in 5NF. |
|
Die letzten leicht erkennbaren Objekte sind die Artikel. Sie werden identifiziert (ArtNr), haben eine Bezeichnung (ArtBez) und werden beschrieben. ArtNr wird also von der Determinante zum Schlüssel mit folgenden funktional abhängigen Attributen: |
Artikel |
- ArtNr => ArtBez
- ArtNr => ArtBeschr
- ArtNr => LiPreis: Da es sich um den Einzelpreis der Artikel handelt.
- ArtNr => Standort: Standort der Ware im Lager. Für einen Artikel immer derselbe.
|
|
Dies führt zu folgender Relation: |
|
|
|
Abbildung 2.13-5: FA-Diagramm von Artikel |
|
Artikel (#ArtNr, ArtBez, ArtBeschr, LiPreis, Standort) |
|
Beim Überprüfen der Semantik überkommen uns Zweifel. Die Artikelbeschreibung liegt derzeit nur für 10% der Artikel vor. Soll das Attribut dann hier bleiben? In der späteren Datenbank wird dann für jeden Artikel der Speicherplatz für die Beschreibung verbraucht, auch wenn keine vorliegt. Da unser Datenbankmanagementsystem an dieser Stelle keine dynamische Speicherverwaltung anbietet, beschließen wir, die Artikelbeschreibung in eine eigene Relation auszulagern. |
Pragmatik |
Damit erhalten wir eine Generalisierung / Spezialisierung. In der relationalen Modellierung wird dafür für die Spezialisierung eine eigene Relation angelegt mit dem entsprechenden Attribut und mit dem Schlüssel der Generalisierung: |
Muster Generalisierung / Spezialisierung |
ArtBeschr(#ArtNr, ArtBeschr) //Artikelbeschreibung |
|
Auch hier gibt es keinen Verstoß gegen die 5NF. |
|
Bleiben noch die übrigen Attribute. Sie bewegen sich alle um die Rechnungspositionen herum. Rechnungspositionen werden durch eine Attributskombination identifiziert: (ReNr, PosNr). Folgende funktionalen Abhängigkeiten bestehen: |
|
- (ReNr, PosNr) => ArtNr: Da es pro Rechnungsposition nur einen Artikel gibt.
- (ReNr, PosNr) => Anzahl: Anzahl der Artikel je Position.
|
|
Damit ergibt sich folgende Relation zu Rechnungspositionen, ebenfalls in 5NF: |
|
|
|
Abbildung 2.13-6: FA-Diagramm zu Rechnungspositionen (RePos) |
|
RePos (#(ReNr, PosNr), ArtNr, Anzahl). |
|
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 (ReNr, ArtNr) eingerichtet. Dann wird die PosNr zu einem beschreibenden Attribut der Relation. Insgesamt also: |
Alternativer Weg |
RePos (#(ReNr, ArtNr), PosNr, Anzahl) //Alternative |
|
Relationale Verknüpfungen |
|
In dem Lösungsweg sind nun sechs Relationen entstanden, die wesentliche Merkmale der Rechnung beschreiben. Zu prüfen sind aber noch die die relationalen Verknüpfungen und damit die Schlüssel/Fremdschlüssel - Beziehungen. |
|
- Zwischen Kunden und ReKöpfe: Hier liegt sicherlich eine Beziehung vor. Ein Kunde hat u.U. viele Rechnungen mit dem Unternehmen, aber eine Rechnung bezieht sich immer nur auf einen Kunden. Diese 1:n - Beziehung kann verankert werden, indem in ReKöpfe die Kundennummer als Fremdschlüssel festgehalten wird.
|
|
ReKöpfe (#ReNr, ReDatum, KVDAT, Tour, Verkäufer, DatumLief, ZV, MWStB, KuNr) |
|
Damit ist auch festgelegt, dass es keinen Rechnungskopf ohne Kundennummer gibt (denn ein Fremdschlüssel darf nie leer bleiben). Wenn wir annehmen, dass in der Datenbank nur Kunden erfasst sind, die schon gekauft haben, gelten die Min-/Max-Angaben von Kunden zu ReKöpfe 1,n : 1,1. |
|
- Zwischen Kunden und Artikel: Hier gibt es auf der Ebene der Relationen keine direkte Beziehung. Die Beziehung manifestiert sich durch die Rechnung und ihre Positionen. Wenn man sie trotzdem einrichtet, um z.B. im Rahmen des Kundenbeziehungsmanagements (Customer Relationship Management; CRM) schnellen Zugriff auf die vom Kunden schon getätigten Käufe zu haben, ist das möglich. Dafür müsste eine Verbindungsrelation eingerichtet werden.
- Zwischen Kunden und RePos (Rechnungspositionen): Auch hier gibt es auf der Ebene der Relationen keine Beziehung. Die Verknüpfung erfolgt über die Rechnung.
- Zwischen ReKöpfe und Artikel: Dieser Zusammenhang wird über die RePos hergestellt.
- Zwischen ReKöpfe und RePos: Diese Beziehung ist natürlich fundamental. Es ist eine 1:n - Beziehung, denn eine Rechnung kann mehrere Positionen haben, eine Rechnungsposition gehört aber immer zu einer bestimmten Rechnung. Damit handelt es sich bei diesem Muster um eine Komposition. Diese Beziehung wurde aber schon bei der Festlegung des Schlüssels von RePos festgelegt. Es muss lediglich noch die ReNr als Fremdschlüssel gekennzeichnet werden:
|
|
RePos (#(ReNr, PosNr), ArtNr, Anzahl) |
|
Komposition bedeutet ja Existenzabhängigkeit, die hier ganz klar zu erkennen ist. Da ein zusammengesetzter Schlüssel, wie hier (ReNr, PosNr), immer vollständig sein muss, kann es keine Rechnungsposition ohne zugehörigen Rechnungskopf geben. Und: Wird ein Rechnungskopf gelöscht, müssen auch die verbundenen Rechnungspositionen gelöscht werden. Die Min-/Max-Angaben sind 1,1 : 1,n, von RePos ausgehend. |
|
- Zwischen Artikel und Rechnungspositionen (RePos): Auch hier liegt eine 1:n - Beziehung vor. Ein Artikel kommt hoffentlich auf vielen Rechnungspositionen vor und eine Rechnungsposition erfasst genau einen Artikel. Die Min-/Max-Angabe von 1,1 auf der Seite der Rechnungspositionen ist hier besonders sinnvoll, denn es hat keinen Sinn, Rechnungspositionen ohne Artikel zu erfassen. Damit kann die Verknüpfung durch Übernahme der ArtNr in die Relation RePos eingerichtet werden. Da dies oben schon geschehen ist (falls nicht, würde das Defizit spätestens hier erkannt), muss lediglich noch die Kennzeichnung von ArtNr als Fremdschlüssel erfolgen:
|
|
RePos (#(ReNr, PosNr), ArtNr, Anzahl) |
|
Die funktionalen Abhängigkeiten sind in allen Relationen 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. |
Idealstruktur - redundanzfrei |
Die folgende Abbildung zeigt die grafische Darstellung des Datenmodells. |
|
|
|
Abbildung 2.13-7: Relationales Datenmodell Rechnungsstellung Stufe 1 |
|
Hier noch die textlichen Notationen - im Zusammenhang: |
|
2.13.3 Lösung Stufe 1 |
|
ArtBeschr(#ArtNr, Beschr) |
|
Artikel (#ArtNr, ArtBez, Standort, LiPreis) |
|
Kunden (#KuNr, Anrede, Name, VName, PLZ, Ort, Straße) |
|
KuTel(#(KuNr, Tel)) |
|
ReKöpfe (#ReNr, ReDatum, KVDAT, Tour, Verkäufer, DatumLief, ZV, MWStB, KuNr) |
|
RePos (#(ReNr, PosNr), ArtNr, Anzahl) |
|
2.14 Rechnung Stufe 2 |
|
2.14.1 Anforderungsbeschreibung |
|
Hier soll das Überarbeiten eines Datenmodells thematisiert werden. Dies ist eine Standardaufgabe, denn ein Anwendungsbereich verändert sich ständig und wenn dies geschieht, muss das Datenmodell und dann die Datenbank angepasst werden. |
Überarbeiten |
Das folgende Datenmodell aus obiger Aufgabe ist der Ausgangspunkt. Wie zu Beginn von Aufgabe 3.11 erläutert, beschreibt es einen Anwendungsbereich zur Rechnungsstellung: |
|
ArtBeschr(#ArtNr, Beschr) |
|
Artikel (#ArtNr, ArtBez, Standort, LiPreis) |
|
Kunden (#KuNr, Anrede, Name, VName, PLZ, Ort, Straße) |
|
KuTel(#(KuNr, Tel)) |
|
ReKöpfe (#ReNr, ReDatum, KVDAT, Tour, Verkäufer, DatumLief, ZV, MWStB, KuNr) |
|
RePos (#(ReNr, PosNr), ArtNr, Anzahl) |
|
In Stufe 2 wird nun zwischen Liefer- und Rechnungsadresse unterschieden und es soll gelten: Ein Kunde kann beliebig viele Adressen haben, jede kann bei einer Rechnung Liefer- oder Rechnungsadresse sein. |
Liefer- und Rechnungsadresse |
2.14.2 Lösungsschritte |
|
Da es nun mehrere Adressen je Kunde geben kann ist eine Folge dieser neuen Anforderungen, dass die alte Relation Kunden verkürzt wird, da die Adressattribute in eine eigene Relation Adressen gehen. Übrig bleiben KuNr, Name, VName, so dass daraus die neue Kundenrelation entsteht: |
|
Kunden (#KuNr, Name, Vorname) |
|
Die neue Relation Adressen erhält zusätzlich einen Schlüssel Adressnummer (AdrNr), denn einen Schlüssel braucht jede Relation: |
|
Adressen (#AdrNr, PLZ, Ort, Straße, Telefon) |
|
Nun fehlt noch die Verknüpfung zwischen den Kunden und Adressen. Deren Wertigkeit ist n:m, denn ein Kunde kann ja mehrere Adressen haen und unter einer Adresse wohnen u.U. mehrere Kunden (Mehrfamilienhäuser). Es wird also eine Verbindungsrelation Kunden/Adressen benötigt. Sie wird KuAdr genannt: |
|
KuAdr (#(KuNr, AdrNr)) |
|
Beide Attribute wurden gleich als Fremdschlüssel gekennzeichnet. Damit ist im Datenmodell die Beziehung zwischen Kunden und Adressen festgehalten. Die Min-/Max-Angaben sind 1,n : 1,m, da nur Kunden mit Adressen und nur Adresen mit Kunden erfasst werden wollen. |
|
Bleibt noch zu klären, wie festgehalten wird, welche bei einer bestimmten Lieferung die Liefer- und welche die Rechnungsadresse ist. Bisher war diesbezüglich ja einfach die KNr als Fremdschlüssel in ReKöpfe hinterlegt. |
|
Eine sinnvolle Lösung ist, für jede Lieferung die drei Relationen Kunden, Adressen und Rechnungsköpfe zu verknüpfen und bei jeder Verknüpfung festzuhalten, ob es sich um die Liefer- oder die Rechnungsadresse handelt (hier mit dem Attribut Typ). Dann kann es pro Lieferung eine oder zwei solche Verknüpfungen geben, je nachdem, wieviele Adressen der Kunde angegeben hat. Die Relation hat damit drei Fremdschlüssel: |
|
Lieferungen (#(KuNr, AdrNr, ReNr), Typ) |
|
Das Attribut Typ 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. Diese Semantik muss über die Datenbankprogrammierung sichergestellt werden. Die folgende Tabelle zeigt zur Verdeutlichung einige Beispielsdaten: |
|
Lieferungen |
|
ReNr |
KuNr |
AdrNr |
Typ |
1001 |
007 |
2 |
L |
1001 |
007 |
5 |
R |
2002 |
007 |
1 |
R |
2020 |
010 |
1 |
R |
... |
... |
... |
... |
| |
Zur Veranschaulichung wurde in den Daten auch der Fall mit eingefügt, dass unter einer Adresse mehrere Kunden wohnen (Rechnungsnummern 2002 und 2020). |
|
Die Relation KuAdr wird jetzt eigentlich nicht mehr benötigt. Die Beziehung zwischen Kunden und Adressen könnte auch aus Lieferungen gewonnen werden. Da es aber oftmals sinnvoll ist, die Adressen von Kunden auch ohne die Rechnungen/Lieferungen ansprechen zu können, z.B. bei Marketingmaßnahmen oder ganz allgemein im Customer Relationship Management (CRM), soll sie drin bleiben. |
Pragmatik |
Die Wertigkeiten bei der dreistelligen Beziehung Lieferungen ergeben sich - von Lieferungen ausgehend - zu Kunden, Adressen und ReKöpfe wie folgt: Kardinalität 1,1, Min-/Max-Angabe 1,1 : 0,n (falls ein Kunde vor seiner ersten Lieferung erfasst werden kann). |
|
2.14.3 Lösung |
|
Textliche Fassung |
|
Adressen (#AdrNr, PLZ, Ort, Straße, Telefon) |
|
ArtBeschr(#ArtNr, ArtBeschr) |
|
Artikel (#ArtNr, ArtBez, Standort, LiPreis) |
|
KuAdr (#(KuNr, AdrNr)) |
|
Lieferungen (#(KuNr, AdrNr, ReNr), Typ) |
|
Kunden (#KuNr, Anrede, Name, Vorname) |
|
KuTel(#(KuNr, Tel)) |
|
ReKöpfe (#ReNr, ReDatum, KVDAT, Tour, Verkäufer, DatumLief, ZV, MWStB) |
|
RePos (#(ReNr, PosNr), ArtNr, Anzahl) |
|
Grafische Fassung |
|
|
|
Abbildung 2.14-1: Datenmodell Rechnungsstellung Stufe 2 |
|
2.15 Rechnung Stufe 3 |
|
Vgl. zur zeitlichen Dimension auch [Staud 2021, Kapitel 15]. |
|
2.15.1 Anforderungsbeschreibung |
|
Hier geht es um die Änderung eines Datenmodells. Ausgangspunkt ist das Datenmodell Rechnungsstellung aus obiger Aufgabe: |
|
Adressen (#AdrNr, PLZ, Ort, Straße, Telefon) |
|
ArtBeschr(#ArtNr, ArtBeschr) |
|
Artikel (#ArtNr, ArtBez, Standort, LiPreis) |
|
KuAdr (#(KuNr, AdrNr)) |
|
Lieferungen (#(KuNr, AdrNr, ReNr), Typ) |
|
Kunden (#KuNr, Anrede, Name, Vorname) |
|
KuTel(#(KuNr, Tel)) |
|
ReKöpfe (#ReNr, ReDatum, KVDAT, Tour, Verkäufer, DatumLief, ZV, MWStB) |
|
RePos (#(ReNr, PosNr), ArtNr, Anzahl) |
|
Nun soll eine zeitliche Dimension hinzugefügt werden und zwar mit dem Ziel, die Rechnungen der vergangenen Jahre aus der Datenbank heraus reproduzierbar zu halten, auch wenn sich die Stammdaten verändern. Bei einer Rechnungsstellung entstehen ja Daten zum kaufmännischen Vorgang, die auch nicht mehr verändert werden. Z.B. Rechnungsnummer, Rechnungsdatum, Artikelbeschreibung, Positionssummen, Gesamtsumme. Andere Daten werden mit Hilfe der durch das Datenmodell vorgegebenen Struktur im Moment der Rechnungsstellung aus den Datenbeständen geholt: zum Kunden, zu den Artikeln. Genau diese Daten können sich aber nach dem Zeitpunkt der Rechnungsstellung sehr schnell ändern: |
Zeitliche Dimension |
- Der Kunde zieht um, seine Telefonnummer ändert sich, er ändert seinen Namen.
- Die Artikelpreise ändern sich, Artikel verschwinden aus dem Sortiment, ihre Bezeichnung oder auch Beschreibung ändert sich.
|
|
Und so weiter. |
|
2.15.2 Lösungsschritte |
|
Die Lösung besteht darin, die "vergänglichen" Attribute bzw. deren Ausprägungen zum Zeitpunkt der Rechnungsstellung (RZ; Rechnungsstellungszeitpunkt) festzuhalten. Dazu werden diese Attribute an geeigneter Stelle im Datenmodell angelegt und dann in der Datenbank gespeichert. |
|
Die erste Überlegung bei einer solchen Anpassung des Datenmodells ist also, welche Attribute sich im Zeitverlauf ändern können. Von diesen müssen die Attributsausprägungen gerettet werden. In obigem Datenmodell sind dies bezüglich der Kunden: Name, Vorname, PLZ, Ort, Straße. Dies geschieht, indem sie mit dem Zusatz "RZ" zusätzlich aufgenommen werden: |
Zu "rettende" Kundendaten |
- Name-RZ
- Vorname-RZ
- PLZ-RZ
- Ort-RZ
- Straße-RZ
|
|
Hier stehen dann jeweils die Attributsausprägungen des Rechnungsstellungszeitpunkts drin. |
|
In welcher Relation soll man sie unterbringen? Hier hilft die Überlegung, von welcher Determinante diese Attribute funktional abhängig sind. Natürlich von der Rechnungsnummer, also gehören sie in die Relation ReKöpfe. Da sich der Mehrwertsteuersatz ja auch regelmäßig ändert und auf der Rechnung ausgewiesen ist, muss auch er "konserviert" werden. Auch er ist von der Rechnungsnummer funktional abhängig. Somit ergibt sich: |
|
ReKöpfe (#ReNr, ReDatum, KVDAT, Tour, Verkäufer, DatumLief, ZV, MWStB, Name-RZ, VName-RZ, PLZ-RZ, Ort-RZ, Straße-RZ, Tel-RZ, MWStS-RZ) |
|
Folgende "vergänglichen" Attribute bezüglich der Artikel sollten, da sie auf der Rechnung erscheinen, verdoppelt werden: Artikelnummer (ArtNr), Artikelbezeichnung (ArtBez), Listenpreis (LiPreis). Wieder hängen wir das Kürzel RZ an. Der Platz für diese Attributdoppelung ist, auch hier hilft wieder die Überlegung zu den funktionalen Abhängigkeiten und zur Determinante, die Relation Rechnungspositionen: |
Zu "rettende" Artikeldaten |
RePos (#(ReNr, PosNr), ArtNr, Anzahl, ArtNr-RZ, ArtBez-RZ, LiPreis-RZ) |
|
Fassen wir das Vorgehen zusammen. Folgende Schritte sind zu leisten: |
|
- Klären, welche Attribute wegen der notwendigen Reproduzierbarkeit dupliziert werden müssen.
- Feststellen, wo diese Attribute platziert werden können durch Klärung der Frage, wovon sie funktional abhängig sind.
|
|
Damit ergibt sich das folgende Datenmodell. |
|
2.15.3 Lösung |
|
Textliche Fassung |
|
Adressen (#AdrNr, PLZ, Ort, Straße) |
|
ArtBeschr(#ArtNr, ArtBeschr) |
|
Artikel (#ArtNr, ArtBez, Standort, LiPreis) |
|
KuAdr (#(KuNr, AdrNr)) |
|
Lieferungen (#(KuNr, AdrNr, ReNr), Typ) |
|
Kunden (#KuNr, Anrede, Name, Vorname) |
|
KuTel(#(KuNr, Tel)) |
|
ReKöpfe (#ReNr, ReDatum, KVDAT, Tour, Verkäufer, DatumLief, ZV, MWStB, Name-RZ, VName-RZ, PLZ-RZ, Ort-RZ, Straße-RZ, Tel-RZ) |
|
RePos (#(ReNr, PosNr), ArtNr, Anzahl, ArtNr-RZ, ArtBez-RZ, LiPreis-RZ) |
|
RZ : Zeitpunkt der Rechnungsstellung |
|
Grafische Fassung |
Grafisches Datenmodell |
Das grafische relationale Datenmodell bleibt gleich, da die duplizierten Attribute weder Schlüssel noch Fremdschlüssel sind. Mit dieser Methode des Einbindens der zeitlichen Dimension sind die "geretteten" Daten in die operative Datenbank integriert. |
|
Das Befüllen der zeitlich fixierten Attribute erfolgt in der Datenbankprogrammierung. Bei jeder Transaktion (Rechnungserstellung) werden die zeitabhängigen Attribute mit der jeweils aktuellen Attributsausprägung beschrieben. |
Datenbank-programmierung |
2.16 PC-Beschaffung |
|
Vgl. Abschnitt 5.1 für die ER-Modellierung desselben Anwendungsbereichs, allerdings mit etwas anderen Anforderungen. |
|
Mit diesem Beispiel soll vertieft auf das Muster Einzel/Typ hingewiesen werden. Z.B., was die relationalen Verknüpfungen angeht. Eine Verknüpfung auf Typ-Ebene erfasst andere Informationen als auf Einzel-Ebene. |
Einzelgerät vs. Typ |
2.16.1 Anforderungsbeschreibung |
|
In einem Unternehmen soll der Vorgang der PC-Beschaffung durch eine Datenbank festgehalten werden. Folgende Festlegungen ergaben sich in den Interviews, die im Vorfeld mit den Betroffenen geführt wurden: |
|
(1) Jeder PC erhält eine Inventarnummer (InvPC), ebenso die Bildschirme (InvBS). Jedem PC ist ein Bildschirm zugeordnet. Einige Nutzer benötigen für ihre Aufgaben zwei Bildschirme an ihrem PC.
|
|
(2) Für jeden PC wird folgendes festgehalten: der Prozessortyp (Proz), die Größe des Arbeitsspeichers (ArbSp), ob ein optisches Laufwerk (DVD, CD-ROM, usw.) vorhanden ist und welche Bezeichnung und Geschwindigkeit (BezLW bzw. Geschw) es hat. Es können durchaus mehrere optische Laufwerk eines Typs in einen PC eingebaut sein (z.B. zu Archivierungszwecken), so dass auch die Anzahl festgehalten wird. Natürlich gibt es einen Laufwerkstyp durchaus in verschiedenen Rechnern.
|
|
(3) Für alle PC wird festgehalten, ob Programmiersprachen (PS) installiert sind und falls ja, welche. Für die PC der Entwickler wird die hauptsächlich verwendete Entwicklungsumgebung (EntwUmg) festgehalten.
|
|
(4) In diesem Unternehmen wird vor der Übergabe des PC an den Nutzer durch die IT geprüft, ob das Gehäuse, die jeweilige Hauptplatine und die Grafikkarte für die Anforderungen des Nutzers geeignet sind. Falls nicht, werden sie ausgetauscht. Deshalb werden diese drei Komponenten in der Datenbank ausgewiesen. Alle mit ihrer Bezeichnung (BezGH, BezHP, BezGK), die Gehäuse noch mit Größenangaben (Größe), die Hauptplatinen mit der Anzahl der Prozessoren (AnzProz) und die Grafikkarten mit ihrer maximalen Auflösung (Auflösung). Natürlich kommt es vor, dass idetnische Komponenten in mehreren PC eingebaut werden.
|
|
(5) Für jede Festplatte wird die Bezeichnung (BezPl), die Speicherkapazität (Größe) sowie die Zugriffsgeschwindigkeit (Zugriff) erfasst. Jede Festplatte erhält von der IT-Abteilung eine eindeutige Seriennummer (SerNrF), angelehnt an die des Festplattenherstellers und wird ausführlich getestet. Das Ergebnis, ein Qualitätskoeffizient (Qual), wird auch festgehalten. Es kommt durchaus vor, dass ein PC mehrere Festplatten hat, aber nicht umgekehrt.
|
|
(6) Außerdem werden jeweils mit Hilfe einer Kurzbezeichnung (KBezSK) die im PC enthaltenen sonstigen Komponenten (W-LAN-Komponente, Kamera, usw.) festgehalten. Natürlich kommt eine bestimmte Komponente in mehreren PC vor. Außerdem hat ein PC typischerweise mehrere solcher "sonstigen Komponenten".
|
|
(7) Für jeden ins Unternehmen gegebenen PC wird weiterhin festgehalten, wer ihn nutzt, erfasst über die Personalnummer (PersNr), Name, Vorname (VName) sowie Telefonnummer (Tel) und wann er dort eingerichtet wurde (DatEinr). Ein bestimmter PC wird immer von genau einem Angestellten genutzt, ein Angestellter kann bis zu zwei PC zugeordnet bekommen.
|
|
(8) Für Bildschirme wird neben der Bezeichnung (BezBS) noch festgehalten, von welcher Art (Art) sie sind, welchen Durchmesser sie haben (Zoll) und wann sie übergeben wurden (DatÜb).
|
|
2.16.2 Lösungsschritte |
|
Zur Erstellung des Datenmodells werden - Schritt um Schritt - nochmals die Anforderungen betrachtet, jeweils etwas eingerückt. |
|
Jeder PC erhält eine Inventarnummer (InvPC), ebenso die Bildschirme (InvBS). Jedem PC ist ein Bildschirm zugeordnet. Einige Nutzer benötigen für ihre Aufgaben zwei Bildschirme an ihrem PC. |
|
Für jeden PC wird folgendes festgehalten: der Prozessortyp (Proz), die Größe des Arbeitsspeichers (ArbSp), ob ein optisches Laufwerk (DVD, CD-ROM, usw.) vorhanden ist und welche Bezeichnung und Geschwindigkeit (BezLW bzw. Geschw) es hat. Es können durchaus mehrere optische Laufwerk eines Typs in einen PC eingebaut sein (z.B. zu Archivierungszwecken), so dass auch die Anzahl festgehalten wird. Natürlich gibt es einen Laufwerkstyp durchaus in verschiedenen Rechnern. |
|
Für alle PC wird festgehalten, ob Programmiersprachen (PS) installiert sind und falls ja, welche. Für die PC der Entwickler wird die hauptsächlich verwendete Entwicklungsumgebung (EntwUmg) vermerkt. |
|
Da PC nicht nur identifiziert, sondern auch beschrieben werden, stellen sie eine Relation dar. Mit den Attributen, die im Text genannt werden und die "keine Probleme" machen ergibt sich der nachfolgende Erstentwurf. |
Relation PC. |
Die Bildschirme tauchen in diesem Textabschnitt nur mit einem einzigen identifizierenden Attribut auf. Ein Blick weiter nach unten in obigen Anforderungen zeigt aber, dass sie weiter beschrieben werden. Also können wir auch dafür eine Relation anlegen. Außerdem ist angegeben, dass jedem PC ein oder zwei Bildschirme zugeordnet sind. Das macht eine Verbindungsrelation zwischen PC und Bildschirmen nötig (PC_BS-Einzeln). |
BS |
PC (#InvPC, Proz, ArbSp, ...) |
|
PC_BS-Einzeln(#(InvPC, InvBS)) |
|
BS-Einzeln (#InvBS, ...) |
|
Optische Laufwerke |
|
Die optischen Laufwerke werden selbst existent, weil sie identifiziert und beschrieben werden. Zu beachten ist, dass sie auf Typebene erfasst sind, was auch im Schlüssel ("Bezeichnung") zu erkennen ist. Mit der Festlegung, dass ein PC auch mehrere optische Laufwerke enthalten kann, ergibt sich damit: |
Muster Einzel/Typ |
OptLw (#BezLW, Geschw) |
|
OptLw_PC (#(BezLW, InvPC), Anzahl) |
|
Hier gibt es oft Verständnisprobleme: In einem PC können durchaus Laufwerke verschiedener Typen (z.B. eines von Seagate, zwei von IBM) eingebaut sein. Deshalb die Relation OptLw_PC. |
|
Man beachte die eingeschränkte Aussagekraft einer solchen Modellierung. Festgehalten wird nicht, welche konkreten Laufwerke in den PC eingebaut sind, sondern nur, wieviele verschiedene Laufwerkstypen. Schon bei der Angabe eines einzigen Typs können dies beliebig viele konkrete Laufwerke sein. |
|
Programmiersprachen |
|
Die Installation der Programmiersprachen wird durch eine eigene Relation PSInstall festgehalten. Der Schlüssel ergibt sich daraus, dass auf einem PC u.U. mehrere Programmiersprachen eingerichtet sind und eine Programmiersprache auf mehreren PC installiert ist. |
|
PS-Install (#(InvPC, ProgSpr)) |
|
Die Hinweise auf die PC der Entwickler führen zu einer Spezialisierung. Es entsteht eine eigene Relation mit dem zusätzlichen Attribut. |
Muster Gen/Spez |
EntwPC (#InvPC, EntwUmg) |
|
Die Verknüpfung der installierten Programmiersprachen mit den PC erfolgt dann über EntwPC. Vgl. die Abbildung unten. |
|
Bildschirme |
|
Bei den Bildschirmen klärt sich die Modellierungssituation im letzten Teil der Anforderungsliste: |
|
Für Bildschirme wird neben der Bezeichnung (BezBS) noch festgehalten, von welcher Art (Art) sie sind, welchen Durchmesser sie haben (Zoll) und wann sie übergeben wurden (DatÜb). |
|
Damit ergibt sich, dass zu Beginn zu Recht die Einzelinformation zu Bildschirmen angelegt wurde (lag ja auch nahe, angesichts des Schlüssels InvBS). Insgesamt ergeben die Attribute aber auch noch eine Relation mit Typinformation zu den Bildschirmen: |
Muster Einzel/Typ |
BS-Einzeln (#InvBS, BezBS, DatÜb) |
|
BS-Typen (#BezBS, Art, Zoll) |
|
Der Fremdschlüssel ist nötig, damit die Einzelinformationen mit den Typinformationen verknüpft werden können. Der Fremdschlüssel hält fest, zu welchem Bildschirmtyp ein bestimmter Bildschirm gehört. |
|
Komponentenpräzisierung. |
|
Der nächste Abschnitt der Spezifikation legt fest, welche Komponenten auf welche Weise erfasst werden. |
|
In diesem Unternehmen wird vor der Übergabe des PC an den Nutzer durch die IT geprüft, ob das Gehäuse, die jeweilige Hauptplatine und die Grafikkarte für die Anforderungen des Nutzers geeignet sind. Falls nicht, werden sie ausgetauscht. Deshalb werden diese drei Komponenten in der Datenbank ausgewiesen. Alle mit ihrer Bezeichnung (BezGH, BezHP, BezGK), die Gehäuse noch mit Größenangaben (Größe), die Hauptplatinen mit der Anzahl der Prozessoren (AnzProz) und die Grafikkarten mit ihrer maximalen Auflösung (Auflösung). Natürlich kommt es vor, dass identische Komponenten in mehreren PC eingebaut werden. |
|
Da alle drei Komponenten mit ihren Bezeichnungen erfasst werden, liegt Typinformation vor. Es handelt sich um eine 1:n-Beziehung zwischen den PC und Komponenten, woraus sich die Schlüssel ergeben. |
1:n-Beziehung und Muster Einzel/Typ. |
Gehäuse (#(BezGH, InvPC), Größe) |
|
Grafikkarten (#(BezGK, InvPC), Auflösung) |
|
Hauptplatinen (#(BezHP, InvPC), AnzProz) |
|
Festplatten |
|
Auch die Festplatten werden so beschrieben, dass sie eigene Relationen bilden und dass Einzel- und Typinformation vorhanden ist. |
|
Für jede Festplatte wird die Bezeichnung (BezPl), die Speicherkapazität (Größe) sowie die Zugriffsgeschwindigkeit (Zugriff) erfasst. Jede Festplatte erhält von der IT-Abteilung eine eindeutige Seriennummer (SerNrF), angelehnt an die des Festplattenherstellers und wird ausführlich getestet. Das Ergebnis, ein Qualitätskoeffizient (Qual), wird auch festgehalten. Es kommt durchaus vor, dass ein PC mehrere Festplatten hat, aber nicht umgekehrt. |
|
Es ergeben sich die entsprechenden Relationen. Hier soll zusätzlich der Frage nachgegangen werden, wie in einem solchen Fall - wenn also Einzel- und Typinformation vorliegt - die Verknüpfung mit dem restlichen Modell (hier PC) vorgenommen wird. Grundsätzlich ist beides möglich, allerdings ist die Verknüpfung mit Typinformation ungenau. Dabei würde nur erfasst, welcher Plattentyp in einem PC installiert ist. Wird dagegen mit Hilfe der Einzelinformation verknüpft, kann genau festgehalten werden, welche und wieviele Festplatten im PC sind. Deshalb wird hier dieseVorgehensweise gewählt. Da eine einzelne Festplatte nur in einem einzigen PC sein kann, handelt es sich um eine 1:n-Beziehung, die durch den Fremdschlüssel InvPC in FP-Einzeln ausgedrückt wird. |
Verknüpfung? |
FP-Einzeln (#SerNrF, Qual, BezPL, InvPC) |
|
FP-Typen (#BezPl, Größe, Zugriff) |
|
Komponenten |
|
Außerdem werden jeweils mit Hilfe einer Kurzbezeichnung (KBezSK) die im PC enthaltenen sonstigen Komponenten (W-LAN-Komponente, Kamera, usw.) festgehalten. Natürlich kommt eine bestimmte Komponente in mehreren PC vor. Außerdem hat ein PC typischerweise mehrere solcher "sonstigen Komponenten". |
|
Auch hier wird wieder auf Typebene modelliert, so dass sich die folgende Relation ergibt. |
|
SK (#(KBezSK, InvPC)) //SK : Sonstige Komponenten |
|
Nutzung |
|
Abschließend wird in der Spezifikation beschrieben, wie die Nutzung und Einrichtung datenbankmäßig modelliert wird. |
|
Für jeden ins Unternehmen gegebenen PC wird weiterhin festgehalten, wer ihn nutzt, erfasst über die Personalnummer (PersNr), Name, Vorname (VName) sowie Telefonnummer (Tel) und wann er dort eingerichtet wurde (DatEinr). Ein bestimmter PC wird immer von genau einem Angestellten genutzt, ein Angestellter kann bis zu zwei PC zugeordnet bekommen. |
|
Die Nutzer werden über die Personalnummer erfasst und durch einige weitere Attribute beschrieben, weshalb für sie eine Relation eingerichtet wird.. |
|
Nutzer (#PersNr, Name, VName, Tel) |
|
Bleibt die Einrichtung des PC. Angesichts der Festlegung der Min-/Max-Angaben wird das Attribut PersNr zu einem Bestandteil von PC. Auch das Datum der Einrichtung kann in diese Relation eingefügt werden, die sich damit wie folgt ergibt: |
|
PC (#InvPC, Proz, ArbSp, PersNr, DatEinr) |
|
Damit sind die Relationen des Datenmodells zusammengestellt. Auch die relationalen Verknüpfungen sind schon angelegt. |
|
Kardinalitäten und Min-/Max-Angaben |
|
Alle Kardinalitäten und Min-/Max-Angaben sind in der Abbildung unten eingetragen. Aufzupassen ist da bei den Angaben mit Relationen auf Typ-Ebene. Ein Wert "1" bedeutet hier bei Geräten nur "ein Typ", z.B. ein Bildschirmtyp (Eizo xyz). Konkret können da mehrere Geräte vorliegen. |
|
Normalformen |
|
Es wurde schon bei der Erstellung darauf geachtet, dass a) keine Mehrfacheinträge vorliegen und b) die in Abschnitt 4.7 beschriebene Idealform für Relationen realisiert ist: Ein Schlüssel und nur Attribute, die von ihm voll funktional abhängig sind. Deshalb ist die höchste Normalform erreicht. |
|
2.16.3 Lösung |
|
Textliche Fassung |
|
BS-Einzeln (#InvBS, BezBS, DatÜb) |
|
BS-Typen (#BezBS, Art, Zoll) |
|
EntwPC (#InvPC, EntwUmg) |
|
FP-Einzeln (#SerNrF, Qual, BezPL, InvPC) |
|
FP-Typen (#BezPl, Größe, Zugriff) |
|
Gehäuse (#(BezGH, InvPC), Größe) |
|
Grafikkarten (#(BezGK, InvPC), Auflösung) |
|
Hauptplatinen (#(BezHP, InvPC), AnzProz) |
|
Nutzer (#PersNr, Name, VName, Tel) |
|
OptLw (#BezLW, Geschw) //Typebene |
|
OptLw_PC (#(BezLW, InvPC), Anzahl) //Typebene |
|
PC (#InvPC, Proz, ArbSp, PersNr, DatEinr) |
|
PSInstall (#(InvPC, ProgSpr)) |
|
SK (#(KBezSK, InvPC)) //Sonstige Komponenten |
|
|
|
Grafische Fassung |
|
|
|
Abbildung 2.16-1: Datenmodell PC-Beschaffung |
|
|
|
|
|
|
|
Weitere Aufgaben zur Datenmodellierung sind im folgenden Kapitel. Dort werden sie allerdings bis zur Einrichtung der Datenbank weitergeführt. |
|
|
|
3 RelDB - Von der Anforderung zur Datenbank |
|
Zwei Schritte des Gesamtwegs: Anforderungen - Datenmodell (Schema) - Datenbank - Web-Benutzeroberfläche |
|
Die Aufgaben dieses Kapitel beziehen sich auf die ersten beiden Schritte des Gesamtwegs, von der Anforderungsbeschreibung zum Datenmodell und weiter zur Datenbank. |
|
Für die SQL-Befehle wurde MySQL (Xampp Control Panel v3.2.4) genutzt. In anderen SQL-Dialekten sind zum Teil andere Bezeichnungen, Befehlsstrukturen, usw. realisiert. In diesem einführenden Kontext betrifft dies evtl. Bezeichnungen von Datentypen und die Gestaltung der verschiedenen JOIN-Varianten. |
|
Die Beispiele sind aus Kapazitäts- und Platzgründen einfach und klein gehalten, reichen aber aus, in die Methoden einzuführen und für größere Aufgaben vorzubereiten. |
|
Folgendes ist zu leisten: |
|
- Erstellung des Datenmodells.
- In einigen Fällen: Erstellen von FA-Diagrammen
- Erstellung der Datenbank
- Einfüllen von Daten
- Formulieren einiger Abfragen im jeweils angegebenen Umfang
|
|
|
|
3.1 Rechnungen/Kunden |
|
3.1.1 Anforderungsbeschreibung |
|
Es geht, stark vereinfacht, um die Verwaltung von Rechnungen von Kunden. Erfasst werden sollen die Rechnungen mit ihren Positionen und dem Rechnungsdatum (ReDatum). Außerdem die Artikel, die in den Rechnungspositionen auftauchen mit ihrer Anzahl. Für die Artikel werden eine Beschreibung, der Preis und der Standort der Ware im Lager erfasst. Für die Kunden werden Name, Vorname, Postleitzahl (PLZ), Ort, Straße und ein Festnetztelefonanschluss (FestTelefon) sowie ein Mobiltelefon (MobilTelefon) erfasst. Von einem Kunden werden maximal zwei Adressen in die Datenbank genommen. |
Vgl. Abschnitt 1.2 zur Typographie |
3.1.2 Lösungsschritte |
|
Relationen festlegen |
|
Sofort erkennbar als Relationen ("Identifikation + Beschreibung") sind Rechnungen, Artikel und Kunden. |
|
Für die Rechnungen wird eine Rechnungsnummer (ReNr) ergänzt und als Schlüsselattribut gewählt. Das Rechnungsdatum kommt hinzu (ReDatum). Bei den Positionen ergibt sich ein Problem. Wie wir wissen hat eine Rechnung typischerweise mehrere Positionen, auf denen die gekauften Artikel vermerkt sind - je einer pro Position. Also müssen die Positionen getrennt verwaltet werden. Wir teilen daher das Realweltphänomen Rechnung auf in Rechnungsköpfe (RechKöpfe) und Rechnungspositionen (RechPos). |
Rechnungen |
In die Relation RechKöpfe kommen erstmal die Attribute ReNr und ReDatum: |
RechKöpfe |
RechKöpfe(#ReNr, ReDatum) |
|
Für die Rechnungspositionen (RechPos) führen wir eine Positionsnummer ein (PosNr). Dieses Ergänzen von Attributen ist zulässig und auch immer wieder notwendig. Auch die Artikelnummer des Artikels (ArtNr), der auf der Position auftaucht (immer nur einer, normalerweise), wird hinzugefügt. Er wird Fremdschlüssel und leistet die Verknüpfung mit der später zu erstellenden Relation zu Artikeln (vgl. unten). Hinzugefügt wird noch die Anzahl der Artikel in der Position. Die Artikelbeschreibung wird deshalb nicht einfach bei den Positionen angeführt, weil (hoffentlich) derselbe Artikel auf mehreren Positionen auftaucht, was dann zu Redundanzen und zu einem Verstoß gegen die 3NF führen würde. |
|
Erinnerung: |
|
Schlüssel: identifizierendes Attribut bzw. identifizierende Attributskombination |
|
Schlüsselattribut: Attribut eines Schlüssels |
|
Nichtschlüsselattribut: die übrigen Attribute einer Relation |
|
Fremdschlüssel: ein Attribut, das der relationalen Verknüpfung dient. Es ist in "seiner" Relation nicht Schlüssel, aber in der anderen zu verknüpfenden Relation. |
|
Mehr dazu in [Staud 2021, Abschnitt 8.2] |
|
Bleibt noch der unabdingbare Schlüssel. Die Positionsnummer kann es nicht sein, denn diese wiederholt sich über die Rechnungen hinweg. Nehmen wir allerdings die Rechnungsnummer dazu, entsteht Eindeutigkeit. Die Kombination aus ReNr und PosNr ergibt den zusammengesetzten Schlüssel. Das darin enthaltene Attribut ReNr ist Fremdschlüssel, es leistet die Verknüpfung mit der Relation RechKöpfe: |
|
RechPos (#(ReNr, PosNr), ArtNr, Anzahl) |
RechPos |
Anmerkungen: |
|
- Auf die Positionsnummer könnte verzichtet werden. Dann wird hier stattdessen die Artikelnummer gewählt. |
|
- Schlüssel sind unabdingbar. Wenn sie in den Anforderungen vergessen werden, sind sie zu ergänzen. |
|
Die Beziehung zwischen Rechungsköpfen und -positionen hat die Kardinalitä 1:n und die Min-/Max-Angaben 1,n : 1,1. Es liegt also Existenzabhängigkeit (eine Komposition) vor. Mehr dazu unten. |
|
Für die Kunden führen wir als Schlüssel eine Kundennummer ein (KuNr). Wir fügen Name und Vorname hinzu und ebenfalls den Mobilanschluss, denn dieser ist personenspezifisch, d.h. diese Information ist funktional abhängig vom Kunden, nicht von seiner Adresse. Damit ergibt sich: |
Kunden |
Kunden(#KuNr, Name, Vorname, MobilTelefon) |
|
Normalerweise würden wir hier die Adressattribute ergänzen. Da es aber nach der Anforderungsbeschreibung mehr als eine Adresse je Kunde geben kann, müssen die Adressangaben in einer eigenen Relation verwaltet werden (keine Mehrfacheinträge!). Wir legen wieder einen Schlüssel fest, eine Adressnummer (AdrNr): |
Adressen |
Adressen (#AdrNr, PLZ, Ort, Straße, FestTelefon) |
|
FestTelefon wurde zu den Adressen genommen, weil ein Festnetztelefon ortsspezifisch ist, d.h., dieses Attribut ist funktional abhängig von den Adressen. |
|
Als letztes sind noch die Artikel zu klären. Für sie werden in der Beschreibung eine Beschreibung, der Preis und der Standort der Ware im Lager (Standort) verlangt. Wir ergänzen noch den oben schon angelegten Schlüssel, Artikelnummer (ArtNr), und erhalten damit: |
Artikel |
Artikel (#ArtNr, Beschreibung, Preis, Standort) |
|
Insgesamt liegen damit folgende Relationen vor: |
|
Adressen (#AdrNr, PLZ, Ort, Straße, FestTelefon) |
|
Artikel (#ArtNr, Beschreibung, Preis, Standort) |
|
Kunden(#KuNr, Name, Vorname, MobilTelefon) |
|
RechKöpfe(#ReNr, ReDatum . . . |
|
RechPos (#(ReNr, PosNr), ArtNr, Anzahl) |
|
Restliche Verknüpfungen |
|
Eine wichtige relationale Verknüpfung wurde oben schon eingefügt, die Komposition zwischen Rechnungsköpfen und -positionen. Denn es gilt: Eine Rechnung hat mindestens eine Position und eine Position gehört zu genau einer Rechnung. Es liegt also eine 1 :n-Beziehung zwischen Rechnungsköpfen und Rechnungspositionen vor. Der oben angelegte zusammengesetzte Schlüssel (ReNr, PosNr) drückt diese Existenzabhängigkeit aus, da durch den zusammengesetzten Schlüssel festgelegt wird, dass jede Rechnungsposition auch zu einem Rechnungskopf gehören muss (Komposition). |
Komposition |
Verknüpfungen sind oft nicht explizit in den Anforderungsbeschreibungen enthalten, sondern müssen aus der Semantik des Anwendungsbereichs oder von der Methodik abgeleitet werden. Hier z.B. für die Verknüpfung von Rechnungen und Kunden. Für diese gilt folgende Semantik: Jede Rechnung gehört zu genau einem Kunden. Ein Kunde kann mehrere Rechnungen haben. Eine solche 1:n-Verknüpfung zwischen Kunden und Rechnungen wird mit den Min-/Max-Angaben 0,n : 1,1 oder 1,n : 1,1 so umgesetzt: Die Kundennummer (KuNr) wird der Relation Rechnungsköpfe als Fremdschlüssel hinzugefügt: |
Rechnungen und Kunden |
RechKöpfe(#ReNr, KuNr, ReDatum) |
|
Die Verknüpfung zwischen den Artikeln und Rechnungspositionen beruht ebenfalls auf einer 1:n-Verknüpfung: auf einer Rechnungsposition ist genau ein Artikel, ein Artikel kann auf mehreren Positionen auftreten. Die Min-/Max-Angaben (Artikel/Rechnungspositionen) sind entsprechend 0,n : 1,1. Dies wurde bereits oben durch Einfügen der Artikelnummer (ArtNr) in die Relation RechPos realisiert. ArtNr ist dort Fremdschlüssel. |
Artikel und Rechnungs-positionen |
RechPos (#(ReNr, PosNr), ArtNr, Anzahl) |
|
Bleibt noch die Verbindung von Kunden und Adressen. Hier wird in der Anforderungsbeschreibung ausgeführt, dass jeder Kunde in der Datenbank zwei Adressen haben kann. Z.B. eine Liefer- und eine Rechnungsadresse. Dies wäre eine 1:n-Beziehung. Da wir aber gleich noch berücksichtigen, dass unter einer Adresse mehrere Kunden wohnen können, wird diese Beziehung zu einer n:m-Beziehung und bedarf einer eigenen Relation, einer Verbindungsrelation. Wenn wir festlegen, dass ein Kunde nur angelegt wird, wenn mindestens eine Adresse vorliegt und eine Adresse nur, wenn sie tatsächlich zu einem Kunden gehört, sind die Min-/Max-Angaben (Kunden/Adressen) 1,2 : 1,m. |
Kunden und Adressen |
Dies führt zu einer Relation Kundenadressen (KuAdr). Sie hat den zusammengesetzten Schlüssel aus Adressnummer und Kundenummer : |
|
KuAdr (#(AdrNr, KuNr)) |
|
Restliche Prüfung |
|
Die gefundenen Relationen sind in der jeweils letzten Fassung vollständig. Es müssen keine weiteren Attribute ergänzt werden, wir können die Relationenbeschreibungen schließen. |
|
Sie sind auch alle bereits in der höchsten Normalform: Es gibt einen Schlüssel und weitere Attribute, die nur von diesem vollumfänglich funktional abhängig sind (BCNF). Probleme mit der 4NF und 5NF gibt es augenscheinlich nicht. Vgl. auch die FA-Diagramme unten. |
|
3.1.3 Lösung |
|
Damit ergibt sich folgendes Datenmodell. |
|
Textliche Notation |
|
Adressen(#AdrNr, PLZ, Ort, Straße, FestTelefon) |
|
Artikel (#ArtNr, Beschreibung, Preis, Standort) |
|
KuAdr (#(AdrNr, KuNr)) |
|
Kunden(#KuNr, Name, Vorname, MobilTelefon) |
|
RechKöpfe(#ReNr, ReDatum, KuNr) |
|
RechPos(#(PosNr, ReNr), ArtNr, Anzahl) |
|
Grafische Notation |
|
Die Frage, ob wirklich alle Verknüpfungen umgesetzt wurden, beantwortet sehr anschaulich die grafische Ausprägung des Datenmodells. |
|
|
|
Abbildung 3.1-1: Relationales Datenmodell Rechnungen/Kunden |
|
3.1.4 FA - Diagramme |
|
Eine Einführung in FA-Diagramme findet sich in [Staud 2021, Kapitel 8] und http://www.staud.info/rm1/rm_t_1.htm#Kapitel9 |
|
Oftmals ist die Betrachtung der funktionalen Abhängigkeiten der Relationen von großem Nutzen. Sie zeigen insbesondere auf, ob wirklich die höchste Normalform bei den Relationen erreicht wurde. |
|
Aufgabe |
|
Erstellen Sie für alle Relationen des Datenmodells ein FA-Diagramm. |
|
Lösung |
|
|
|
Abbildung 3.1-2: FA-Diagramme der Relationen zum Datenmodell Rechnungen/Kunden. |
|
Die FA-Diagramme zeigen, dass tatsächlich alle Relationen in der höchsten Normalform sind. |
|
3.1.5 Umsetzung mit mySQL |
|
Aufgabe |
|
- Erstellen Sie zu diesem Datenmodell die Datenbank mit SQL-Befehlen.
- Füllen Sie Demo-Daten ein, in denen die Verknüpfungen sichtbar werden.
- Führen Sie dann Auswertungen aus, auch über die relationalen Verknüpfungen.
|
|
Lösung |
|
Datenbank und Relationen einrichten |
|
Die Datenbank soll ReKu (Rechnungen/Kunden) genannt werden. Umlaute werden umgewandelt. Einige Attributsbezeichnungen wurden gekürzt. |
|
Aufpassen: Reihenfolge beachten. Bei Verknüpfungen zuerst die Relation mit dem Schlüssel, dann die mit dem Fremdschlüssel. |
|
Der folgende Befehl legt die Datenbank an: |
|
create database reku default character set latin1 collate latin1_german1_ci;
|
|
Nun die Relationen: |
|
Relation Kunden |
|
Kunden(#KuNr, Name, Vorname, MobilTelefon) |
|
create table kunden (KuNr smallint(5), name char(10), vorname char(10), mobil char(12), primary key (KuNr));
|
|
Anzeige der Struktur der Relation |
|
Die untenstehende Abbildung zeigt einen Teil der Tabelle, die mySQL zur Struktur der Relation ausgibt. Das Schlüsselsymbol in gelb (farbig nur in der Web-Version, nicht in den Print-Versionen) gibt einen Primärschlüssel an. Für diesen wird hier standardmäßig die BTREE-Architektur verwendet. |
|
|
|
|
|
Relation Artikel |
|
Artikel (#ArtNr, Beschreibung, Preis, Standort) |
|
create table artikel (ArtNr smallint(4), beschreibung varchar(10), preis decimal(7,2), standort char(5), primary key (ArtNr));
|
|
Anzeige der Relationenstruktur |
|
|
|
|
|
Relation Adressen |
|
Adressen(#AdrNr, PLZ, Ort, Straße, FestTelefon) |
|
create table adressen (AdrNr smallint(7), plz char(5), ort char(10), strasse char(10), FestTelefon char(15), primary key (adrnr));
|
|
Anzeige der Relationenstruktur |
|
|
|
|
|
Relation RechKoepfe |
|
RechKöpfe(#ReNr, ReDatum, KuNr) |
|
create table RechKoepfe (ReNr smallint(6), KuNr smallint(5), primary key (ReNr), ReDatum date, foreign key (KuNr) references kunden(KuNr))
|
|
Anzeige der Relationenstruktur |
|
|
|
|
|
Relation RechPos |
RechPos |
RechPos(#(PosNr, ReNr), ArtNr, Anzahl) |
|
create table RechPos (ReNr smallint(6), PosNr tinyint(3) unsigned, ArtNr smallint(4), anzahl smallint(2),
|
|
primary key (ReNr, PosNr),
|
|
foreign key (ArtNr) references artikel(ArtNR),
|
|
foreign key (ReNr) references RechKoepfe(ReNr));
|
|
Anzeige der Relationenstruktur |
|
|
|
|
|
Relation KuAdr |
KuAdr |
KuAdr (#(AdrNr, KuNr)) |
|
create table KuAdr (AdrNr smallint(7), KuNr smallint(5),
|
|
primary key (adrnr, kunr),
|
|
foreign key (kunr) references kunden(kunr),
|
|
foreign key (adrnr) references adressen(adrnr));
|
|
Anzeige der Relationenstruktur |
|
|
|
|
|
|
|
3.1.6 Einfüllen von Daten |
|
[Falls wegen Fehlern Wiederholung nötig ist, vorab: delete from kunden;] |
|
Relation Kunden |
|
insert into kunden (KuNr, Name, Vorname) values (1007, 'Aberer', 'Anton');
|
|
insert into kunden (KuNr, Name, Vorname) values (1008, 'Blauer', 'Guiseppe');
|
|
insert into kunden (KuNr, Name, Vorname) values (1009, 'Cäser', 'Filippa');
|
|
insert into kunden values (1010, 'Dodolo', 'Rita', '1234567890');
|
|
insert into kunden values (1011, 'Steiner', 'Sepp', '2345678901');
|
|
select * from kunden;
|
|
#KuNr |
name |
vorname |
mobil |
1007 |
Aberer |
Anton |
NULL |
1008 |
Blauer |
Guiseppe |
NULL |
1009 |
Cäser |
Filippa |
NULL |
1010 |
Dodolo |
Rita |
1234567890 |
1011 |
Steiner |
Sepp |
2345678901 |
| |
Relation Adressen
|
|
Insert into adressen (AdrNr, plz, ort) values (1001, '88333', 'Waldhausen');
|
|
Insert into adressen (AdrNr, plz, ort, strasse) values (1011, '99333', 'Buchen', 'Am Baum 7');
|
|
Insert into adressen values (2011, '11111', 'Karlstadt', 'Hauptstr. 77', '111-2222');
|
|
Select * from adressen;
|
|
#AdrNr |
plz |
ort |
strasse |
FestTelefon |
1001 |
88333 |
Waldhausen |
NULL |
NULL |
1011 |
99333 |
Buchen |
Am Baum 7 |
NULL |
2011 |
11111 |
Karlstadt |
Hauptstr. |
111-2222 |
| |
Relation KuAdr
|
|
insert into KuAdr values (1001, 1007);
|
|
insert into KuAdr values (2011, 1007);
|
|
insert into KuAdr values (1001, 1008);
|
|
insert into KuAdr values (1011, 1009);
|
|
insert into KuAdr values (2011, 1010);
|
|
select * from KuAdr;
|
|
AdrNr |
KuNr |
1001 |
1007 |
1001 |
1008 |
1011 |
1009 |
2011 |
1010 |
2011 |
1010 |
| |
#(AdrNr, KuNr) |
|
Auch die Verknüpfung von kunden und adressen über kuadr klappt: |
|
select k.kunr, k.name, k.vorname, k.mobil, a.adrnr, a.plz, a.ort, a.strasse
|
|
from kunden k, adressen a, kuadr v
|
|
where k.kunr=v.kunr and a.adrnr=v.adrnr;
|
|
kunr |
name |
vorname |
mobil |
adrnr |
plz |
ort |
strasse |
1007 |
Aberer |
Anton |
NULL |
1001 |
88333 |
Waldhausen |
NULL |
1008 |
Blauer |
Guiseppe |
NULL |
1001 |
88333 |
Waldhausen |
NULL |
1009 |
Cäser |
Filippa |
NULL |
1011 |
99333 |
Buchen |
Am Baum 7 |
1007 |
Aberer |
Anton |
NULL |
2011 |
11111 |
Karlstadt |
Hauptstr. |
1010 |
Dodolo |
Rita |
1234567890 |
2011 |
11111 |
Karlstadt |
Hauptstr. |
| |
Relation Artikel
|
|
insert into artikel values (100, 'Gamer-PC', 2500.00, 'ST007');
|
|
insert into artikel values (101, 'Büro-PC', 1200.00, 'ST018');
|
|
insert into artikel values (102, 'Entwickler-PC', 3200.00, 'ST100');
|
|
select * from artikel;
|
|
#ArtNr |
beschreibung |
preis |
standort |
100 |
Gamer-PC |
2500.00 |
ST007 |
101 |
Büro-PC |
1200.00 |
ST018 |
102 |
Entwickler |
3200.00 |
ST100 |
| |
Relation RechKoepfe
|
|
insert into rechkoepfe values (23001, 1007, '2023-03-27');
|
|
insert into rechkoepfe values (23010, 1009, '2023-05-20');
|
|
select * from rechkoepfe;
|
|
#ReNr |
KuNr |
ReDatum |
23001 |
1007 |
2023-03-27 |
23010 |
1009 |
2023-05-20 |
| |
Relation RechPos
|
|
insert into rechpos values (23001, 1, 100, 1);
|
|
insert into rechpos values (23001, 2, 101, 2);
|
|
insert into rechpos values (23001, 3, 100, 1);
|
|
insert into rechpos values (23010, 1, 101, 3);
|
|
insert into rechpos values (23010, 2, 102, 1);
|
|
Select * from rechpos;
|
|
ReNr |
PosNr |
ArtNr |
anzahl |
23001 |
1 |
100 |
1 |
23001 |
2 |
101 |
2 |
23001 |
3 |
100 |
1 |
23010 |
1 |
101 |
3 |
23010 |
2 |
102 |
1 |
| |
#(ReNr, PosNr) |
|
|
|
3.1.7 Abfragen |
|
Aufgabe |
|
Gib alle Rechnungen mit rechnungsrelevanten Daten aus. Ohne doppelte Attribute wg. Schlüssel/Fremdschlüssel. Die Sortierung soll aufsteigend nach Rechnungsnummer und Positionsnummer erfolgen. |
|
Lösung |
|
select rk.renr as ReNr, rk.kunr as KuNr, rk.redatum as ReDatum,
|
|
rp.posnr as Position, rp.artnr as ArtNr, rp.anzahl as Anzahl,
|
|
a.beschreibung as Beschreibung, a.preis as Preis
|
|
from rechkoepfe rk, rechpos rp, artikel a
|
|
where rk.renr=rp.renr and rp.artnr=a.artnr
|
|
order by rk.renr, rp.posnr;
|
|
|
|
ReNr |
KuNr |
ReDatum |
Position |
ArtNr |
Anzahl |
Beschreibung |
Preis |
23001 |
1007 |
2023-03-27 |
1 |
100 |
1 |
Gamer-PC |
2500.00 |
23001 |
1007 |
2023-03-27 |
2 |
101 |
2 |
Büro-PC |
1200.00 |
23001 |
1007 |
2023-03-27 |
3 |
100 |
1 |
Gamer-PC |
2500.00 |
23010 |
1009 |
2023-05-20 |
1 |
101 |
3 |
Büro-PC |
1200.00 |
23010 |
1009 |
2023-05-20 |
2 |
102 |
1 |
Entwickler |
3200.00 |
| |
Aufgabe
|
|
Erstelle eine Liste aller Kunden mit ihren Adressen ohne doppelte Attribute. Ohne doppelte Attribute wg. Schlüssel/Fremdschlüssel. |
|
Lösung |
|
select k.kunr as KuNr, k.name as Name, k.vorname as Vorname,
|
|
k.mobil as MobilTel, a.plz as PLZ, a.ort as Ort, a.strasse as
|
|
Straße,a.festtelefon as Festnetz
|
|
from kunden k, adressen a, kuadr ka
|
|
where k.kunr=ka.kunr and ka.adrnr=a.adrnr;
|
|
|
|
KuNr |
Name |
Vorname |
MobilTel |
PLZ |
Ort |
Straße |
Festnetz |
1007 |
Aberer |
Anton |
NULL |
88333 |
Waldhausen |
NULL |
NULL |
1008 |
Blauer |
Guiseppe |
NULL |
88333 |
Waldhausen |
NULL |
NULL |
1009 |
Cäser |
Filippa |
NULL |
99333 |
Buchen |
Am Baum 7 |
NULL |
1007 |
Aberer |
Anton |
NULL |
11111 |
Karlstadt |
Hauptstr. |
111-2222 |
1010 |
Dodolo |
Rita |
1234567890 |
11111 |
Karlstadt |
Hauptstr. |
111-2222 |
| |
3.2 Haushaltsgeräte |
|
Auch bei dieser Aufgabe soll nicht nur das relationale Datenmodell erstellt werden, sondern auch die Datenbank selbst mit mySQL. Anschließend soll eine der n:m-Beziehungen mit Daten befüllt werden. Diese soll mit SQL abgefragt werden, zuerst in einfacher Form, dann mit sortierten Attributen, Spaltenüberschriften, Vermeidung doppelter Spalten und Sortierung. |
|
3.2.1 Anforderungsbeschreibung |
|
Es geht um Haushaltsgeräte in einem Einzelhandelsgeschäft (vereinfacht), die in einer Datenbank erfasst werden sollen. |
|
Für jedes Haushaltsgerät wird die Bezeichnung (Bez) erfasst, z.B. Staubsauger XYZ. Außerdem der Hersteller (Hersteller), der Listenpreis (LPreis) und die Anzahl der Geräte im Lager (AnzLager). Jedes einzelne Gerät erhält eine Gerätenummer (GNr) und es wird festgehalten, wann es hergestellt wurde (MonatHerst; Monat Herstellung) und wann es ins Lager kam (LagAufn). |
|
Für Staubsauger wird zusätzlich festgehalten, welche Saugkraft sie haben und von welchem Typ sie sind (mit Beutel, ohne, . . .). Für Kaffemaschinen, welche Wassermenge sie maximal verarbeiten können (MengeWasser) und in welcher Zeit sie einen halben Liter Kaffee kochen (Geschw). |
|
Von den Kunden werden Name und Vorname (VName) erfasst und sie erhalten eine Kundennummer (KuNr). Jeder Kunde kann beliebig viele Adressen (PLZ, Ort, Straße) besitzen. Die Erfahrung hat gezeigt, dass unter einer Adresse u.U. mehrere Kunden wohnen (Mehrfamilienhaus, Studierendenwohnheim, . . .), dies soll datenbanktechnisch festgehalten werden. |
|
Kunden haben inzwischen oft mehrere Telefone (Festnetz und mobil). Diese werden alle erfasst. Es kommt vor, dass unter einer Telefonnummer mehrere Kunden zu erreichen sind (z.B. bei einer Familie). |
|
Beim Verkauf eines Gerätes wird festgehalten, an welchen Kunden das Gerät verkauft wurde. Außerdem das Datum und der tatsächlich erzielte Preis (ErzPreis). Dieser weicht oft vom Listenpreis ab, weil z.B. Nachlässe gegeben werden. |
|
3.2.2 Lösungsschritte |
|
Die Haushaltsgeräte (HG) sind gleich als Relation erkennbar. Sie werden durch die Gerätenummer (GNr) identifiziert und durch zahlreiche weitere Attribute beschrieben: |
|
HG (#GNr, Bez, Hersteller, LPreis, AnzLager, MonatHerst, LagAufn, . . . |
|
Ein wenig Unbehagen erzeugt diese Relation allerdings. Werden hier nicht Informationen mehrfach erfasst? Z.B. der Hersteller und der Listenpreis für alle identischen Geräte? Genauso ist es und etwas Erinnerung an die Theorie führt zu dem Ergebnis, dass hier ein Muster Einzel/Typ vorliegt. Hier Einzelgeräte vs. Gerätetypen. Bei Tieren z.B. das einzelne Tier und die jeweilige Gattung. Ein wichtiges Muster unserer Realwelt, das beim Modellieren oft übersehen wird. Vgl. [Staud 2021, Abschnitt 14.2]. Obige Relation würde also viele Redundanzen aufweisen. Die Lösung besteht darin, zwei Relationen anzulegen, HG-Einzeln und HG-Typen. |
Hausgeräte (HG) |
Beginnen wir mit HG-Einzeln. Die einzelnen Geräte werden durch die Gerätenummer (GNr) identifiziert und als Einzelgeräte durch den Monat der Herstellung (MonatHerst) und die Lageraufnahme (LagAufn) beschrieben: |
Muster Einzel/Typ |
HG-Einzeln (#GNr, MonatHerst, LagAufn) |
|
Die Geräte als Typen erhalten Bez als Schlüssel und die Attribute Hersteller, LPreis und AnzLager als beschreibende Attribute: |
|
HG-Typen (#Bez, Hersteller, LPreis, AnzLager) |
|
Bleibt noch die Verknüpfung dieser Einzel- und Gerätetyp-Informationen. Diese erfolgt wie meist durch Schlüssel/Fremdschlüssel. Beim Muster Einzel/Typ ist es immer so, dass bei der Einzelinformation der Schlüssel der zugehörigen Typinformation eingefügt wird: |
|
HG-Einzeln (#GNr, MonatHerst, LagAufn, Bez) |
|
Umgekehrt wäre es nicht möglich, da dies zu Mehrfacheinträgen führen würde. Die Kardinalität ist (von HG-Einzeln ausgehend) n:1, die Min-/Max-Angaben sind 1,1 : 0,n: |
|
- Jedes individuelle Hausgerät gehört zu genau einem Gerätetyp
- Zu einem Gerätetyp gehören mehrere Einzelgeräte oder auch keines mehr, nach dem Verkauf des Letzten.
|
|
In der Anforderungsbeschreibung werden dann Staubsauger und Kaffeemaschinen angeführt. Sie sind auch Geräte, erhalten aber zusätzliche Attribute: Staubsauger Saugkraft und Typ, Kaffemaschinen MengeWasser und Geschw. Damit liegt eine Generalisierung / Spezialisierung vor. Vgl. oben sowie [Staud 2021, Abschnitt 14.1]. |
|
In beiden Fällen sind die Attribute auf Typebene: alle einzelnen Kaffeemaschinen haben das Attribut MengeWasser, usw. Insofern gehören sie zur Relation HG-Typen. Ergänzen wir nun aber einfach die Relation HG-Typen um diese Attribute, gibt es das Problem, dass bestimmte Attribute nicht für alle Objekte Gültigkeit haben. Staubsauger haben z.B. nicht die Attribute von Kaffemaschinen, Kühlgeräte weder die von Staubsaugern noch von Kaffeemaschinen, usw. Es gibt also semantische bedingte Leereinträge, die in Datenbeständen absolut unerwünscht sind (vgl. [Staud 2021, S. 180ff]). Die Ursache liegt in der hier vorliegenden Generalisierung / Spezialisierung (Gen/Spez). Diese verlangt für eine korrekte Modellierung, dass die Spezialisierungen (hier: Staubsauger und Kaffeemaschinen) in eigenen Relationen erfasst und mit der Generalisierung (hier: HG-Typen) verknüpft werden. |
GenSpez |
Es entstehen also eigene Relationen für Staubsauger und Kaffeemaschinen, mit dem Schlüssel von HG-Typen: |
HG |
Staubsauger (#Bez, Saugkraft, Typ) |
|
Kaffeemaschinen (#Bez, MengeWasser, Geschw) |
|
Die Schlüssel der Spezialisierungen sind also gleich dem Schlüssel der Generalisierung. Allerdings sind die Schlüsselmengen der Spezialisierungen Teilmengen der Schlüsselmenge der Generalisierung. Es handelt sich um eine Beziehung mit der Kardinalität 1:1 und den Min-/Max-Angaben 0,1 : 1,1 (von der Generalisierung ausgehend). |
|
Auch die Kunden erfüllen die Kriterien für eine Relation. Der Schlüssel ist KuNr, die Attribute sind Name und Vorname. |
Kunden |
Kunden (#KuNr, Name, Vorname) |
|
Wo kommen die Adressinformationen hin? Gäbe es nur eine Adresse, kämen sie einfach in die Kundendatei. Die Möglichkeit mehrerer Adressen je Kunde führt aber zu einer eigenen Relation Adressen mit den Attributen PLZ, Ort, Straße. Da es ohne Schlüssel nicht geht und in der Anforderung keiner spezifiziert ist, legen wir einen fest: AdrNr (Adressnummer): |
Adressen |
Adressen (#AdrNr, PLZ, Ort, Straße) |
|
In der Beschreibung wird ausgeführt, dass Kunden mehrere Telefonanschlüsse haben können. Dafür muss dann eine eigene Relation Telefone angelegt werden. Für diese steht beschreibend nur die Telefonnummer zur Verfügung (Tel). Da zu einem Anschluss mehrere Kunden gehören, liegt eine n:m-Beziehung zwischen Kunden und Telefonen vor. Die MinMax-Angaben sind 0,n : 1,m. Wir lassen also auch zu, dass es in unserer Datenbank Kunden ohne angegebene Telefonnummer gibt. Dies alles erfordert einen zusammengesetzten Schlüssel in Telefone und KuNr als Fremdschlüssel : |
Telefonanschlüsse mit 1:n |
Telefone (#(Tel, KuNr)) |
|
Die bei einer Verbindungsrelation normalerweise folgende dritte Relation (hier zu Telefonanschlüssen) ist mangels beschreibender Attribute für Telefonanschlüsse hier nicht nötig. Wäre aber möglich, z.B. bezüglich Anschlussart, Geschäftstelefon, privater Anschluss, Erreichbarkeit des Anschlusses. |
|
Die Erfassung der Verkäufe gestaltet sich etwas anspruchsvoller. In der Beschreibung ist angedeutet, dass Einzelgeräte erfasst werden sollen, nicht die Bezeichnung der Typ-Ebene. Da wäre modelltechnisch eine Ergänzung der Relation HG-Einzeln durch ein Attribut KuNr als Fremdschlüssel denkbar: |
Verkäufe |
HG-Einzeln (#GNr, KuNr, Bez, . . . //falsche Lösung |
|
Dies entspricht einer 1:n-Beziehung zwischen KUNDEN und HG-Einzeln. Überdenkt man die damit ausgedrückte Semantik, wird aber klar, dass dies nicht möglich ist. In HG-Einzeln werden alle Geräte erfasst, die auf Lager genommen werden. In die Verkäufe kommen nur die verkauften Geräte, also eine Teilmenge. Will man entsprechend der relationalen Theorie semantisch bedingte Leereinträge (hier bei KuNr) vermeiden, ist eine Relation Verkäufe mit dem Schlüssel/Fremdschlüssel #GNr und dem Fremdschlüssel KuNr die richtige Lösung: |
|
Verkäufe (#GNr, KuNr, Datum, ErzPreis) //richtige Lösung |
|
Hier ist nun jedem tatsächlich verkauften Gerät ein Kunde zugeordnet mit einer 1:n-Beziehung zwischen Kunden und Geräten. |
|
Die Min-/Max-Angaben sind (von den Kunden ausgehend) 0,n : 0,1. Es kann also Kunden geben, die noch nicht gekauft haben und es gibt natürlich Geräte, die noch nicht verkauft sind. Auch hier gilt wieder, dass dies auch anders festgelegt werden kann. |
|
Die Beziehung zwischen Kunden und Adressen ist noch nicht erfasst. Hier wurde in der Anforderung darauf hingewiesen, dass nicht nur ein Kunde mehrere Adressen haben kann, sondern dass unter einer Adresse auch mehrere Kunden wohnen können. Eine solche Situation erfordert eine n:m-Beziehung, die zu einer Verbindungsrelation KuAdr führt: |
Adressen |
KuAdr (#(KuNr, AdrNr)) |
|
Die Min-/Max-Angaben können wir festlegen. Da es in der Datenbank keine Kunden ohne Adressen und keine Adressen ohne Kunden geben soll (beides wäre auch möglich!), ergeben sich die Min-/Max-Angaben 1,n : 1,m. |
|
Damit ist die Modellierung abgeschlossen. Die Relationen sind in der höchsten Normalform: Die BCNF ist erfüllt und es liegen keine Verstöße gegen die 4NF und 5NF vor. Die auftretenden Muster (Gen/Spez und Einzel/Typ) wurden eingearbeitet. Zeitliche Informationen liegen, bis auf das Verkaufsdatum, nicht vor. |
|
3.2.3 Lösung |
|
Textliche Fassung |
|
HG-Einzeln (#GNr, MonatHerst, LagAufn, Bez) |
|
HG-Typen (#Bez, Hersteller, LPreis, AnzLager) |
|
Staubsauger (#Bez, Saugkraft, Typ) |
|
Kaffeemaschinen (#Bez, MengeWasser, Geschw) |
|
Kunden (#KuNr, Name, Vorname) |
|
Adressen (#KuNr, PLZ, Ort, Straße) |
|
KuAdr (#(KuNr, AdrNr)) |
|
Telefone (#(Tel, KuNr)) |
|
Verkäufe (#GNr, KuNr, Datum, ErzPreis) |
|
|
|
Grafische Fassung |
|
|
|
Abbildung 3.2-1: Relationales Datenodell Haushaltsgeräte |
|
3.2.4 Datenbank erstellen |
|
Zuerst muss die Datenbank angelegt werden. Dies geschieht mit folgendem Befehl: |
|
create database HG default character set latin1 collate latin1_german1_ci;
|
|
Dann werden die Relationen angelegt. Dabei muss eine Reihenfolge beachtet werden: Eine Relation mit Fremdschlüssel kann nur eingerichtet werden, wenn die Relation mit dem zugehörigen Schlüssel vorhanden ist. |
|
HG-Typen (#Bez, Hersteller, LPreis, AnzLager) |
|
create table hgt (Bez varchar(7), Hersteller varchar(2), LPreis decimal(7,2), AnzLager smallint(3), primary key (bez));
|
|
HG-Einzeln (#GNr, MonatHerst, LagAufn, Bez) |
|
create table hge (GNr int(5), MonatHerst date, LagAufn date, bez varchar(7) references hgt (bez), primary key (GNr));
|
|
Kaffeemaschinen (#Bez, MengeWasser, Geschw) |
|
create table kaffee (bez varchar(7), wasser decimal(4,1), geschw smallint(3), primary key (bez));
|
|
Staubsauger (#Bez, Saugkraft, Typ) |
|
create table staubsauger (bez varchar(7), saug int (4), typ varchar(10), primary key (bez));
|
|
Adressen (#KuNr, PLZ, Ort, Straße) |
|
create table adressen (AdrNr int(6), plz varchar(5), ort varchar(10), strasse varchar(10), primary key (adrnr));
|
|
Kunden (#KuNr, Name, Vorname) |
|
create table kunden (KNr int(6), name varchar(10), vname varchar(10), primary key (KNr));
|
|
KuAdr (#(KuNr, AdrNr)) |
|
create table KuAdr (KNr int(6), AdrNr int(6), primary key (KNr, AdrNr), foreign key (KNr) references kunden(knr), foreign key (adrnr) references adressen(adrnr));
|
|
Verkäufe (#GNr, KuNr, Datum, ErzPreis) |
|
create table verkaeufe (GNr int(5), KNr int(6) references kunden(knr), Datum date, ErzPreis decimal (6,2), primary key (GNr));
|
|
Telefone (#(Tel, KuNr)) |
|
create table telefone (Tel varchar(10), KNr int(6), primary key (Tel, KNr), foreign key (KNr) references kunden(knr));
|
|
Alternativ, mit Benennung des Fremdschlüssels: |
|
create table telefone2 (Tel varchar(10), KNr int(6), primary key (Tel, KNr), constraint fs_tel_ku foreign key (KNr) references kunden(knr));
|
|
Am Stück, für die Übernahme nach mySQL: |
|
create table hgt (Bez varchar(7), Hersteller varchar(2), LPreis decimal(7,2), AnzLager smallint(3), primary key (bez)); |
|
create table hge (GNr int(5), MonatHerst date, LagAufn date, bez varchar(7) references hgt (bez), primary key (GNr)); |
|
create table kaffee (bez varchar(7), wasser decimal(4,1), geschw smallint(3), primary key (bez)); |
|
create table staubsauger (bez varchar(7), saug int (4), typ varchar(10), primary key (bez)); |
|
create table adressen (AdrNr int(6), plz varchar(5), ort varchar(10), strasse varchar(10), primary key (adrnr)); |
|
create table kunden (KNr int(6), name varchar(10), vname varchar(10), primary key (KNr)); |
|
create table KuAdr (KNr int(6), AdrNr int(6), primary key (KNr, AdrNr), foreign key (KNr) references kunden(knr), foreign key (adrnr) references adressen(adrnr)); |
|
create table verkaeufe (GNr int(5), KNr int(6) references kunden(knr), Datum date, ErzPreis decimal (6,2), primary key (GNr)); |
|
create table telefone (Tel varchar(10), KNr int(6), primary key (Tel, KNr), foreign key (KNr) references kunden(knr)); |
|
3.2.5 Einfüllen von Daten |
|
Relation kunden |
|
insert into kunden (KNr, name, vname) values (1005, 'Na1', 'VN1');
|
|
insert into kunden values (1004, 'Na2', 'VN1');
|
|
insert into kunden values (1003, 'Na3', 'VN3'), (1002, 'Na4', 'VN4'), (1001, 'Na5', 'VN5');
|
|
SELECT * FROM kunden;
|
|
KNr |
name |
vname |
1001 |
Na5 |
VN5 |
1002 |
Na4 |
VN4 |
1003 |
Na3 |
VN3 |
1004 |
Na2 |
VN1 |
1005 |
Na1 |
VN1 |
| |
|
|
Relation adressen |
|
Insert into adressen values
|
|
(123, '99999', 'Ort99', 'Str123'),
|
|
(234, '77777', 'Ort77', 'Str234'),
|
|
(789, '55555', 'Ort55', 'Str789'),
|
|
(678, '88888', 'Ort88', 'Str678'),
|
|
(567, '22222', 'Ort22', 'Str567');
|
|
SELECT * FROM adressen;
|
|
AdrNr |
plz |
ort |
strasse |
123 |
99999 |
Ort99 |
Str123 |
234 |
77777 |
Ort77 |
Str234 |
567 |
22222 |
Ort22 |
Str567 |
678 |
88888 |
Ort88 |
Str678 |
789 |
55555 |
Ort55 |
Str789 |
| |
|
|
Relation kuadr (Kunden - Adressen) |
|
insert into kuadr values
|
|
(1001, 789),(1002, 234),(1003, 567),(1004, 123),(1005, 678),(1002, 789),(1005, 678),(1005, 789);
|
|
SELECT * FROM kuadr;
|
|
KNr |
AdrNr |
1001 |
789 |
1002 |
234 |
1002 |
789 |
1003 |
567 |
1004 |
123 |
1005 |
567 |
1005 |
678 |
1005 |
789 |
| |
3.2.6 Abfragen |
|
Verknüpfung der drei Relationen kunden, adressen und kuadr, zuerst in einfachster Form. |
|
select * from kunden k, adressen a, kuadr ka where k.knr=ka.knr and a.adrnr=ka.adrnr;
|
|
KNr |
name |
vname |
AdrNr |
plz |
ort |
strasse |
KNr |
AdrNr |
1001 |
Na5 |
VN5 |
789 |
55555 |
Ort55 |
Str789 |
1001 |
789 |
1002 |
Na4 |
VN4 |
234 |
77777 |
Ort77 |
Str234 |
1002 |
234 |
1002 |
Na4 |
VN4 |
789 |
55555 |
Ort55 |
Str789 |
1002 |
789 |
1003 |
Na3 |
VN3 |
567 |
22222 |
Ort22 |
Str567 |
1003 |
567 |
1004 |
Na2 |
VN1 |
123 |
99999 |
Ort99 |
Str123 |
1004 |
123 |
1005 |
Na1 |
VN1 |
567 |
22222 |
Ort22 |
Str567 |
1005 |
567 |
1005 |
Na1 |
VN1 |
678 |
88888 |
Ort88 |
Str678 |
1005 |
678 |
1005 |
Na1 |
VN1 |
789 |
55555 |
Ort55 |
Str789 |
1005 |
789 |
| |
|
|
Jetzt mit Vermeidung doppelter Spalten (Attribute), Spaltenüberschriften und Sortierung nach Postleitzahl und Kundennummer. Außerdem sollen die Ortsangaben in der Tabelle vor den Kundenangaben und die PLZ an erster Stelle stehen. |
|
select a.plz as PLZ, a.adrnr as AdressNr, a.ort as Ort, a.strasse as Strasse, k.knr as KundenNr, k.name as Name, k.vname as Vorname
|
|
from kunden k, adressen a, kuadr ka
|
|
where k.knr=ka.knr and a.adrnr=ka.adrnr order by a.plz, k.knr;
|
|
|
|
PLZ |
AdressNr |
Ort |
Strasse |
KundenNr |
Name |
Vorname |
22222 |
567 |
Ort22 |
Str567 |
1003 |
Na3 |
VN3 |
22222 |
567 |
Ort22 |
Str567 |
1005 |
Na1 |
VN1 |
55555 |
789 |
Ort55 |
Str789 |
1001 |
Na5 |
VN5 |
55555 |
789 |
Ort55 |
Str789 |
1002 |
Na4 |
VN4 |
55555 |
789 |
Ort55 |
Str789 |
1005 |
Na1 |
VN1 |
77777 |
234 |
Ort77 |
Str234 |
1002 |
Na4 |
VN4 |
88888 |
678 |
Ort88 |
Str678 |
1005 |
Na1 |
VN1 |
99999 |
123 |
Ort99 |
Str123 |
1004 |
Na2 |
VN1 |
| |
3.3 Zoo |
|
3.3.1 Anforderungsbeschreibung |
|
(1) Für einen Zoo soll eine Datenbank rund um die vorhandenen Tiere erstellt werden. Dabei erfolgt eine Konzentration auf größere Tiere (Säugetiere, Reptilien, . . .). Allen diesen Tieren wird eine identifizierende Tiernummer (TNr), ihr Name (Name) und die Gattung, zu der sie gehören (Gattung: z.B. afrikanische Elefanten, Bengalen-Tiger, Schimpansen, Nil-Krokodile) zugewiesen. Außerdem wird ihr Geburtstag (GebTag), das Geschlecht und das Gebäude erfasst, in dem Sie gehalten werden. Für jede Gattung wird auch festgehalten, wieviele Tiere davon im Zoo vorhanden sind (z.B. 5 Afrikanische Elefanten oder 20 Schimpansen) (Anzahl). Wegen der Bedeutung der Information für die Gebäude und das Außengelände wird bei Elefanten noch zusätzlich das Gewicht und bei Giraffen die Größe erfasst, jeweils mit dem Datum, zu dem der Wert erhoben wurde.
|
|
(2) Auch die Rahmenbedingungen der Fütterung der Tiere werden festgehalten: Welches Futter (Futterbezeichnung; FuttBez) ein Tier bekommt (durchaus mehrere Futterarten, z.B. Heu und Frischkost) und welche Menge davon täglich (Menge). Wieviel Vorrat vorhanden ist und welche Mindestmenge immer vorrätig gehalten wird (MiMenge).
|
|
(3) Den Tieren sind Pfleger zugeordnet. Von diesen wird in der Datenbank die Personalnummer (PersNr), der Name und Vorname (VName) festgehalten. Es wird auch festgehalten, in welchem Zeitraum der Pfleger einem Tier zugeordnet ist (Erster Tag: Beginn; Letzter Tag: Ende). Öfters kommt es vor, dass ein Pfleger für einen bestimmten Zeitraum einem Tier zugeordnet ist, dann nicht mehr und später wieder, so dass es mehrere Pflegezeiträume eines Pflegers bei einem Tier geben kann.
|
|
(4) Für die einzelnen Gebäude des Zoos wird eine Gebäudenummer (GebNr), die Größe, der Typ (für Säugetiere, für Reptilien, usw.) und die Anzahl der Plätze (AnzPlätze) erfasst. Selbstverständlich wird auch festgehalten, welches Tier aktuell in welchem Gebäude ist.
|
|
(5) Für jedes Tier gibt es Tierakten, die digital geführt werden. Eine wird bei der Geburt angelegt, eine beim Weggang bzw. Sterben des Tieres. Dazwischen entstehen digitale Akten bei besonderen Anlässen, z.B. wenn das Tier den Zoo wechselt, eine schwere Verletzung / Erkrankung erleben muss oder Nachwuchs bekommt. Die Akten eines Tieres erhalten eine fortlaufende Nummer (1, 2, 3, . . .) (AktenNr). Außerdem wird das Datum der Anlage der Akte (DatAnlage) sowie der Grund für die Anlage (Geburt, Krankheit, Tod, . . .) (Ereignis) und eine Beschreibung des Ereignisses (BeschrEr) in die Datenbank eingetragen. Nach dem Tod des Tieres werden alle Akten aus der Datenbank entfernt.
|
|
3.3.2 Lösungsschritte |
|
Die Anforderungsbeschreibung wird Punkt für Punkt abgearbeitet. |
|
Anforderung Teil 1 |
|
In Teil 1 wird auf die Tiere des Zoos eingegangen. Die Nennung der identifizierenden Tiernummer (Schlüssel) und weiterer beschreibender Attribute deutet eine Relation zu Tieren an: |
|
Tiere (#TNr, Name, Gattung, GebTag, Geschlecht, GebNr) |
|
Die Gebäudenummer (GebNr) wurde weiter unten als Teil einer Relation Gebäude im Text gefunden und konnte deshalb hier gleich als Fremdschlüssel angelegt werden. |
|
An der Stelle "Für jede Gattung . . ." werden offensichtlich nicht mehr einzelne Tiere beschrieben, sondern die jeweilige Gattung. Nach einer Prüfung, ob damit eine neue Relation begründet wird (Gattung könnte auch ein Attribut von Tiere sein), wird diese angelegt. BezGatt (Gattungsbezeichnung) wird Schlüssel, Anzahl ein beschreibendes Attribut: |
Muster Einzel/Typ |
Tiere-Gattung (#BezGatt, Anzahl) |
|
Das Attribut Gattung von Tiere wird dann umbenannt in BezGatt und die Relation Tiere in Tiere-Einzeln: |
|
Tiere-Einzeln (#TNr, Name, BezGatt, GebTag, Geschlecht, GebNr) |
|
Dies ist das Muster Einzel/Typ, das in so gut wie jedem Datenmodell vorkommt und trotzdem häufig übersehen wird. |
|
Das Attribut BezGatt realisiert, als Schlüssel und Fremdschlüssel, eine relationale Verknüpfung zwischen den beiden Relationen und hält somit fest, zu welcher Gattung ein einzelnes Tier gehört. Die Kardinalitäten und Min-/Max-Angaben sind wie folgt: Von Tiere-Einzeln zu Tiere-Gattung: n:1 bzw. 1,1 : 1,m. |
|
Beginnend mit "Wegen der Bedeutung . . ." wird in der Anforderungsbeschreibung weiter spezifiziert: Es gibt zusätzliche Attribute für (die einzelnen) Elefanten (Gewicht) und Giraffen (Größe). Diese beiden Attribute werden für die übrigen Tiere nicht erfasst. Fügt man sie an Tiere-Einzeln an, gibt es in dieser Relation Attribute, die nicht für alle Tiere erfasst werden. Es gäbe also semantisch bedingte Leereinträge. Dies ist in allen Datenbeständen nicht erwünscht (vgl. [Staud 2021, Stichwortsuche bzw. Index]) und wird auch von der relationalen Theorie unterbunden. In einer solchen Situation, werden die "zusätzlichen" Attribute in eigene Relationen getan. Es entsteht eine Generalisierung / Spezialisierung. Mit der Datumsangabe (Zeitpunkt der Messung), die jeweils zu einem zusammengesetzten Schlüssel führt, entsteht folgende Generalisierung / Spezialisierung: |
Generalisierung / Spezialisierung |
Elefanten (#(TierNr, Datum), Gewicht) |
|
Giraffen (#(TierNr, Datum), Größe) |
|
Tiere-Einzeln (#TierNr, Name, BezGatt, GebTag, Geschlecht, GebNr) |
|
Die Kardinalitäten und Min-/Max-Angaben sind wie folgt: Von Tiere-Einzeln zu Giraffen: 1:1 bzw. 0,1 : 1,1. Ebenso von Tiere-Einzeln zu Elefanten. |
|
Hier das Modellfragment zu diesen ersten Schritten: |
|
|
|
Abbildung 3.3-1: Datenmodell Zoo - Fragment Tiere |
|
Anforderung Teil 2 |
|
Teil 2 beschreibt die bezüglich der Fütterung zu erfassenden Datenbankaspekte. Zuerst einmal geht es um die tägliche Fütterung. Hier wird eine n:m-Beziehung angedeutet: für ein Tier mehrere Futterarten, eine Futterart für mehrere Tiere. Dies führt zu einer Relation Fütterung mit dem zusammengesetzten Schlüssel (TierNr, FuttBez), der auch gleich das Attribut Menge beigefügt wird. TierNr ist hier Schlüsselattribut (also Teil des Schlüssels) und auch Fremdschlüssel, dient also der Verknüpfung mit Tiere-Einzeln. Im folgenden wird auch noch das Futter hinsichtlich der Entnahmen näher beschrieben. Wir müssen also auch eine Relation Futter anlegen mit dem Schlüssel Bez (Futterbezeichnung) und den beschreibenden Attributen Vorrat und MiMenge (Mindestmenge). |
|
Hier die Relationen dieser n:m-Beziehung: |
|
Futter (#Bez, Vorrat, MiMenge) |
|
Fütterung (#(TierNr, FuttBez), Menge) |
|
Tiere-Einzeln (#TierNr, Name, BezGatt, GebTag, Geschlecht, GebNr) |
|
Die Kardinalitäten und Min-/Max-Angaben sind wie folgt: Von Tiere-Einzeln über Fütterung zu Futter: n:m, bzw. 1,n : 0,m, weil es auch mal neu beschaffte Futterarten geben kann, die noch nicht verfüttert wurden. |
|
Anforderung Teil 3 |
|
Teil 3 widmet sich den Pflegern und Pflegerinnen. Diese sind gleich als Relation erkennbar: |
|
Pfleger (#PersNr, Name, Vorname) |
|
Der nachfolgende Text spricht - mit einem zeitlichen Aspekt - die Pflege als solche an. Es kann angenommen werden (vor allem mit der zeitlichen Dimension), dass ein Tier von unterschiedlichen Pflegern versorgt wird und ein Pfleger unterschiedliche Tiere versorgt. Der Kern des Schlüssels ist daher die Kombination aus PersNr und TierNr, ergänzt um ein Attribut der Zeitphasen. Wir nehmen dafür hier Beginn. Das zweite zeitliche Attribut wird dann zum Nichtschlüsselattribut der Relation: |
|
Pflege (#(PersNr, TierNr, Beginn), Ende) |
|
Die Kardinalitäten und Min-/Max-Angaben sind wie folgt: Von Pfleger über Pflege zu Tiere-Einzeln: n:m, bzw. 0,n : 1,m, weil eine neu eingestellte Pflegekraft erst mal noch keine Zuständigkeit hat. |
|
Anforderung Teil 4 |
|
Teil 4 beschreibt die Gebäude. Die Relation ist sofort erkennbar: |
|
Gebäude (#GebNr, Größe, Typ, AnzPlätze) |
|
Das Attribut GebNr wurde oben schon in der Relation Tiere-Einzeln als Fremdschlüssel genutzt. |
|
Wie bringen wir die Information unter, "welches Tier aktuell in welchem Gebäude ist". Dies leistet die GebNr (Gebäudenummer) als Fremdschlüssel in Tiere-Einzeln. Möglich ist dies, weil es sich um eine 1:n-Beziehung handelt (ein Tier kann nicht gleichzeitig in zwei Gebäuden sein). Die Kardinalitäten und Min-/Max-Angaben sind wie folgt: Von Gebäude zu Tiere-Einzeln: 1:n, bzw. 0,n : 1,1, weil auch neue Gebäude, denen noch kein Tier zugeordnet ist, in der Datenbank angelegt werden sollen. |
|
Anforderung Teil 5 |
|
Den Anforderungen kann entnommen werden, dass es zu jedem Tier zahlreiche Tierakten gibt. Dies erfordert einen zusammengesetzten Schlüssel (TierNr, AktNr), wobei TierNr Fremdschlüssel ist. Beschreibende Attribute sind das Datum der Anlage (DatAnlage), das die Aktenanlage auslösende Ereignis sowie eine Beschreibung des Ereignisses (BeschrEr). |
Tierakten |
Tierakten (#(TierNr, AktNr), DatAnlage, Ereignis, BeschrEr) |
|
Dies ist ein Beispiel für Existenzabhängigkeit, die in anderen Kontexten auch Komposition genannt wird (Z.B. in der objektorientierten Theorie, vgl. [Staud 2019]). Deutlich wird dies dadurch, dass die Akten nur zur Lebenszeit des Tieres in der Datenbank verbleiben sollen. Nach seinem Tod werden sie aus der Datenbank genommen. Sie sind also existenzabhängig von dem entsprechenden Tupel der Relation Tiere-Einzeln. |
Komposition / Existenzabhängigkeit |
Die Kardinalitäten und Min-/Max-Angaben sind wie folgt: Von Tiere-Einzeln zu Tierakten: 1:n, bzw. 1,n : 1,1, wenn man annimmt, dass ein Tier mit der Geburt die erste Akte erhält. |
|
Im Aufbau des Schlüssels von Tierakten zeigt sich die Abhängigkeit: Da eine Relation immer einen vollständigen Schlüssel haben muss und da TierNr ein Teil des Schlüssels ist, fällt mit Wegfall des Tieres auch das Tupel in Tierakte weg. |
|
3.3.3 Lösung |
|
Textliche Fassung |
|
Elefanten (#(TierNr, Datum), Gewicht) |
|
Futter (#Bez, Vorrat, MiMenge) |
|
Fütterung (#(TierNr, FuttBez, Datum), Menge) |
|
Gebäude (#GebNr, Größe, Typ, AnzPlätze) |
|
Giraffen (#(TierNr, Datum), Größe) |
|
Pflege (#(PersNr, TierNr, Beginn), Ende) |
|
Pfleger (#PersNr, Name, VName) |
|
Tierakten (#(TierNr, AktenNr), DatAnlage, Ereignis, BeschrEr) |
|
Tiere-Einzeln (#TierNr, Name, BezGatt, GebTag, Geschlecht, GebNr) |
|
Tiere-Gattung (#BezGatt, Anzahl) |
|
Nicht selbsterklärende Attributsbezeichnungen: |
|
Futter.MiMenge: Mindestmenge |
|
Fütterung.FuttBez: Bezeichnung des Futters |
|
Gebäude.AnzPlätze: Anzahl der Plätze im Gebäude |
|
Gebäude.GebNr: Eindeutige Nummer des Gebäudes |
|
Pfleger.VName: Vorname |
|
Tierakten.DatAnlage: Datum der Anlage der Akte |
|
Tierakten.BeschrEr: Beschreibung des Ereignisses, das zur Anlage der Akte geführt hat |
|
Tiere-Einzeln.TierNr: Eindeutige, dem Tier zugeordnete Nummer. |
|
Tiere-Gattung.BezGatt: Bezeichnung der Tiergattung |
|
Grafische Fassung |
|
|
|
Abbildung 3.3-2: Relationales Datenmodell Zoo |
|
Muster Komposition bei Tierakten |
|
Muster Einzel/Typ bei Tiere |
|
Muster Gen/Spez bei Elefanten, Giraffen |
|
3.3.4 Einrichten der Datenbank |
|
Datenbank Zoo |
|
create database Zoo default character set latin1 collate latin1_german1_ci;
|
|
Futter (#Bez, Vorrat, MiMenge) |
|
create table futter (Bez char(10), Vorrat decimal(5,2), MiMenge decimal(5,2), primary key (Bez));
|
|
Gebäude (#GebNr, Größe, Typ, AnzPlätze) |
|
create table gebaeude (GebNr tinyint(3), groesse smallint(5), typ varchar(10), AnzPlaetze tinyint(3), primary key (GebNr));
|
|
Pfleger (#PersNr, Name, VName) |
|
create table Pfleger (PersNr smallint(3), Name varchar(10), VName varchar(10), primary key (PersNr));
|
|
Tiere-Gattung (#BezGatt, Anzahl) |
|
create table TiereG (BezGatt varchar(15), Anzahl tinyint(2), primary key (BezGatt));
|
|
Tiere-Einzeln (#TierNr, Name, BezGatt, GebTag, Geschlecht, GebNr) |
|
create table TiereE (TierNr smallint(6), Name char(10), BezGatt varchar(15) references TiereG(BezGatt), GebTag date, Geschlecht char(1), GebNr tinyint(3), primary key (TierNr), foreign key (GebNr) references Gebaeude(GebNr));
|
|
Elefanten (#(TierNr, Datum), Gewicht) |
|
create table elefanten (TierNr smallint(6), Datum date, Gewicht decimal (6,2), primary key (TierNr, Datum), foreign key (TierNr) references TiereE(TierNr));
|
|
Giraffen (#(TierNr, Datum), Größe) |
|
create table giraffen (TierNr smallint(6), Datum date, Größe decimal (4,2), primary key (TierNr, Datum), foreign key (TierNr) references TiereE(TierNr));
|
|
Fütterung (#(TierNr, FuttBez, Datum), Menge) |
|
create table Fuetterung (TierNr smallint(6), FuttBez char(10), Datum date, Menge decimal(3,1), primary key (TierNr, FuttBez, Datum), foreign key (TierNr) references TiereE(TierNr), foreign key (FuttBez) references Futter(Bez));
|
|
Pflege (#(PersNr, TierNr, Beginn), Ende) |
|
create table Pflege (PersNr smallint(3), TierNr smallint(6), Beginn date, Ende date, primary key (PersNr, TierNr, Beginn), foreign key (PersNr) references pfleger(PersNR), foreign key (TierNr) references TiereE(TierNR));
|
|
Tierakten (#(TierNr, AktenNr), DatAnlage, Ereignis, BeschrEr) |
|
create table Tierakten (TierNr smallint(6), AktenNr smallint(3), DatAnlage date, Ereignis varchar(10), BeschrEr varchar(20), primary key (TierNr, AktenNr), foreign key (TierNr) references TiereE(TierNr));
|
|
Am Stück, für die Übernahme nach mySQL: |
|
create database Zoo default character set latin1 collate latin1_german1_ci; |
|
create table futter (Bez char(10), Vorrat decimal(5,2), MiMenge decimal(5,2), primary key (Bez)); |
|
create table gebaeude (GebNr tinyint(3), groesse smallint(5), typ varchar(10), AnzPlaetze tinyint(3), primary key (GebNr)); |
|
create table Pfleger (PersNr smallint(3), Name varchar(10), VName varchar(10), primary key (PersNr)); |
|
create table TiereG (BezGatt varchar(15), Anzahl tinyint(2), primary key (BezGatt)); |
|
create table TiereE (TierNr smallint(6), Name char(10), BezGatt varchar(15) references TiereG(BezGatt), GebTag date, Geschlecht char(1), GebNr tinyint(3), primary key (TierNr), foreign key (GebNr) references Gebaeude(GebNr)); |
|
create table elefanten (TierNr smallint(6), Datum date, Gewicht decimal (6,2), primary key (TierNr, Datum), foreign key (TierNr) references TiereE(TierNr)); |
|
create table giraffen (TierNr smallint(6), Datum date, Größe decimal (4,2), primary key (TierNr, Datum), foreign key (TierNr) references TiereE(TierNr)); |
|
create table Fuetterung (TierNr smallint(6), FuttBez char(10), Datum date, Menge decimal(3,1), primary key (TierNr, FuttBez, Datum), foreign key (TierNr) references TiereE(TierNr), foreign key (FuttBez) references Futter(Bez)); |
|
create table Pflege (PersNr smallint(3), TierNr smallint(6), Beginn date, Ende date, primary key (PersNr, TierNr, Beginn), foreign key (PersNr) references pfleger(PersNR), foreign key (TierNr) references TiereE(TierNR)); |
|
create table Tierakten (TierNr smallint(6), AktenNr smallint(3), DatAnlage date, Ereignis varchar(10), BeschrEr varchar(20), primary key (TierNr, AktenNr), foreign key (TierNr) references TiereE(TierNr)); |
|
3.3.5 Befüllen mit Daten |
|
Hinweis: Beim Nachvollziehen die Reihenfolge beachten. |
|
Relation TiereG |
|
insert into TiereG values ('ElefInd', 5);
|
|
insert into TiereG values ('ElefAfr', 6);
|
|
insert into TiereG values ('Giraffen', 11);
|
|
insert into TiereG values ('Löwen', 4);
|
|
select * from TiereG;
|
|
BezGatt |
Anzahl |
ElefAfr |
6 |
ElefInd |
5 |
Giraffen |
11 |
Löwen |
4 |
| |
|
|
Relation Gebaeude |
|
insert into gebaeude (gebnr, groesse, typ, anzplaetze) values (17, 80, 'Hochhaus', 10);
|
|
insert into gebaeude values (22, 60, 'Haus', 5);
|
|
insert into gebaeude values (7, 80, 'Massivhaus', 8);
|
|
select * from Gebaeude;
|
|
GebNr |
groesse |
typ |
AnzPlaetze |
7 |
80 |
Massivhaus |
8 |
17 |
80 |
Hochhaus |
10 |
22 |
60 |
Haus |
5 |
| |
|
|
Relation TiereE |
|
insert into TiereE values (1001, 'Rudi', 'ElefAfr', '2001-01-01', 'm', 7);
|
|
insert into TiereE values (1009, 'Sepp', 'ElefAfr', '2001-01-01', 'm', 7);
|
|
insert into TiereE values (1007, 'Otto', 'ElefAfr', '1998-02-05', 'm', 7);
|
|
insert into TiereE values (1010, 'Chiara', 'ElefInd', '2005-11-17', 'w', 7);
|
|
insert into TiereE values (1019, 'Ella', 'ElefInd', '2018-12-22', 'w', 7);
|
|
insert into TiereE values (2001, 'Fipo', 'Giraffen', '1980-05-01', 'm', 17);
|
|
insert into TiereE values (2011, 'Betsy', 'Giraffen', '1990-09-10', 'm', 17);
|
|
insert into TiereE values (5004, 'Rudi', 'Löwen', '2008-11-01', 'm', 22);
|
|
insert into TiereE values (5002, 'Ratzo', 'Löwen', '2006-01-06', 'w', 22);
|
|
insert into TiereE values (5001, 'Brutus', 'Löwen', '2016-02-23', 'm', 22);
|
|
insert into TiereE values (5003, 'Cäsar', 'Löwen', '2022-01-31', 'w', 22);
|
|
Select * from TiereE;
|
|
TierNr |
Name |
BezGatt |
GebTag |
Geschlecht |
GebNr |
1001 |
Rudi |
ElefAfr |
2001-01-01 |
m |
7 |
1007 |
Otto |
ElefAfr |
1998-02-05 |
m |
7 |
1009 |
Sepp |
ElefAfr |
2001-01-01 |
m |
7 |
1010 |
Chiara |
ElefInd |
2005-11-17 |
w |
7 |
1019 |
Ella |
ElefInd |
2018-12-22 |
w |
7 |
2001 |
Fipo |
Giraffen |
1980-05-01 |
m |
17 |
2011 |
Betsy |
Giraffen |
1990-09-10 |
m |
17 |
5001 |
Rudi |
Löwen |
2016-02-23 |
m |
22 |
5002 |
Ratzo |
Löwen |
2006-01-06 |
w |
22 |
5003 |
Brutus |
Löwen |
2022-01-31 |
w |
22 |
5004 |
Cäsar |
Löwen |
2008-11-01 |
m |
22 |
| |
|
|
Relation Elefanten |
|
insert into elefanten values (1001, '2024-01-31', 520), (1007, '2024-01-18', 601), (1009, '2024-01-01', 720), (1010, '2024-05-05', 480), (1019, '2024-01-16', 515);
|
|
Relation Giraffen |
|
insert into giraffen values (2001, '2023-12-12', 3.80), (2011, '2023-12-20', 4.15);
|
|
Am Stück, für die Übernahme nach mySQL: |
|
insert into TiereG values ('ElefInd', 5); |
|
insert into TiereG values ('ElefAfr', 6); |
|
insert into TiereG values ('Giraffen', 11); |
|
insert into TiereG values ('Löwen', 4); |
|
insert into gebaeude (gebnr, groesse, typ, anzplaetze) values (17, 80, 'Hochhaus', 10); |
|
insert into gebaeude values (22, 60, 'Haus', 5); |
|
insert into gebaeude values (7, 80, 'Massivhaus', 8); |
|
insert into TiereE values (1001, 'Rudi', 'ElefAfr', '2001-01-01', 'm', 7); |
|
insert into TiereE values (1009, 'Sepp', 'ElefAfr', '2001-01-01', 'm', 7); |
|
insert into TiereE values (1007, 'Otto', 'ElefAfr', '1998-02-05', 'm', 7); |
|
insert into TiereE values (1010, 'Chiara', 'ElefInd', '2005-11-17', 'w', 7); |
|
insert into TiereE values (1019, 'Ella', 'ElefInd', '2018-12-22', 'w', 7); |
|
insert into TiereE values (2001, 'Fipo', 'Giraffen', '1980-05-01', 'm', 17); |
|
insert into TiereE values (2011, 'Betsy', 'Giraffen', '1990-09-10', 'm', 17); |
|
insert into TiereE values (5004, 'Rudi', 'Löwen', '2008-11-01', 'm', 22); |
|
insert into TiereE values (5002, 'Ratzo', 'Löwen', '2006-01-06', 'w', 22); |
|
insert into TiereE values (5001, 'Brutus', 'Löwen', '2016-02-23', 'm', 22); |
|
insert into TiereE values (5003, 'Cäsar', 'Löwen', '2022-01-31', 'w', 22); |
|
insert into elefanten values (1001, '2024-01-31', 520), (1007, '2024-01-18', 601), (1009, '2024-01-01', 720), (1010, '2024-05-05', 480), (1019, '2024-01-16', 515); |
|
insert into giraffen values (2001, '2023-12-12', 3.80), (2011, '2023-12-20', 4.15); |
|
3.3.6 Abfragen |
|
Auswahl der weiblichen Elefanten und Giraffen mit den Attributen TierNr, Name, Gattung, GebNr, AnzPlaetze, GebTag und Geschlecht. |
|
SELECT e.TierNr, e.Name, g.BezGatt as Gattung, h.GebNr as 'Nr Gebäude', h.AnzPlaetze as 'Zahl Plätze', e.GebTag as Geburtstag, e.Geschlecht as G
|
|
FROM tiereE E, TiereG G, Gebaeude H
|
|
where e.Geschlecht='w' and e.GebNr=h.GebNr and e.BezGatt =g.BezGatt;
|
|
|
|
TierNr |
Name |
Gattung |
Nr Gebäude |
Zahl Plätze |
Geburtstag |
G |
1010 |
Chiara |
ElefInd |
7 |
8 |
2005-11-17 |
w |
1019 |
Ella |
ElefInd |
7 |
8 |
2018-12-22 |
w |
5002 |
Ratzo |
Löwen |
22 |
5 |
2006-01-06 |
w |
5003 |
Brutus |
Löwen |
22 |
5 |
2022-01-31 |
w |
| |
|
|
Auswahl der Elefanten mit den Attributen TierNr, Name, BezGatt, Gewicht und Wiegedatum (datum). |
|
select t.TierNr, t.name as Name, t.BezGatt as Gattung,
|
|
e.gewicht as Gewicht, e.datum as Wiegedatum
|
|
from TiereE t, Elefanten e
|
|
where t.TierNr=e.tiernr order by t.BezGatt, t.Name;
|
|
|
|
TierNr |
Name |
Gattung |
Gewicht |
Wiegedatum |
1007 |
Otto |
ElefAfr |
601.00 |
2024-01-18 |
1001 |
Rudi |
ElefAfr |
520.00 |
2024-01-31 |
1009 |
Sepp |
ElefAfr |
720.00 |
2024-01-01 |
1010 |
Chiara |
ElefInd |
480.00 |
2024-05-05 |
1019 |
Ella |
ElefInd |
515.00 |
2024-01-16 |
| |
|
|
4 RelDB - Von der Anforderung zur Web-Benutzeroberfläche |
|
Gesamtweg: Anforderungen - Datenmodell (Schema) - Datenbank - Web-Benutzeroberfläche |
|
Gesamtaufgabe |
|
Ziel dieses Kapitels ist es, den in den obigen zwei Kapiteln aufgezeigten Weg von den Anforderungen bis zum Datenmodell bzw. bis zur Datenbank fortzusetzen bis zur Web-Oberfläche, von der aus die Datenbank abgefragt und ausgewertet wird. Auch für diesen letzten Schritt des Gesamtwegs werden die elementaren Techniken trainiert. Damit ist dann der oben gezeigte Gesamtweg in seinen Grundzügen in den Aufgaben thematisiert. Insgesamt also: |
|
- Anforderungen zum Anwendungsbereich bearbeiten.
- Relationales Datenmodell (Schema) erstellen (Kapitel 2).
- Relationale Datenbank mit mySQL unter XAMPP einrichten (Kapitel 3).
- Realisierung exemplarischer Abfragen und Auswertungen mit mySQL (Kapitel 3).
- Erstellung einer einfachen webbasierten Benutzerschnittstelle ("WebOberfläche"; Graphical User Interface; GUI) (mit HTML, CSS) für exemplarische Abfragen und Auswertungen mit der Datenbank (Kapitel 4).
|
|
Für diesen letzten Schritt werden zusätzlich zu den oben genannten Methoden auch noch Kenntnisse in HTML und PHP benötigt. Die wichtigsten daraus benötigten Theorieelemente werden in den Kapiteln 11 und 12 wiederholt. |
|
|
|
4.1 Kindergarten |
|
Aufgabenstellung: Prof. Dr. Josef L. Staud |
|
Lösung: stud. oec. inf. Karolin Staud |
|
Diese Aufgabe ist Grundlage für die nachfolgenden (4.2 - 4.7). d.h., die hier erstellte Datenbank wird für die Aufgaben 4.2 - 4.7 genutzt. |
|
4.1.1 Anforderungsbeschreibung |
|
Ein Kindergarten möchte seine Daten in einer Datenbank verwalten. Folgendes soll erfasst werden: |
|
- Die Kinder mit Name, Vorname, Adresse (Straße, PLZ, Ort), Eintrittsdatum, Geburtstag. Außerdem wird erfasst, ob es ein Geschwisterkind ist, d.h., ob ein Geschwister auch im Kindergarten ist.
- Für die Kinder über 4 Jahre wird erfasst, an welchen Förderprogrammen sie teilnehmen (Sprachförderung, Förderung Feinmotorik, . . .) und von wann bis wann (Datumsangaben) diese durchgeführt werden. Es kommt durchaus vor, dass ein Kind an mehreren Fördermaßnahmen teilnimmt.
- Die Eltern mit Name, Vorname, Telefon (mehrere Telefonnummern, z.B. eine zu Hause, eine von der Arbeitsstätte, ein Handy) und Adresse. Natürlich wird festgehalten, welche Eltern zu welchem Kind gehören. Eltern und Kinder müssen nicht denselben Nachnamen haben. Die Eltern können an unterschiedlichen Orten wohnen (z.B., weil sie geschieden sind).
|
|
4.1.2 Aufgaben |
|
- Erstellen Sie für diesen Anwendungsbereich ein Relationales Datenmodell in textlicher und grafischer Fassung.
- Richten Sie zum obigen Datenmodell eine Datenbank ein. Führen Sie zwei SQL-Abfragen durch, die jeweils mindestens zwei Relationen verknüpfen.
|
|
4.1.3 Datenmodell erstellen |
|
Am Anfang der Anforderungsbeschreibung kommt man auf die Relation der Kinder, in der der Name, der Vorname, die Adresse, das Eintrittsdatum, das Austrittsdatum und das Geschwister (falls vorhanden) festgehalten werden soll. Hier fügt man am besten einen konstruierten eindeutigen Schlüssel hinzu, da sonst der Schlüssel zu groß und damit schwer zu verarbeiten wird. Dadurch kommt man relativ schnell auf folgende Relation: |
|
Kinder (#KindID, Name, Vorname, AdressID, Eintrittsdatum, Geburtstag) |
|
Da das Attribut, das aussagt, ob ein Kind ein Geschwister hat oder nicht, als Verknüpfung sehr schwer darzustellen wäre, fügt man dies hier als Attribut (GKindJN) einfach an die Relation Kinder an. Hier kann man mit 1 (Ja) oder 0 (Nein) den Sachverhalt erfassen. |
|
Kinder (#KindID, Name, Vorname, Eintrittsdatum, Geburtstag, GKindJN) |
|
Nun zur Erfassung der Adressen. Da ein Kind nur an einer Adresse wohnt, könnte man die ganze Adresse direkt in der Relation Kinder anführen. Da aber weiter unten in der Anforderungsbeschreibung von Adressen von Elternteilen die Rede ist, werden die Adressen in einer eigenen Relation erfasst: |
|
Adressen (#AdressID, Straße, PLZ, Ort) |
|
Die Relation Kinder wird dann um einen Fremdschlüssel AdressID ergänzt: |
|
Kinder (#KindID, Name, Vorname, AdressID, Eintrittsdatum, Geburtstag, GKindJN) |
|
Beim weiteren Lesen erkennt man eine Generalisierung / Spezialisierung im nächsten Teil der Anforderungsbeschreibung, nämlich darin, dass über 4-jährige Kinder spezifische Attribute erhalten. Dies wird im relationalen Modell so umgesetzt, dass die Ü4-jährigen Kinder eine neue Relation erhalten, mit demselben Schlüssel wie Kinder. Angehängt werden die Attribute die im Text aufgezählt sind. |
Generalisierung / Spezialisierung |
Kinderü4 (#KindID, Förderprogramm, Anfang, Ende) |
|
Da ein Kind jedoch an mehreren Förderprogrammen teilnehmen kann, muss "Förderprogramm" in eine neue Relation ausgelagert werden und in der Kindü4-Relation zum Fremdschlüssel gemacht werden. Sonst kann es zu Mehrfacheinträgen kommen. In der neuen Relation wird auch ein Schlüssel "FördID" angelegt, da alles andere nur schwer eindeutig zu machen wäre: |
|
Kinderue4 (#(KindID, FördProg)) |
|
FoerdProg (#FördID, Bez, Art, Anfang, Ende) |
|
Da für die Relation Kindü4 der Schlüssel KindID nicht eindeutig wäre, wird KindID und FördProg gemeinsam zum Schlüssel. |
|
Im nächsten Abschnitt werden die Eltern beschrieben. Hier werden einige Attribute aufgenommen, unter anderem die Telefonnummer und die Adresse. Auch hier wird eine eindeutige ID festgelegt. |
|
Elternteil (#ElternID, Name, Vorname, AdressID) |
|
Da es verschiedene Telefonnummern und auch Adressen gibt, müssen diese wieder in extra Relationen ausgelagert werden, um Mehrfacheinträge zu vermeiden. |
|
Da die Telefonnummern nur durch die Nummer an sich nicht eindeutig werden, weil auch diese zu z.B. 2 Elternteilen gehören können (zum Beispiel bei Festnetz), muss sich der Schlüssel hier aus der Telefonnummer und der ElternID zusammensetzen. Das Attribut "Art" legt fest, ob es sich um die Mobilfunknummer, die Festnetznummer oder eine andere Nummer handelt. |
|
ElternTel (#(ElternID, TelNr), Art) |
|
Die Kinder der Eltern müssen in einer Verbindungsrelation aufgenommen werden, da wir hier eine N-zu-M Beziehung haben. Ein Kind hat womöglich 2 oder mehrere Elternteile, ein Elternteil kann auch mehrere Kinder haben. |
|
Dies kann man also nicht wie bisher einfach durch einen Fremdschlüssel lösen, sondern durch eine neue Relation, die Elternteil und Kinder verbindet und die durch die zusammengesetzten Schlüssel der beiden Relationen eindeutige Ausprägungen hat. |
|
EltTeilKind (#(KindID, ElternID)) |
|
Textliche Fassung |
|
Kinder (#KindID, Name, Vorname, AdressID, Eintrittsdatum, Austrittsdatum, GKindJN) |
|
Kinderue4(#(KindID, FoerdProg)) |
|
FoerdProg (#FoerdId, Bez, Art, Anfang, Ende) |
|
Elternteil (#ElternID, Name, Vorname, AdressID) |
|
EltTeilKind (#(KindID, ElternID)) |
|
ElternTel (#(ElternId, TelNr), Art) |
|
Adressen (#AdressID, Straße, PLZ, Ort) |
|
Grafische Fassung |
|
|
|
Abbildung 4.1-1: Relationales Datenmodell Kindergarten |
|
4.1.4 Datenbank einrichten |
|
Lösung: stud. oec. inf. Karolin Staud |
|
Zunächst muss die Datenbank an sich angelegt werden: |
|
create database Kindergarten default character set latin1 collate latin1_german1_ci;
|
|
Dann müssen zuerst die Relationen ohne Fremdschlüssel angelegt werden, da diese auf keine anderen (womöglich noch nicht erstellten) Relationen zugreifen. |
|
Anlegen der Relation für die Förderprogramme: |
|
create table FoerdProg (FoerdID smallint(2), Bez varchar(15),
|
|
Art varchar(15), Anfang date, Ende date, primary key (FoerdID));
|
|
Anlegen der Adressen: |
|
create table Adressen (AdressID smallint(3), Strasse varchar(20),
|
|
PLZ varchar(5), Ort varchar(15), primary key(AdressID));
|
|
Jetzt kann man auch die Relationen mit Fremdschlüssel anlegen, da die Basis gelegt wurde. Anlegen der Kinderrelation: |
|
create table Kinder(KindID smallint(3), Name char(10),
|
|
Vorname char(10), AdressID smallint(3), Eintrittsdatum date,
|
|
Geburtstag date, GKindJN boolean,
|
|
primary key(KindID),
|
|
foreign key(AdressID) references adressen(AdressID));
|
|
Anlegen der Relation für Kinder über 4: |
|
create table Kinderue4 (KindID smallint(3), FoerdProg smallint(2),
|
|
primary key(KindID, FoerdProg),
|
|
foreign key (FoerdProg) references FoerdProg(FoerdID));
|
|
Anlegen der Relation für die Eltern: |
|
create table Elternteil (ElternID smallint(3), Name varchar(15), Vorname varchar(9), AdressID smallint(3),
|
|
primary key (ElternID),
|
|
foreign key (AdressID) references Adressen(AdressID));
|
|
Anlegen der Verbindung zwischen Kindern und Eltern: |
|
create table EltTeilKind(KindID smallint(3), ElternID smallint(3),
|
|
primary key (KindID, ElternID),
|
|
foreign key (KindID) references Kinder (KindID),
|
|
foreign key (ElternID) references Elternteil (ElternID));
|
|
Anlegen der Telefone der Eltern: |
|
create table ElternTel(ElternID smallint(3), TelNr char(12), Art varchar(8),
|
|
primary key (ElternID, TelNr),
|
|
foreign key (ElternID) references Elternteil(ElternID));
|
|
Zusammengefasst für die Übernahme nach mySQL: Die Datenbank und alle Relationen. |
|
Zuerst die Datenbank anlegen: |
|
create database Kindergarten default character set latin1 collate latin1_german1_ci; |
|
Jetzt die Datenbank anwählen, dann: |
|
create table FoerdProg (FoerdID smallint(2), Bez varchar(15), Art varchar(15), Anfang date, Ende date, primary key (FoerdID)); |
|
create table Adressen (AdressID smallint(3), Strasse varchar(20), PLZ varchar(5), Ort varchar(15), primary key(AdressID)); |
|
create table Kinder(KindID smallint(3), Name char(10), Vorname char(10), AdressID smallint(3), Eintrittsdatum date, Geburtstag date, GKindJN boolean, primary key(KindID), foreign key(AdressID) references adressen(AdressID)); |
|
create table Kinderue4 (KindID smallint(3), FoerdProg smallint(2), primary key(KindID, FoerdProg), foreign key (FoerdProg) references FoerdProg(FoerdID)); |
|
create table Elternteil (ElternID smallint(3), Name varchar(15), Vorname varchar(9), AdressID smallint(3), primary key (ElternID), foreign key (AdressID) references Adressen(AdressID)); |
|
create table EltTeilKind(KindID smallint(3), ElternID smallint(3), primary key (KindID, ElternID), foreign key (KindID) references Kinder (KindID), foreign key (ElternID) references Elternteil (ElternID)); |
|
create table ElternTel(ElternID smallint(3), TelNr char(12), Art varchar(8), primary key (ElternID, TelNr), foreign key (ElternID) references Elternteil(ElternID)); |
|
Einfüllen von fiktiven Daten |
|
Auch hier gilt: Zuerst die Relationen ohne Fremdschlüssel befüllen! |
|
Relation FoerdProg |
|
insert into foerdprog values
|
|
(1, 'Sprachförderung', 'Sprache', '2022-06-01', '2022-11-30'),
|
|
(2, 'Feinmotorik', 'Körper', '2022-01-05', '2022-3-22'),
|
|
(3, 'Motivation', 'Intellekt', '2023-10-13', '2023-12-24'),
|
|
(4, 'Reaktionen', 'Körper', '2022-07-26', '2023-02-19');
|
|
Relation Adressen |
|
insert into adressen values
|
|
(001, 'Schlossstraße 2', '12345', 'München'),
|
|
(002, 'Auf der Mauer 17', '55874', 'Heiligenbach'),
|
|
(003, 'Alleeweg 5', '37254', 'Weingarten'),
|
|
(004, 'Weinstraße 1', '37254', 'Weingarten'),
|
|
(005, 'Schlossstraße 4', '12345', 'München'),
|
|
(006, 'Am Bergweg 11', '55874', 'Heiligenbach'),
|
|
(007, 'Klabusterstraße 7', '55874', 'Heiligenbach'),
|
|
(008, 'Heinzelgasse 63', '74385', 'Überlingen'),
|
|
(009, 'Gartenstraße 29', '94743', 'Passau'),
|
|
(010, 'Beethovenstraße 12', '94743', 'Passau');
|
|
Relation Elternteil |
|
insert into Elternteil VALUES
|
|
(1, 'Meier', 'Alexander', 6),
|
|
(2, 'Meier', 'Sandra', 6),
|
|
(3, 'Schneider', 'Josef', 1),
|
|
(4, 'Müller', 'Bernd', 7),
|
|
(5, 'Wagner', 'Luise', 3),
|
|
(6, 'Wagner', 'Benedikt', 3),
|
|
(7, 'Bäcker', 'Angelika', 2),
|
|
(8, 'Hoffmann', 'Pamela', 10),
|
|
(9, 'Hoffmann', 'Jim', 10),
|
|
(10, 'Lenz', 'Moritz', 8),
|
|
(11, 'Rose', 'Emma', 8),
|
|
(12, 'Rose', 'Maria', 9),
|
|
(13, 'Sturm', 'Lorenz', 4),
|
|
(14, 'Wiese', 'Hannes', 5),
|
|
(15, 'Wiese', 'Clemenz', 5);
|
|
Relation Kinder |
|
insert into Kinder VALUES
|
|
(1, 'Meier', 'Max', 6, '2021-03-20', '2016-06-12', true),
|
|
(2, 'Meier', 'Moritz', 6, '2019-01-04', '2016-01-25', true),
|
|
(3, 'Schneider', 'Elli', 1, '2023-05-24', '2017-01-25', true),
|
|
(4, 'Schneider', 'Luca', 1, '2022-01-18', '2018-10-23', true),
|
|
(5, 'Müller', 'Johannes', 7, '2018-09-03', '2015-12-18', false),
|
|
(6, 'Wagner', 'Karla', 3, '2019-04-23', '2016-10-14', false),
|
|
(7, 'Bäcker', 'Klaus', 2, '2022-04-27', '2017-01-25', false),
|
|
(8, 'Hoffmann', 'Claudia', 10, '2018-01-01', '2015-01-01', true),
|
|
(9, 'Hoffmann', 'Lena', 10, '2019-01-01', '2021-01-01', true),
|
|
(10, 'Hoffmann', 'Sabrina', 10, '2022-01-01', '2018-01-25', true),
|
|
(11, 'Lenz', 'Barbie', 8, '2020-07-16', '2021-11-11', false),
|
|
(12, 'Rose', 'Max', 9, '2019-09-10', '2021-09-10', true),
|
|
(13, 'Rose', 'Lukas', 9, '2021-09-10', '2022-03-25', true),
|
|
(14, 'Sturm', 'Niklas', 4, '2022-08-12', '2018-01-25', false),
|
|
(15, 'Wiese', 'Elisabeth', 5, '2023-08-21', '2020-01-25', false);
|
|
Relation Kinderü4 |
|
insert into Kinderue4 VALUES
|
|
(1, 2),
|
|
(3, 1),
|
|
(3, 3),
|
|
(8, 4),
|
|
(9, 1),
|
|
(9, 2),
|
|
(9, 4),
|
|
(14, 3);
|
|
Relation EltTeilKind |
|
insert into EltTeilKind VALUES
|
|
(1, 1),(1, 2),(2, 1),(2, 2),(3, 3),(4, 3),(5, 4),(6, 5),(6, 6),(7, 7),(8, 8),(8, 9),(9, 8),(9, 9),(10, 8),(10, 9),(11, 10),(11, 11),(12, 12),(13, 12),(14, 13),(15, 14),(15, 15);
|
|
Relation ElternTel |
|
insert into ElternTel VALUES
|
|
(1, '012345678901', 'mobil'),
|
|
(2, '234567898765', 'mobil'),
|
|
(1, '456789876543', 'Festnetz'),
|
|
(2, '456789876543', 'Festnetz'),
|
|
(3, '564738574612', 'mobil'),
|
|
(4, '098675463415', 'mobil'),
|
|
(4, '867594876676', 'Arbeit'),
|
|
(5, '048396775844', 'mobil'),
|
|
(5, '346384739288', 'Festnetz'),
|
|
(6, '346384739288', 'Festnetz'),
|
|
(7, '574987336452', 'mobil'),
|
|
(8, '476302980014', 'Arbeit'),
|
|
(8, '120923847625', 'Festnetz'),
|
|
(9, '120923847625', 'Festnetz'),
|
|
(10, '473639567386', 'mobil'),
|
|
(11, '003927562834', 'mobil'),
|
|
(12, '874630112742', 'Arbeit'),
|
|
(13, '493823465989', 'Festnetz'),
|
|
(14, '112653049378', 'Festnetz'),
|
|
(15, '112653049378', 'Festnetz');
|
|
Alles zusammen, für die Übernahme in mySQL: |
|
insert into foerdprog values |
|
(1, 'Sprachförderung', 'Sprache', '2022-06-01', '2022-11-30'), |
|
(2, 'Feinmotorik', 'Körper', '2022-01-05', '2022-3-22'), |
|
(3, 'Motivation', 'Intellekt', '2023-10-13', '2023-12-24'), |
|
(4, 'Reaktionen', 'Körper', '2022-07-26', '2023-02-19'); |
|
insert into adressen values |
|
(001, 'Schlossstraße 2', '12345', 'München'), |
|
(002, 'Auf der Mauer 17', '55874', 'Heiligenbach'), |
|
(003, 'Alleeweg 5', '37254', 'Weingarten'), |
|
(004, 'Weinstraße 1', '37254', 'Weingarten'), |
|
(005, 'Schlossstraße 4', '12345', 'München'), |
|
(006, 'Am Bergweg 11', '55874', 'Heiligenbach'), |
|
(007, 'Klabusterstraße 7', '55874', 'Heiligenbach'), |
|
(008, 'Heinzelgasse 63', '74385', 'Überlingen'), |
|
(009, 'Gartenstraße 29', '94743', 'Passau'), |
|
(010, 'Beethovenstraße 12', '94743', 'Passau'); |
|
insert into Elternteil VALUES |
|
(1, 'Meier', 'Alexander', 6), |
|
(2, 'Meier', 'Sandra', 6), |
|
(3, 'Schneider', 'Josef', 1), |
|
(4, 'Müller', 'Bernd', 7), |
|
(5, 'Wagner', 'Luise', 3), |
|
(6, 'Wagner', 'Benedikt', 3), |
|
(7, 'Bäcker', 'Angelika', 2), |
|
(8, 'Hoffmann', 'Pamela', 10), |
|
(9, 'Hoffmann', 'Jim', 10), |
|
(10, 'Lenz', 'Moritz', 8), |
|
(11, 'Rose', 'Emma', 8), |
|
(12, 'Rose', 'Maria', 9), |
|
(13, 'Sturm', 'Lorenz', 4), |
|
(14, 'Wiese', 'Hannes', 5), |
|
(15, 'Wiese', 'Clemenz', 5); |
|
insert into Kinder VALUES |
|
(1, 'Meier', 'Max', 6, '2021-03-20', '2016-06-12', true), |
|
(2, 'Meier', 'Moritz', 6, '2019-01-04', '2016-01-25', true), |
|
(3, 'Schneider', 'Elli', 1, '2023-05-24', '2017-01-25', true), |
|
(4, 'Schneider', 'Luca', 1, '2022-01-18', '2018-10-23', true), |
|
(5, 'Müller', 'Johannes', 7, '2018-09-03', '2015-12-18', false), |
|
(6, 'Wagner', 'Karla', 3, '2019-04-23', '2016-10-14', false), |
|
(7, 'Bäcker', 'Klaus', 2, '2022-04-27', '2017-01-25', false), |
|
(8, 'Hoffmann', 'Claudia', 10, '2018-01-01', '2015-01-01', true), |
|
(9, 'Hoffmann', 'Lena', 10, '2019-01-01', '2021-01-01', true), |
|
(10, 'Hoffmann', 'Sabrina', 10, '2022-01-01', '2018-01-25', true), |
|
(11, 'Lenz', 'Barbie', 8, '2020-07-16', '2021-11-11', false), |
|
(12, 'Rose', 'Max', 9, '2019-09-10', '2021-09-10', true), |
|
(13, 'Rose', 'Lukas', 9, '2021-09-10', '2022-03-25', true), |
|
(14, 'Sturm', 'Niklas', 4, '2022-08-12', '2018-01-25', false), |
|
(15, 'Wiese', 'Elisabeth', 5, '2023-08-21', '2020-01-25', false); |
|
insert into Kinderue4 VALUES (1, 2), (3, 1), (3, 3), (8, 4), (9, 1), (9, 2), (9, 4), (14, 3); |
|
insert into EltTeilKind VALUES (1, 1), (1, 2), (2, 1), (2, 2), (3, 3), (4, 3), (5, 4), (6, 5), (6, 6), (7, 7), (8, 8), (8, 9), (9, 8), (9, 9), (10, 8), (10, 9), (11, 10), (11, 11), (12, 12), (13, 12), (14, 13), (15, 14), (15, 15); |
|
insert into ElternTel VALUES |
|
(1, '012345678901', 'mobil'), |
|
(2, '234567898765', 'mobil'), |
|
(1, '456789876543', 'Festnetz'), |
|
(2, '456789876543', 'Festnetz'), |
|
(3, '564738574612', 'mobil'), |
|
(4, '098675463415', 'mobil'), |
|
(4, '867594876676', 'Arbeit'), |
|
(5, '048396775844', 'mobil'), |
|
(5, '346384739288', 'Festnetz'), |
|
(6, '346384739288', 'Festnetz'), |
|
(7, '574987336452', 'mobil'), |
|
(8, '476302980014', 'Arbeit'), |
|
(8, '120923847625', 'Festnetz'), |
|
(9, '120923847625', 'Festnetz'), |
|
(10, '473639567386', 'mobil'), |
|
(11, '003927562834', 'mobil'), |
|
(12, '874630112742', 'Arbeit'), |
|
(13, '493823465989', 'Festnetz'), |
|
(14, '112653049378', 'Festnetz'), |
|
(15, '112653049378', 'Festnetz'); |
|
Abfragebeispiele |
|
In der ersten Abfrage werden Eltern mit ihren Kindern ausgegeben: |
|
select e.elternid, k.kindid, e.name as "Elternteil Name",
|
|
e.vorname as "Elternteil VName", k.name as "Name Kind",
|
|
k.vorname as "Vorname Kind"
|
|
from Elternteil e, kinder k, eltteilkind et
|
|
where k.kindid=et.kindid and e.elternid= et.elternid
|
|
order by elternid, kindid;
|
|
|
|
elternid |
kindid |
Elternteil Name |
Elternteil VName |
Name Kind |
Vorname Kind |
1 |
1 |
Meier |
Alexander |
Meier |
Max |
1 |
2 |
Meier |
Alexander |
Meier |
Moritz |
2 |
1 |
Meier |
Sandra |
Meier |
Max |
2 |
2 |
Meier |
Sandra |
Meier |
Moritz |
3 |
3 |
Schneider |
Josef |
Schneider |
Elli |
3 |
4 |
Schneider |
Josef |
Schneider |
Luca |
4 |
5 |
Müller |
Bernd |
Müller |
Johannes |
5 |
6 |
Wagner |
Luise |
Wagner |
Karla |
6 |
6 |
Wagner |
Benedikt |
Wagner |
Karla |
7 |
7 |
Bäcker |
Angelika |
Bäcker |
Klaus |
8 |
8 |
Hoffmann |
Pamela |
Hoffmann |
Claudia |
8 |
9 |
Hoffmann |
Pamela |
Hoffmann |
Lena |
8 |
10 |
Hoffmann |
Pamela |
Hoffmann |
Sabrina |
9 |
8 |
Hoffmann |
Jim |
Hoffmann |
Claudia |
9 |
9 |
Hoffmann |
Jim |
Hoffmann |
Lena |
9 |
10 |
Hoffmann |
Jim |
Hoffmann |
Sabrina |
10 |
11 |
Lenz |
Moritz |
Lenz |
Barbie |
11 |
11 |
Rose |
Emma |
Lenz |
Barbie |
12 |
12 |
Rose |
Maria |
Rose |
Max |
12 |
13 |
Rose |
Maria |
Rose |
Lukas |
13 |
14 |
Sturm |
Lorenz |
Sturm |
Niklas |
14 |
15 |
Wiese |
Hannes |
Wiese |
Elisabeth |
15 |
15 |
Wiese |
Clemenz |
Wiese |
Elisabeth |
| |
|
|
In der zweiten Abfrage werden die Kinder in alphabetischer Reihenfolge mit ihren Förderprogrammen ausgegeben: |
|
SELECT ki.name as Name, ki.vorname as VName,
|
|
ki.geburtstag as Geburtstag, fo.foerdid, fo.bez as Programm,
|
|
fo.anfang as Beginn, fo.ende as Ende
|
|
FROM kinder ki, kinderue4 k4, foerdprog fo
|
|
where ki.kindid = k4.kindid and k4.foerdprog=fo.foerdid
|
|
order by ki.name, fo.foerdid;
|
|
|
|
Name |
VName |
Geburtstag |
foerdid |
Programm |
Beginn |
Ende |
Hoffmann |
Lena |
2021-01-01 |
1 |
Sprachförderung |
2022-06-01 |
2022-11-30 |
Hoffmann |
Lena |
2021-01-01 |
2 |
Feinmotorik |
2022-01-05 |
2022-03-22 |
Hoffmann |
Claudia |
2015-01-01 |
4 |
Reaktionen |
2022-07-26 |
2023-02-19 |
Hoffmann |
Lena |
2021-01-01 |
4 |
Reaktionen |
2022-07-26 |
2023-02-19 |
Meier |
Max |
2016-06-12 |
2 |
Feinmotorik |
2022-01-05 |
2022-03-22 |
Schneider |
Elli |
2017-01-25 |
1 |
Sprachförderung |
2022-06-01 |
2022-11-30 |
Schneider |
Elli |
2017-01-25 |
3 |
Motivation |
2023-10-13 |
2023-12-24 |
Sturm |
Niklas |
2018-01-25 |
3 |
Motivation |
2023-10-13 |
2023-12-24 |
| |
4.2 Leitseite für WebAbfragen |
|
Diese und die Aufgaben 4.3 - 4.7 basieren auf dem Datenmodell von Aufgabe 4.1, genauer auf der Relation Kinder. |
|
4.2.1 Aufgabe |
|
Erstellen Sie eine Webseite mit Buttons, die Abfragen auf der Datenbank durchführen, so wie in der folgenden Webseite gezeigt. Diese grafische Bedienoberfläche mit HTML und CSS soll etwa so aussehen: |
|
|
|
Alle Schaltflächen beziehen sich nur auf die Daten der Kinder. Legen Sie für die Buttons folgende Bezeichnungen für die Programme an: |
|
- Daten aller Kinder anzeigen : KiGaTabelle.php
- Neuzugang erfassen: KiGaNeueintrag.php
- Daten eines Kindes löschen: KiGaLoeschen_a.php
- Daten ausgewählter Kinder anzeigen: KiGaName.php
- Daten von Kindern ändern: Ki_aendern_a.php
|
|
4.2.2 Lösung |
|
Die Lösung verlangt für die Leitseite eine HTML-Datei, eine Stylesheet-Datei und die Vorbereitung mehrerer PHP-Dateien. |
|
- Kindergarten.html (für die Leitseite)
- kindergarten.css (für die Stylesheets)
Die Leitseite Kindergarten.html ist vollständig HTML-basiert und hat deshalb ein entsprechendes Suffix. Die Schaltflächen werden fix positioniert, siehe Stylesheets in kindergarten.css. |
|
Kindergarten.html |
|
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title><center>Abfragen zur Datenbank Kindergarten</title>
|
|
<link rel="stylesheet" type="text/css" href="kindergarten.css">
|
|
</head>
|
|
<body>
|
|
<div id='p100'>
|
|
<h1>Datenbank KINDERGARTEN</h1>
|
|
</div>
|
|
<div id='p101'>
|
|
<p class="text_1">Daten aller Kinder anzeigen</p>
|
|
<form action="KiGaTabelle.php" method="post">
|
|
<p><input type="submit" value="Los geht's">
|
|
</form>
|
|
</div>
|
|
<div id='p102'>
|
|
<p class="text_1">Neuzugang erfassen</p>
|
|
<form action="KiGaNeueintrag.php" method="post">
|
|
<p><input type="submit" value="Los geht's">
|
|
</form>
|
|
</div>
|
|
<div id='p106'>
|
|
<p class="text_1">Daten eines Kindes lamp;ouml;schen</p>
|
|
<form action="KiGaLoeschen_a.php" method="post">
|
|
<p><input type="submit" value="Los geht's">
|
|
</form>
|
|
</div>
|
|
<div id='p104'>
|
|
<p class="text_1">Daten ausgewamp;auml;hlter Kinder anzeigen.<br>Anfangsbuchstaben eingeben.</p>
|
|
<form action="KiGaName.php" method="post">
|
|
<input name="anfang"> <input type="submit" value="Los geht's">
|
|
</form>
|
|
</div>
|
|
<div id='p105'>
|
|
<p class="text_1"><a href="ki_aendern_a.php">Daten von Kindern amp;auml;ndern</a></p>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
Stylesheet-Datei Kindergarten.css |
|
/*ID-Selektoren für <div... */ |
|
#p100 { height:40px; width: 900px;position: absolute; top: 70px; left: 40px; text-align: center;}
|
|
#p101 { height:70px; background-color:yellow; width: 440px; border: 1px solid green;position: absolute; top: 130px; left: 110px; text-align: center;}
|
|
#p102 { height:70px; background-color:yellow; width: 440px; border: 1px solid green;position: absolute; top: 220px; left: 110px; text-align: center;}
|
|
#p106 { height:70px; background-color:yellow; width: 440px; border: 1px solid green; position: absolute; top: 310px; left: 110px; text-align: center;}
|
|
#p104 { height:100px; background-color:yellow; width: 440px; border: 1px solid green; position: absolute; top: 130px; left: 490px; text-align: center;}
|
|
#p105 { height:40px; background-color:yellow; width: 440px; border: 1px solid green; position: absolute; top: 250px; left: 490px; text-align: center;}
|
|
/*Typ-Selektoren für HTML-Elemente*/ |
|
h1 { font-size:16pt; font-weight: bold; text-align: center; font-family: Calibri, Arial, sans-serif; color: blue; margin-bottom:10px; margin-right:0px; margin-top:5px; margin-left:0px;}
|
|
p {color: black; font-family: Arial, sans-serif; margin-bottom:10px; margin-right:10px; margin-top:10px; margin-left:10px;}
|
|
table {font-family: Arial, sans-serif;}
|
|
td {border: 1px solid black; vertical-align: middle; text-align: left;} td {padding: 3px}
|
|
thead {font-size: 10pt; color: black; font-family: Arial, sans-serif;}
|
|
/*Klassenselektoren mit Punkt*/ |
|
.text_1 { font-family: Arial, sans-serif; font-size:12pt; font-weight: bold; color:black;}
|
|
.text_2 { font-family: Arial, sans-serif; font-size:16pt; font-weight: bold;}
|
|
.text_3 {font-family: Arial, sans-serif; font-size:14pt; font-weight: bold;}
|
|
|
4.3 Daten aller Kinder anzeigen |
|
Diese Aufgabe basiert auf den Aufgaben 4.1 und 4.2. |
|
Erläutern Sie die notwendigen PHP-Programme, v.a. dort, wo es um die Verknüpfung von Datenbank und Webseite geht. |
|
4.3.1 Aufgabe |
|
Mit dem obersten linken Button der Leitseite wird eine Tabelle mit den Daten aller Kinder ausgegeben. |
|
|
|
Die Tabelle soll so aussehen: |
|
|
|
Erstellen Sie die notwendigen PHP-Programme. Erläutern Sie diese, v.a., wenn es um die Verknüpfung von Datenbank und Webseite geht. |
|
4.3.2 Lösung |
|
Das Programm ist in der Datei KiGaTabelle.php realisiert. Es realisiert den Zugriff von der Webseite auf die Relation mit tabellarischer Ausgabe aller Tupel. Außerdem werden entsprechend der Vorgabe in der Tabelle Spaltenüberschriften vergeben. |
|
KiGaTabelle.php |
|
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Ausgabe in Tabelle</title>
|
|
<link rel="stylesheet" type="text/css" href="kindergarten.css">
|
|
</head>
|
|
<body>
|
|
<table>
|
|
<caption class="text_2">Kinder im Kindergarten</caption>
|
|
<thead>
|
|
<th>Lfd. Nr.</th>
|
|
<th>KindID</th>
|
|
<th>Name</th>
|
|
<th>Vorname</th>
|
|
<th>AdressID</th>
|
|
<th>Datum Eintritt in KiGa</th>
|
|
<th>Geburtstag</th>
|
|
<th>Geschwisterkind?</th></thead>
|
|
An den letzten drei Attributen ist zu erkennen, dass die Spaltenüberschriften der Tabelle losgelöst von den Attributsbezeichnungen und auch losgelöst von etwaigen Spaltenüberschriften gestaltet werden können. Allerdings bleibt es dabei: Die Attributsbezeichnungen für die Funktion fetch_assoc() müssen die des SQL-Befehls sein. |
|
<?php
|
|
include "zeit2.inc.php"; //siehe Anmerkung und Programm unten
|
|
$con = new mysqli("localhost", "root", "", "kindergarten");
|
|
$sql = "SELECT KindID, Name, Vorname, AdressID, Eintrittsdatum, Geburtstag, GKindJN FROM kinder order by name";
|
|
$res = $con->execute_query($sql);
|
|
$lf = 1;
|
|
while($dsatz = $res->fetch_assoc())
|
|
{
|
|
echo "<tr>";
|
|
echo "<td><center>$lf</td>";
|
|
echo "<td><center>" . $dsatz["KindID"] . "</td>";
|
|
echo "<td><left>" . $dsatz["Name"] . "</td>";
|
|
echo "<td><left>" . $dsatz["Vorname"] . "</td>";
|
|
echo "<td><center>" . $dsatz["AdressID"] . "</td>";
|
|
echo "<td><center>" . db_datum_aus($dsatz["Eintrittsdatum"]) . "</td>";
|
|
echo "<td><center>" . db_datum_aus($dsatz["Geburtstag"]) . "</td>";
|
|
echo "<td><center>" . $dsatz["GKindJN"] . "</td>";
|
|
echo "</tr>";
|
|
$lf++;
|
|
}
|
|
$res->close();
|
|
$con->close();
|
|
?>
|
|
</table>
|
|
Der folgende Link führt zurück zur Leitseite: |
|
<p class="text_1"><a href="http://localhost/kindergarten.html">Zuramp;uuml;ck zur Leitseite</a></p>
|
|
</body>
|
|
</html>
|
|
Programm zeit2.inc.php |
|
Dieses Programm wird oben eingefügt. Es liefert die Umwandlung von US-Datumsangaben in das deutsche Datumsformat. |
|
<?php
|
|
function db_datum_aus($db_datum)
|
|
{
|
|
$feld = mb_split("-", $db_datum);
|
|
$tag = intval($feld[2]);
|
|
$monat = intval($feld[1]);
|
|
$jahr = intval($feld[0]);
|
|
$ausgabe = sprintf("%'.02d.%'.02d.%'.04d", $tag, $monat, $jahr);
|
|
return $ausgabe;
|
|
}
|
|
?>
|
|
4.4 Neuzugang erfassen |
|
Diese Aufgabe basiert auf den Aufgaben 4.1 und 4.2. |
|
Erläutern Sie die notwendigen PHP-Programme, v.a. dort, wo es um die Verknüpfung von Datenbank und Webseite geht. |
|
4.4.1 Aufgabe |
|
Mit dem zweiten Button werden die Daten eines neu hinzugekommenen Kindes angelegt. |
|
|
|
Dies erfordert die Abspeicherung von Daten in der Datenbank. Die Erfassungsmaske soll so gestaltet sein: |
|
|
|
Folgendes soll das Programm leisten: |
|
- Erfassen und Abspeichern eines neuen Datensatzes, evtl. auch gleich mehrerer hintereinander.
- Zurücksetzen wegen eventueller Fehleingaben.
- Anzeigen der Relation mit den neuen Daten.
|
|
4.4.2 Lösung |
|
Das Programm wird KiGaNeueintrag.php genannt und ergibt sich wie im Folgenden gezeigt. Der Übersichtlichkeit wegen zuerst das Programm ohne Anmerkungen. |
|
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Eingabe von Datensätzen</title>
|
|
<link rel="stylesheet" type="text/css" href="kindergarten.css">
|
|
<?php
|
|
include "pruefen.inc.php";
|
|
if(isset($_POST["gesendet"]))
|
|
{
|
|
$con = new mysqli("localhost", "root", "", "kindergarten");
|
|
$fehler=false;
|
|
if(int_positiv("Kindid", $_POST["id"], $id))
|
|
{
|
|
if(id_neu_doppelt("KinderId", $id, $con, "kinder", "kindid"))
|
|
$fehler = true;
|
|
}
|
|
else
|
|
$fehler = true;
|
|
if(!datum_gueltig("Eintrittsdatum", $_POST["ei"], $ei))
|
|
$fehler = true;
|
|
if(!datum_gueltig("Geburtstag", $_POST["gt"], $gt))
|
|
$fehler = true;
|
|
if(!$fehler)
|
|
{
|
|
$sql = "INSERT INTO kinder" . "(kindid, name, vorname, adressid, eintrittsdatum, geburtstag, gkindjn)"
|
|
. "VALUES(?, ?, ?, ?, ?, ?, ?)";
|
|
$con->execute_query($sql, [$_POST["id"], $_POST["na"],
|
|
$_POST["vn"], $_POST["ad"], $ei, $gt, $_POST["gk"]]);
|
|
}
|
|
else
|
|
echo "<p><big>Kein Datensatz eingetragen</p></big>";
|
|
$con->close();
|
|
}
|
|
?>
|
|
</head>
|
|
<body>
|
|
<p>Geben Sie bitte einen Datensatz ein<br>und senden Sie
|
|
das Formular ab:</p>
|
|
<form action="KiGaneueintrag.php" method="post">
|
|
<p><input type="text" name="id"> KindID</p>
|
|
<p><input type="text" name="na"> Name</p>
|
|
<p><input name="vn"> Vorname</p>
|
|
<p><input name="ad"> AdressID (eine ganze Zahl, 1 - 10)</p>
|
|
<p><input name="ei"> Eintrittsdatum (in T.M.JJJJ)</p>
|
|
<p><input name="gt"> Geburtstag (in T.M.JJJJ)
|
|
<p><input name="gk"> Geschwisterkind: 1 (ja), 0 (nein)</p>
|
|
<p><input type="submit" name="gesendet">
|
|
<input type="reset"></p>
|
|
</form>
|
|
<p>Alle Daten <a href="kigaAlleKi.php">anzeigen</a></p>
|
|
<p class="text_1">Zuramp;uuml;ck zur
|
|
<a href="http://localhost/kindergarten.html">Leitseite</a></p>
|
|
</body>
|
|
</html>
|
|
Nun das Programm mit Erläuterungen |
|
Zu Beginn des PHP-Abschnitts wird die Datei pruefen.inc.php eingefügt. Sie enthält mehrere Funktionen zum Prüfen der Eingaben in die Felder. |
|
include "pruefen.inc.php";
|
|
Mit der Funktion isset() kann geprüft werden, ob eine Variable existiert und welchen Wert sie hat. Dies wird hiergenutzt, um festzustellen, ob das untenstehende Erfassungsformular schon mal gesendet wurde. Dazu erhält das Formular die Bezeichnung gesendet. Dieses ist erstmal false, nach dem ersten Senden hat es den Wert true. |
|
if(isset($_POST["gesendet"]))
|
|
{
|
|
Im positiven Fall wird die Verknüpfung hergestellt: |
|
$con = new mysqli("localhost", "root", "", "kindergarten");
|
|
$fehler=false;
|
|
Nachfolgend erfolgt die Prüfung, ob die Eingabe in KindId (sie erhält unten die Bezeichnung id) eine positive ganze Zahl ist. Dazu wird eine Funktion aus pruefen.inc.php benutzt. |
|
if(int_positiv("Kindid", $_POST["id"], $id))
|
|
{
|
|
Falls ja, wird geprüft, ob die KinderId schon da ist. |
|
if(id_neu_doppelt("KinderId", $id, $con, "kinder", "kindid"))
|
|
$fehler = true;
|
|
}
|
|
else
|
|
$fehler = true;
|
|
Es folgt die Prüfung des angegebenen Eintrittsdatums durch eine Funktion aus pruefen.inc.php. |
|
if(!datum_gueltig("Eintrittsdatum", $_POST["ei"], $ei))
|
|
$fehler = true;
|
|
Ebenso zum Geburtstag. |
|
if(!datum_gueltig("Geburtstag", $_POST["gt"], $gt))
|
|
$fehler = true;
|
|
Falls die Variable $fehler auf false steht ("if (!$fehler)") kann nun die Verbindung zwischen Webseite und Datenbank hergestellt werden. Das Formular ist ja dank der isset-Prüfung auf jeden Fall beschrieben. |
|
Im Formular unten wurde für jedes Feld eine Bezeichnung vergeben. Z.B. |
|
<p><input type="text" name="id"> #KindID</p>
|
|
In $_POST["id"] steht dann der Wert von KindId. |
|
Damit wird dann die Verknüpfung wie folgt realisiert: Zuerst der SQL-Befehl insert into. An den Stellen, wo dann normalerweise die einzutragenden Werte stehen, werden Fragezeichen eingefügt. Für jeden Werte eines. |
|
if(!$fehler)
|
|
{
|
|
$sql = "INSERT INTO kinder" . "(kindid, name, vorname, adressid,
|
|
eintrittsdatum, geburtstag, gkindjn)"
|
|
. "VALUES(?, ?, ?, ?, ?, ?, ?)";
|
|
Bei der nachfolgenden Ausführung des Befehls in der Datenbank werden die geposteten Werte in derselben Reihenfolge, wie im übrigen SQL-Befehl angelegt, in die VALUES-Liste eingefügt. Damit ist ein sog. Prepared Statement umgesetzt. |
|
$con->execute_query($sql, [$_POST["id"], $_POST["na"], $_POST["vn"],
|
|
$_POST["ad"], $ei, $gt, $_POST["gk"]]);
|
|
}
|
|
Prepared Statement |
|
Man könnte die geposteten Werte im INSERT INTO-Befehl auch direkt eingeben, was aber Schwierigkeiten machen und der sog. SQL Injection (Hacker-Angriff) den Weg öffnen würde. Dies verhindern die sog. Prepared Statements. Dabei handelt es sich um ein Konstrukt in PHP, dessen Hauptmotiv die Verhinderung von SQL Injection ist. Vgl. [Theis 2023, Abschnitt 3.7] sowie [Wenz und Hauser 2021, Abschnitt 33.3]. |
|
Bei den Werten, die schon einer Prüfung unterzogen wurden ($ei, $gt), kann auf $_POST verzichtet werden, da sie von den Prüffunktionen über Referenzparameter zurückgegeben werden. |
|
Die folgende Abbildung verdeutlicht diese Zuordnung. |
|
|
|
Abbildung 4.4-1: Datensätze erzeugen mit einem Prepared Statement. |
|
Weiter im Programm: |
|
else
|
|
echo "<p><big>Kein Datensatz eingetragen</p></big>";
|
|
$con->close();
|
|
}
|
|
?>
|
|
</head>
|
|
Im Body-Teil folgt das Formular für die Datenerfassung. |
|
- Das Attribut action verweist auf das PHP-Auswertungsprogramm KiGaNeueintrag.php. D.h., hier ruft das Formular das "eigene" Programm auf. Dadurch können mehrere neue Einträge hintereinander getätigt werden.
- Das Attribut method gibt die Übermittlungsmethode zum Webserver (post) an.
- Es folgen die Texteingabefelder. Das Attribut name gibt dabei jeweils eine Kurzbezeichnung für jedes Attribut an, die im Befehl execute_query benötigt wird. Vgl. auch die Abbildung oben.
- Die Absende-Schaltfläche wird durch <input type="submit" name="gesendet"> angefordert. Hier wird die Bezeichnung vergeben, die oben mit isset benötigt wird.
- Abschließend wird die Schaltfläche für das Zurücksetzen mit <input type="reset"> angefordert.
|
|
<body>
|
|
<p>Geben Sie bitte einen Datensatz ein<br>und senden Sie das Formular ab:</p>
|
|
<form action="KiGaneueintrag.php" method="post">
|
|
<p><input type="text" name="id"> KindID</p>
|
|
<p><input type="text" name="na"> Name</p>
|
|
Bei diesem input type kann type="text" auch weggelassen werden: |
|
<p><input name="vn"> Vorname</p>
|
|
<p><input name="ad"> AdressID (eine ganze Zahl)</p>
|
|
<p><input name="ei"> Eintrittsdatum (in T.M.JJJJ)</p>
|
|
<p><input name="gt"> Geburtstag (in T.M.JJJJ)</p>
|
|
<p><input name="gk"> Geschwisterkind: 1 (ja), 0 (nein)</p>
|
|
<p><input type="submit" name="gesendet">
|
|
<input type="reset"></p>
|
|
</form>
|
|
Es folgt der Link für das Programm zum Anzeigen aller Daten der Relation. |
|
<p>Alle Daten <a href="kigaAlleKi.php">anzeigen</a></p>
|
|
Ein weiterer Link führt zur Leitseite zurück. |
|
<p class="text_1">Zuramp;uuml;ck zur <a href="http://localhost/kindergarten.html">Leitseite</a></p>
|
|
</body>
|
|
</html>
|
|
Programm Pruefen.inc.php |
|
Diese Datei enthält die oben und in den folgenden Programmen benötigten Prüffunktionen für Eingaben. Sie wird von Theis in [Theis 2023] zur Verfügung gestellt (siehe [Theis 2023, S. 210]). |
|
<?php
|
|
function int_positiv($bereich, $text, amp;$zahl)
|
|
{
|
|
if(!is_numeric($text))
|
|
{
|
|
echo "<p style='color:#ff0000;'>$bereich: Zahl eintragen</p>";
|
|
return false;
|
|
}
|
|
if($text == "0")
|
|
{
|
|
$zahl = 0;
|
|
return true;
|
|
}
|
|
$zahl = intval($text);
|
|
if($zahl < 0)
|
|
{
|
|
echo "<p style='color:#ff0000;'>" . "$bereich: Ganze Zahl >= 0 eintragen</p>";
|
|
return false;
|
|
}
|
|
else
|
|
return true;
|
|
}
|
|
function id_neu_doppelt($bereich, $pk, $con, $tab, $feld)
|
|
{
|
|
$sql = "SELECT * FROM $tab WHERE $feld = ?";
|
|
$res = $con->execute_query($sql, [$pk]);
|
|
$anzahl = $res->num_rows;
|
|
$res->close();
|
|
if($anzahl > 0)
|
|
{
|
|
echo "<p style='color:#ff0000;'>$bereich: Bereits vorhanden</p>";
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
function datum_gueltig($bereich, $datum, amp;$gt)
|
|
{
|
|
$feld = mb_split("\.", $datum);
|
|
if(count($feld) != 3)
|
|
{
|
|
echo "<p style='color:#ff0000;'>". "$bereich: Datum in T.M.JJJJ eintragen</p>";
|
|
return false;
|
|
}
|
|
if(!is_numeric($feld[0]) || !is_numeric($feld[1]) || !is_numeric($feld[2]))
|
|
{
|
|
echo "<p style='color:#ff0000;'>". "$bereich: Zahlen für Tag, Monat und Jahr eintragen</p>";
|
|
return false;
|
|
}
|
|
$tag = intval($feld[0]);
|
|
$monat = intval($feld[1]);
|
|
$jahr = intval($feld[2]);
|
|
if(checkdate($monat, $tag, $jahr))
|
|
{
|
|
$gt = $jahr . "-" . $monat . "-" . $tag;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
echo "<p style='color:#ff0000;'>" . "$bereich: Gültiges Datum eintragen</p>";
|
|
return false;
|
|
}
|
|
}
|
|
?>
|
|
Programm KiGaAlleKi.php |
|
Dieses Programm dient zur Ausgabe aller Datensätze nach einem Neueintrag. |
|
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Ausgabe in Tabelle</title>
|
|
<link rel="stylesheet" type="text/css" href="kindergarten.css">
|
|
</head>
|
|
<body>
|
|
<table>
|
|
<tr>
|
|
<td>KindID</td>
|
|
<td>Name</td>
|
|
<td>Vorname</td>
|
|
<td>AdressID</td>
|
|
<td>Eintrittsdatum</td>
|
|
<td>Geburtstag</td>
|
|
<td>GKind JN</td>
|
|
</tr>
|
|
<?php
|
|
include "zeit2.inc.php";
|
|
$con = new mysqli("localhost", "root", "", "kindergarten");
|
|
$sql = "SELECT * FROM kinder";
|
|
$res = $con->execute_query($sql);
|
|
while($dsatz = $res->fetch_assoc())
|
|
{
|
|
echo "<tr>";
|
|
echo "<td><center>" . $dsatz["KindID"] . "</td>";
|
|
echo "<td><left>" . $dsatz["Name"] . "</td>";
|
|
echo "<td><left>" . $dsatz["Vorname"] . "</td>";
|
|
echo "<td><center>" . $dsatz["AdressID"] . "</td>";
|
|
echo "<td><center>" . db_datum_aus($dsatz["Eintrittsdatum"]) . "</td>";
|
|
echo "<td><right>" . db_datum_aus($dsatz["Geburtstag"]) . "</td>";
|
|
echo "<td><center>" . $dsatz["GKindJN"] . "</td>";
|
|
echo "</tr>";
|
|
}
|
|
$res->close();
|
|
$con->close();
|
|
?>
|
|
</table>
|
|
<p class="text_1"><a href="http://localhost/kindergarten.html">
|
|
Zuramp;uuml;ck zur Leitseite</a></p>
|
|
</body>
|
|
</html>
|
|
4.5 Daten eines Kindes löschen |
|
Diese Aufgabe basiert auf den Aufgaben 4.1 und 4.2. |
|
Erläutern Sie die notwendigen PHP-Programme, v.a. dort, wo es um die Verknüpfung von Datenbank und Webseite geht. |
|
4.5.1 Aufgabe |
|
Der dritte Button soll erlauben, die Daten eines Kindes zu löschen. |
|
|
|
Dazu soll zuerst in einer Gesamttabelle das betreffende Kind ausgewählt werden: |
|
|
|
Nach Wahl eines Datensatzes und Anforderung der Löschung soll diese durchgeführt werden. |
|
4.5.2 Lösung |
|
Das Gesamtprogramm ist in zwei Dateien aufgeteilt, KiGaLoeschen_a.php und KiGaLoeschen_b.php. |
|
Programm KiGaLoeschen_a.php. |
|
In diesem Programm erfolgt der Aufbau des Formulars. |
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Datensatz auswählen</title>
|
|
<link rel="stylesheet" type="text/css" href="kindergarten.css">
|
|
</head>
|
|
<body>
|
|
<p class="text_3">Wamp;auml;hlen Sie den zu lamp;ouml;schenden Datensatz aus:</p>
|
|
Folgende Zeile legt fest, was beim "Submit" passiert. Es wird die zweite Datei aufgerufen, in der die Datenbankaktionen festgelegt sind. |
|
<form action="KiGaloeschen_b.php" method="post">
|
|
<table>
|
|
<thead>
|
|
<th>Auswahl</th>
|
|
<th>KindID</th>
|
|
<th>Name</th>
|
|
<th>Vorname</th>
|
|
<th>AdressID</th>
|
|
<th>Eintrittsdatum</th>
|
|
<th>Geburtstag</th>
|
|
<th>GKindJN</th>
|
|
</thead>
|
|
<?php
|
|
include "zeit2Auf diese .inc.php";
|
|
$con = new mysqli("localhost", "root", "", "kindergarten");
|
|
$sql = "SELECT * FROM kinder";
|
|
$res = $con->execute_query($sql);
|
|
Jetzt stehen die gemäß der SQL-Abfrage gehosteten Attribute und ihre Ausprägungen in der assoziativen Variablen $dsatz zur Verfügung. |
|
Mit . . . |
|
input type='radio' name='auswahl'
|
|
wird das Auswahlmenü angefordert. |
|
Weiter im Programm: |
|
while($dsatz = $res->fetch_assoc())
|
|
Das Formular erhält die Bezeichnung auswahl. Damit wird vor dem Löschvorgang in KiGaLoeschen_b.php geprüft, ob wirklich eine Auswahl für den zu löschenden Datensatz getroffen wurde. |
|
echo "<tr><td><input type='radio' name='auswahl'"
|
|
. " value='" . $dsatz["KindID"] . "'></td>"
|
|
. "<td><center>" . $dsatz["KindID"] . "</td>"
|
|
. "<td>" . $dsatz["Name"] . "</td>"
|
|
. "<td>" . $dsatz["Vorname"] . "</td>"
|
|
. "<td><center>" . $dsatz["AdressID"] . "</td>"
|
|
. "<td><center>" . db_datum_aus($dsatz["Eintrittsdatum"]) . "</td>"
|
|
. "<td>" . db_datum_aus($dsatz["Geburtstag"]) . "</td>"
|
|
. "<td><center>" . $dsatz["GKindJN"] . "</td></tr>";
|
|
$res->close();
|
|
$con->close();
|
|
?>
|
|
</table>
|
|
Die folgende Schaltfläche erlaubt es den Löschvorgang zu starten. |
|
<p><input type="submit" value="Datensatz lamp;ouml;schen"></p>
|
|
<p class="text_1">Zuramp;uuml;ck zur <a href="http://localhost:80/kindergarten.html">Leitseite</a></p>
|
|
</form>
|
|
</body>
|
|
</html>
|
|
Programm KiGaLoeschen_b.php |
|
Hier wird das Löschen des Datensatzes durchgeführt. |
|
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Datensatz loeschen</title>
|
|
<link rel="stylesheet" type="text/css" href="kindergarten.css">
|
|
</head>
|
|
<body>
|
|
<?php
|
|
Prüfen, ob Auswahl getroffen wurde: |
|
if(isset($_POST["auswahl"]))
|
|
{
|
|
$con = new mysqli("localhost", "root", "", "kindergarten");
|
|
Lösche-Befehl in $sql speichern und ausführen: |
|
$sql = "delete from kinder where kindid= " . intval($_POST["auswahl"]);
|
|
$res = $con->execute_query($sql);
|
|
echo "<p>Datensatz ist gelamp;ouml;scht</p>";
|
|
}
|
|
else
|
|
echo "<p>Keine Auswahl getroffen</p>";
|
|
?>
|
|
Das Programm KiGaAlleKi wurde oben beschrieben. |
|
<p>Alle Daten <a href="kigaAlleKi.php">anzeigen</a></p>
|
|
<p class="text_1"><a href="http://localhost:80/kindergarten.html">Zuramp;uuml;ck zur Leitseite</a></p>
|
|
</body>
|
|
</html>
|
|
4.6 Daten ausgewählter Kinder anzeigen |
|
Diese Aufgabe basiert auf den Aufgaben 4.1 und 4.2. |
|
Erläutern Sie die notwendigen PHP-Programme, v.a. dort, wo es um die Verknüpfung von Datenbank und Webseite geht. |
|
4.6.1 Aufgabe |
|
Diese Schaltfläche soll erlauben, die Datensätze bestimmter Kinder, ausgewählt nach den Anfangsbuchstaben des Namens, auszuwählen und auszugeben. |
|
|
|
Das Ergebnis soll, bei Wahl des Anfangsbuchstabens S, so aussehen: |
|
|
|
4.6.2 Lösung |
|
Das Programm KiGaName.php leistet das Gewünschte. Neu hinzu kommt gegenüber den obigen Beispielen der Maskierungsoperator LIKE im SQL-Statement. |
Programm KiGaName.php |
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Auswahl mit Namensanfang</title>
|
|
<link rel="stylesheet" type="text/css" href="kindergarten.css">
|
|
</head>
|
|
<body>
|
|
<table>
|
|
<caption class="text_2">Ausgewamp;auml;hlte Kinder</caption>
|
|
<thead>
|
|
<th>KindID</th>
|
|
<th>Name</th>
|
|
<th>Vorname</th>
|
|
<th>AdressID</th>
|
|
<th>Eintrittsdatum</th>
|
|
<th>GKind JN</th>
|
|
</thead>
|
|
<?php
|
|
include "zeit2.inc.php";
|
|
$con = new mysqli("localhost", "root", "", "kindergarten");
|
|
Der Zugriff von der Webseite auf die (Server-Datenbank) erfolgt wieder mit einem Prepared Statement. |
|
$sql = "SELECT KindID, Name, Vorname, AdressID, Eintrittsdatum,
|
|
GKindJN FROM kinder where Name like ?";
|
|
$anfang = $_POST["anfang"] . "%";
|
|
$res = $con->execute_query($sql, [$anfang]);
|
|
Prüfung der Zahl der Treffer. |
|
if($res->num_rows == 0)
|
|
echo "<br>Keine Ergebnisse<br><br>";
|
|
Obige Prüfung sollte bei Abfragen der Datenbank immer erfolgen. Sie wurde hier aus Platzgründen meist weggelassen. |
|
Falls keine Treffer vorliegen, startet die While-Schleife nicht. |
|
while($dsatz = $res->fetch_assoc())
|
|
{
|
|
echo "<tr>";
|
|
echo "<td><center>" . $dsatz["KindID"] . "</td>";
|
|
echo "<td><left>" . $dsatz["Name"] . "</td>";
|
|
echo "<td><left>" . $dsatz["Vorname"] . "</td>";
|
|
echo "<td><center>" . $dsatz["AdressID"] . "</td>";
|
|
echo "<td><center>" . db_datum_aus($dsatz["Eintrittsdatum"])
|
|
. "</td>";
|
|
echo "<td><center>" . $dsatz["GKindJN"] . "</td>";
|
|
echo "</tr>";
|
|
}
|
|
$res->close();
|
|
$con->close();
|
|
?>
|
|
</table>
|
|
<p class="text_1"><a href="http://localhost/kindergarten.html"> Zuramp;uuml;ck zur Leitseite</a></p>
|
|
</body>
|
|
</html>
|
|
4.7 Daten von Kindern ändern |
|
Diese Aufgabe basiert auf den Aufgaben 4.1 und 4.2. |
|
Erläutern Sie die notwendigen PHP-Programme, v.a. dort, wo es um die Verknüpfung von Datenbank und Webseite geht. |
|
4.7.1 Aufgabe |
|
Die folgende Schaltfläche soll erlauben, die Daten eines Kindes zu ändern. |
|
|
|
4.7.2 Lösung |
|
Die Lösung ist auf drei Programme verteilt: |
|
- ki_aendern_a.php
- ki_aendern_b.php
- ki_aendern_c.php
|
|
Ki_aendern_a.php |
|
Das erste Programm fordert eine Auswahlliste mit Radiobuttons an, wie schon in Abschnitt 2.7 vorgestellt. |
|
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Datensatz auswählen</title>
|
|
<link rel="stylesheet" type="text/css" href="kindergarten.css">
|
|
</head>
|
|
<body>
|
|
<p class="text_3">Treffen Sie Ihre Auswahl:</p>
|
|
Am Anfang des Formulars wird über den Parameter action festgelegt, was bei submit zu tun ist und über method mit welcher Methode dies geschehen soll. |
|
<form action="ki_aendern_b.php" method="post">
|
|
<table>
|
|
<thead>
|
|
<th>Auswahl</th>
|
|
<th>KindID</th>
|
|
<th>Name</th>
|
|
<th>Vorname</th>
|
|
<th>AdressID</th>
|
|
<th>Eintrittsdatum</th>
|
|
<th>Geburtstag</th>
|
|
<th>GKindJN</th>
|
|
</thead>
|
|
<?php
|
|
include "zeit2.inc.php";
|
|
$con = new mysqli("localhost", "root", "", "kindergarten");
|
|
$sql = "SELECT * FROM kinder";
|
|
$res = $con->execute_query($sql);
|
|
while($dsatz = $res->fetch_assoc())
|
|
Anforderung Auswahl-Button (type='radio') mit Bezeichnung auswahl: |
|
echo "<tr><td><input type='radio' name='auswahl'" .
|
|
" value='" . $dsatz["KindID"] . "'></td>" .
|
|
"<td><center>" . $dsatz["KindID"] . "</td>"
|
|
"<td>" . $dsatz["Name"] . "</td>" .
|
|
"<td>" . $dsatz["Vorname"] . "</td>" .
|
|
"<td><center>" . $dsatz["AdressID"] . "</td>"
|
|
"<td><center>" . db_datum_aus($dsatz["Eintrittsdatum"]) .
|
|
"</td>" .
|
|
"<td>" . db_datum_aus($dsatz["Geburtstag"]) . "</td>" .
|
|
"<td><center>" . $dsatz["GKindJN"] . "</td></tr>"; .
|
|
$res->close();
|
|
$con->close();
|
|
?>
|
|
</table>
|
|
Mit submit wird - siehe oben - das Programm ki_aendern_b.php aufgerufen. |
|
<p><input type="submit" value="Datensatz anzeigen"></p>
|
|
<p class="text_1">Zuramp;uuml;ck zur <a href="http://localhost/kindergarten.html">Leitseite</a></p>
|
|
</form>
|
|
</body>
|
|
</html>
|
|
Das Programm führt zu folgender Ausgabe: |
|
|
|
Wurde ein Datensatz gewählt und dann die Schaltfläche Datensatz anzeigen angeklickt, startet das folgende Programm. |
|
Ki_aendern_b.php |
|
Dies führt zu folgender Ausgabe, falls Moritz Meier angewählt wurde. |
|
|
|
Hier das Programm: |
|
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Datensatz anzeigen</title>
|
|
</head>
|
|
<body>
|
|
<?php
|
|
Für die Umstellung des Datums: |
|
include "zeit2.inc.php";
|
|
if(isset($_POST["auswahl"]))
|
|
{
|
|
$con = new mysqli("localhost", "root", "", "kindergarten");
|
|
Hier wird im SQL-Befehl das Ergebnis des Post-Vorgangs (die KindID), abgesichert als Integer-Wert eingesetzt. |
|
$sql = "SELECT * FROM kinder WHERE KindID = "
|
|
. intval($_POST["auswahl"]);
|
|
$res = $con->execute_query($sql);
|
|
$dsatz = $res->fetch_assoc();
|
|
echo "<p class='text_3'>Bitte amp;auml;ndern und speichern:</p>";
|
|
Wiederum wird als Aktion ein Programm aufgerufen (zum Ändern des Datensatzes) und die zu verwendende Methode spezifiziert. |
|
echo "<form action='ki_aendern_c.php' method='post'>";
|
|
echo "<p><input name='id' value='" . $dsatz["KindID"]
|
|
. "'> KindID</p>";
|
|
echo "<p><input name='na' value='" . $dsatz["Name"]
|
|
. "'> Nachname</p>";
|
|
echo "<p><input name='vn' value='" . $dsatz["Vorname"]
|
|
. "'> Vorname</p>";
|
|
echo "<p><input name='ad' value='" . $dsatz["AdressID"]
|
|
. "'> AdressID</p>";
|
|
echo "<p><input name='ei' value='" .
|
|
db_datum_aus($dsatz["Eintrittsdatum"]) . "'>Eintrittsdatum</p>";
|
|
echo "<p><input name='gt' value='" .
|
|
db_datum_aus($dsatz["Geburtstag"]) . "'>
|
|
Geburtstag (in JJJJ-MM-TT)</p>";
|
|
echo "<input type='hidden' name='oripn' value='" .
|
|
$_POST["auswahl"] . "'>";
|
|
echo "<p><input type='submit' value='Speichern'>
|
|
<input type='reset' value='amp;Auml;nderungen zurücksetzen'></p>";
|
|
echo "</form>";
|
|
$res->close();
|
|
$con->close();
|
|
}
|
|
else
|
|
echo "<p>Keine Auswahl getroffen</p>";
|
|
?>
|
|
<p class="text_1"><a href="http://localhost/kindergarten.html">
|
|
Zuramp;uuml;ck zur Leitseite</a></p>
|
|
</body>
|
|
</html></body>
|
|
</html>
|
|
Ki_aendern_c.php |
|
Dieses Programm führt mit Hilfe eines Update-Befehls die Änderung durch. |
|
<!DOCTYPE html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Datensatz ändern</title>
|
|
<link rel="stylesheet" type="text/css" href="kindergarten.css">
|
|
</head>
|
|
<body>
|
|
<?php
|
|
include "pruefen.inc.php";
|
|
$con = new mysqli("localhost", "root", "", "kindergarten");
|
|
echo "<p class='text_3'>Datensatz geändert!<br>";
|
|
Wieder ein Prepared Statement: |
|
$sql = "UPDATE kinder SET kindid= ?, name = ?, vorname = ?," .
|
|
" adressid = ?, eintrittsdatum = ?, geburtstag = ?" .
|
|
" WHERE kindid = " . $_POST["oripn"];
|
|
$con->execute_query($sql, [$_POST["id"], $_POST["na"],
|
|
$_POST["vn"], $_POST["ad"], $_POST["ei"], $_POST["gt"]]);
|
|
$con->close();
|
|
?>
|
|
<p>Zur <a href="ki_aendern_a.php">Auswahl</a></p>
|
|
</body>
|
|
</html>
|
|
|
|
5 Relationale Theorie I |
|
Für eine umfassende Einführung in die relationale Modellierung vgl. [Staud 2021]: |
|
Staud, Josef Ludwig: Relationale Datenbanken. Grundlagen, Modellierung, Speicherung, Alternativen (2. Auflage). Hamburg 2021 (tredition) |
|
Auszüge finden sich auf http://www.staud.info/rm1/rm_t_1.htm |
|
Aufbau von Relationen |
|
In [Staud 2021, Kapitel 4] wird der Aufbau von Relationen erläutert. Hieraus nur eine Abbildung, die den Aufbau von Relationen und die hier gewählte Begrifflichkeit erläutert. Sie zeigt auch, dass zwischen beliebigen Tabellen und Relationen große Unterschiede bestehen. |
|
g |
|
Abbildung 4.7-1: Aufbau von Relationen. Quelle: [Staud 2019, S. 57] |
|
Abkürzungen: |
|
VName: Vorname |
|
PW: Personalwesen, IT: IT-Abteilung, RE: Rechnungswesen, PW: Personalwesen, VB: Vertrieb |
|
Die Antwort auf die Frage "Durch welche Eigenschaften wird eine Tabelle zu einer Relation?" findet sich in Aufgabe 5.1. |
|
Rollen von Attributen |
|
Attribute können folgende "Rollen" in Relationen annehmen (vgl. [Staud 2021, S. 117ff]): |
|
- Schlüssel
- Schlüsselkandidaten (candidate keys). Identifizierende Attribute, die nicht als Schlüssel eingesetzt werden.
- Teil eines zusammengesetzten Schlüssels, dann werden sie Schlüsselattribute (SA) genannt
- Attribute außerhalb des Schlüssels/der Schlüssel. Diese werden Nichtschlüsselattribute (NSA) genannt
- Determinanten. Attribute, von denen andere funktional abhängig sein können.
|
|
Zur Veranschaulichung hier ein FA-Diagramm (Diagramm der funktionalen Abhängigkeiten) einer Relation zu Aufträgen (Aufträge_1NF) bei der die Determinanten (D), Schlüsselattribute (SA) und Nichtschlüsselattribute (NSA) markiert sind. |
|
|
|
Abbildung 4.7-2: Schlüsselattribute (SA), Nichtschlüsselattribute (NSA) und Determinanten (D) in Aufträge_1NF. Quelle: [Staud 2021, S. 118] |
|
Abkürzungen: |
|
AuftrNr: Auftragsnummer |
|
PosNr: Positionsnummer |
|
AuftrDatum: Auftragsdatum |
|
KuNr: Kundennummer |
|
KuName: Kundenname |
|
ProdNr: Produktnummer |
|
ProdBez: Produktbezeichnung |
|
Nun zu den Aufgaben. |
|
|
|
5.1 Relationen |
|
5.1.1 Aufgabe |
|
Durch welche Eigenschaften wird eine Tabelle zu einer Relation? |
|
5.1.2 Lösung |
|
Folgende Eigenschaften sind dafür verantwortlich: |
|
(1) Jede Zeile (auch "Reihe" oder "Tupel") beschreibt ein Objekt (bzw. eine Beziehung), die Tabelle als Ganzes beschreibt die Objekt- oder Beziehungsklasse.
|
|
(2) In jeder Spalte steht als Kopf der Name eines Attributs, darunter stehen die Attributsausprägungen, die das jeweilige Objekt (die Beziehung) beschreiben.
|
|
(3) Eine Relation hat immer einen Schlüssel, der auch aus mehr als einem Attribut bestehen kann, und mindestens ein beschreibendes Attribut.
|
|
(4) Es gibt keine zwei identischen Tupel, d.h. jedes Tupel beschreibt ein anderes Objekt.
|
|
(5) Im Schnittpunkt jeder Zeile und Spalte wird genau eine Attributsausprägung festgehalten, nicht mehr. Dies macht die Tabelle zur flachen Tabelle.
|
|
Vgl. [Staud 2021, Abschnitt 4.2]
|
|
5.2 Funktionale Abhängigkeiten |
|
5.2.1 Aufgabe |
|
Wie sind funktionale Abhängigkeiten definiert? Erläutern Sie auch mit Hilfe aussagekräftiger Beispiele. |
|
5.2.2 Lösung |
|
Funktionale Abhängigkeit basiert auf der Semantik des Anwendungsbereichs und bezieht sich auf das Verhältnis zweier Attribute. Ein Attribut A2 ist funktional abhängig von einem Attribut A1, wenn von den Ausprägungen bei A1 auf die von A2 geschlossen werden kann. Es besteht also ein entsprechender inhaltlicher Zusammenhang. Die Notation: |
Definition FA |
A1 => A2 |
|
A1 determiniert A2, A1 ist Determinante für A2. Vgl. [Staud 2021, Kapitel 8] für detailliertere Ausführungen. |
|
Beispiele: |
|
BezAbteilung => AbtLeiter //Von der Bezeichnung der Abteilung kann auf den Abteilungsleiter geschlossen werden. |
|
PersNr => Wohnort //Von der Personalnummer kann auf den Wohnort geschlossen werden bzw. für eine Personalnummer gibt es genau einen Wohnort. Sollten die Angestellten auch mehrere Adressen in der Firmendatenbank angeben können, wäre diese funktionale Abhängigkeit nicht da. |
|
(PosNr, ReNr) => ArtNr //Von Rechnungsnummer UND Positionsnummer kann auf die Artikelnummer geschlossen werden bzw. für eine Kombination von Rechnungsnummer und Positionsnummer gibt es genau eine Artikelnummer. |
|
ArtNr => Preis //Von der Artikelnummer kann auf den Peis geschlossen werden bzw. für eine Artikelnummer gibt es genau einen Preis. |
|
5.3 3NF - Definition |
|
5.3.1 Aufgabe |
|
a) Wie ist die 3NF definiert?
|
|
b) Geben Sie textlich ein inhaltlich tragfähiges Beispiel einer Relation an, die in 2NF und nicht in 3NF ist.
|
|
5.3.2 Lösung |
|
a) |
|
Die 3NF beseitigt funktionale Abhängigkeiten zwischen Nichtschlüsselattributen (NSA). Solche führen insgesamt - vom Schlüssel über die zwei Nichtschlüsselattribute - zu transitiven Abhängigkeiten. Deshalb kann die 3NF so definiert werden: |
Definition 3NF |
Eine Relation ist in 3NF, falls sie in 2NF ist und falls keine transitiven Abhängigkeiten zwischen dem Schlüssel und den Nichtschlüsselattributen vorliegen. |
|
Vgl. [Staud 2021, Abschnitt 10.5]. |
|
b) |
|
Rechnungsköpfe (#RechNr, RechDatum, KundenNr, Kundenname) |
|
Begründung: 2NF ist erfüllt, da es keinen zusammengesetzten Schlüssel gibt. Die 3NF wird durch folgende transitive Abhängigkeit verhindert: RechNr => KundenNr => KundenName, d.h. der Name des Kunden wird jedesmal erfasst, wenn in einer Rechnung seine Kundennummer benötigt wird. |
|
5.4 2NF - Definition |
|
5.4.1 Aufgabe |
|
a) Wie ist die 2NF definiert?
|
|
b) Geben Sie textlich ein inhaltlich tragfähiges Beispiel einer Relation an, die in 1NF und nicht in 2NF ist.
|
|
5.4.2 Lösung |
|
a) |
|
Die 2NF beseitigt funktionale Abhängigkeiten zwischen Schlüsselattributen (Teilen des Schlüssels) und Nichtschlüsselattributen (NSA): "SA => NSA". Für solche Schlüsselattribute gilt, dass Attributsausprägungen auch mehrfach vorkommen können. Dann taucht auch jedesmal dieselbe Ausprägung beim NSA auf, was redundant ist. |
|
b) |
|
Das Beispiel betrifft Projektmitarbeit. Diese hat einen Schlüssel aus Angestelltennummer (AngNr) und Projektbezeichnung (ProjBez). Die 1NF kann angenommen werden. |
|
Projektmitarbeit (#(AngNr, ProjNr), Beginn, ProjBez) |
|
Die 2NF ist nicht erfüllt, denn es gilt: ProjNr => ProjBez, d.h. die Projektbezeichnung ist funktional abhängig von der Projektnummer und wird, da in diesem Schlüssel eine Projektnummer natürlich mehrfach vorkommen kann, mehrfach gespeichert. |
|
5.5 Normalisierung |
|
5.5.1 Aufgabe |
|
Folgende Relation ist gegeben: |
|
Angestellte (#(PersNr, ProgSprBez), BezCompiler, Name, Vorname) |
|
Hinweis : ProgSprBez bedeutet Bezeichnung einer Programmiersprache. BezCompiler bedeutet Bezeichnung des Compilers, der für die Programmiersprache im Unternehmen genutzt wird. |
|
a) Erstellen Sie ein FA-Diagramm dieser Relation. Vermerken Sie bei jedem Attribut, welche Rolle es hat (NSA, Schlüssel, usw.).
|
|
b) In welcher NF ist diese Relation? Bitte begründen.
|
|
c) Beschreiben Sie, wo bei dieser Relation Redundanz steckt.
|
|
d) Normalisieren Sie! Das Ergebnis soll in 3NF sein. Geben Sie für jede Ergebnisrelation ein FA-Diagramm an. Geben Sie in jedem entstehenden FA-Diagramm für jedes Attribut seine Rolle an. Kennzeichnen Sie eventuelle Fremdschlüssel.
|
|
5.5.2 Lösungen |
|
a) |
|
|
|
Abbildung 5.5-1: FA-Diagramm der Relation Angestellte mit Rollen von Attributen |
|
S: Schlüssel, SA: Schlüsselattribut, NSA: Nichtschlüsselattribut, D: Determinante |
|
b) |
|
1NF, nicht 2NF, da Schlüsselattribute Determinanten sind. |
|
c) |
|
Es wird z.B. mehrfach erfasst, welchen Namen eine Person hat, wenn sie mehrere Programmiersprachen beherrscht. Genauso wird mehrfach erfasst, welchen Compiler das Unternehmen für die jeweilige Programmiersprache nutzt, falls mehrere Mitarbeiter dieselbe Programmiersprache nutzen. |
|
d) |
|
|
|
Abbildung 5.5-2: FA-Diagramme der normalisierten Relation Angestellte |
|
5.6 Nicht 1NF, nicht 3NF |
|
5.6.1 Aufgabe |
|
Erstellen Sie eine inhaltlich aussagekräftige Relation, die einen Verstoß gegen die 1NF und einen gegen die 3NF enthält. Bringen Sie diese Relation in die BCNF. Erstellen Sie vom Ergebnis ein textliches Datenmodell. |
|
5.6.2 Lösungsbeispiel |
|
Angestellte (#PersNr, ProgrSpr, Abteilung, Abteilungsleiter) |
|
Das Attribut ProgrSpr hat Mehrfacheinträge - Verstoß gegen die 1NF. Abteilungsleiter ist funktional abhängig von Abteilung, für jede Person wird nicht nur die Abteilung, sondern auch der Abteilungsleiter erfasst - Verstoß gegen die 3NF. Dieser wird beseitigt, indem eine neue Relation Abteilungen angelegt wird und Angestellte.Abteilung zum Fremdschlüssel wird: |
non 3NF,
3NF |
Abteilungen (#Abteilung, Abteilungsleiter) |
|
Angestellte (#PersNr, Abteilung) |
|
Die Mehrfacheinträge werden beseitigt, indem eine Relation zur Programmiersprachenkompetenz mit zusammengesetztem Schlüssel eingerichtet wird: |
|
ProgSprKompetenz (#(PersNr, ProgrSpr)) |
|
PersNr wird hier zum Fremdschlüssel. |
|
5.7 Idealform |
|
5.7.1 Aufgabe |
|
Es gibt eine Idealform für eine Relation, bei der diese ohne jegliche Redundanz ist. Beschreiben Sie sie. |
|
5.7.2 Lösung |
|
Eine solche Relation hat entweder nur Schlüsselattribute oder einen Schlüssel mit Attributen, die nur von diesem voll funktional abhängig sind. Auch mehrere Schlüssel sind möglich. M.a.W.: Jede Determinante ist Schlüssel, wodurch die BCNF erreicht ist [Staud 2021, Kapitel 11]. Hier sind dann auch die 4NF und 5NF erfüllt. |
5NF |
Zwei abstrakte Beispiele: |
|
|
|
Abbildung 5.7-1: FA-Diagramm Idealform 1 mit zusammengesetztem Schlüssel |
|
|
|
Abbildung 5.7-2: FA-Diagramm Idealform 2 mit einfachem Schlüssel |
|
5.8 Von UN zu 1NF |
|
5.8.1 Aufgabe |
|
a) Erstellen Sie eine inhaltlich fundierte Relation in tabellarischer Darstellung, die ein mehrwertiges Attribut aufweist, also nicht in 1NF ist. Bringen Sie diese mittels Tupelvermehrung in die 1NF.
|
|
b) Bringen Sie die Relation in die 2NF. Geben Sie die textliche Notation an. Erstellen Sie für jede Relation ein FA-Diagramm.
|
|
5.8.2 Lösungsbeispiel |
|
a) |
|
Die folgende Relation erfasst - unnormalisiert - den Besuch von Vorlesungen durch Studierende. |
|
Vorlesungsbesuch_UN |
|
MatrikelNr |
NameStud |
LVBez |
1007 |
Stauber |
DBS, GPROZ |
1008 |
Ranz |
DBS, UMOD |
1009 |
Rübezahl |
GPROZ |
| |
Die normalisierte Fassung (Tupelvermehrung, vgl. [Staud 2021, Abschnitt 7.3]) ist wie folgt: |
1NF |
Vorlesungsbesuch_1NF |
|
MatrikelNr |
NameStud |
LVBez |
1007 |
Stauber |
DBS |
1007 |
Stauber |
GPROZ |
1008 |
Ranz |
DBS |
1008 |
Ranz |
UMOD |
1009 |
Rübezahl |
GPROZ |
| |
LVBez: Kurzbezeichnung einer Lehrveranstaltung |
|
Die Redundanz liegt darin, dass der Zusammenhang zwischen MatrikelNr und NameStud mehrfach erfasst wird. |
|
b) |
|
Die Normalisierung für die 2NF verlangt, dass die Redundanz beseitigt wird. Dazu erstellen wir eine Relation zu den Studierenden: |
2NF |
Studierende_2NF (#MatrikelNr, NameStud) |
|
Jetzt wird der Zusammenhang zwischen MatrikelNr und NameStud nur noch jeweils einmal festgehalten. Den Vorlesungsbesuch erfassen wir in einer neuen "schlanken" Relation: |
|
Vorlesungsbesuch_2NF (#(MatrikelNr, LVBez)) |
|
Hier wird die MatrikelNr zum Fremdschlüssel. |
|
2NF?: Tatsächlich sind beide Relationen bereits in der höchsten Normalform (5NF). |
|
|
|
Abbildung 5.8-1: FA-Diagramme zu Vorlesungsbesuch und Studierende |
|
LVBez: Bezeichnung der Lehrveranstaltung |
|
5.9 Von 1NF zu 3NF |
|
5.9.1 Aufgabe |
|
Die folgende Tabelle zeigt eine Relation in 1NF, bei der es um Projektmitarbeit geht. |
|
Projektmitarbeit_1NF |
|
Name |
PersonalNr |
NameProj |
Funktion |
FunktionsSpez |
ProjDauer |
ProjZugeh |
ProjBudget |
Stein |
12345 |
SmartC |
Leiter |
ArbGr02 |
24 |
24 |
10 |
Maier |
12346 |
SmartC |
DV |
Gesamt |
24 |
18 |
10 |
Müller |
23456 |
NetBNG |
Leiter |
Gesamt |
18 |
18 |
30 |
Bach |
54321 |
NetBNG |
InfMan |
BPR |
18 |
10 |
30 |
Bach |
54321 |
SmartC |
DV |
Vernetzung |
24 |
24 |
10 |
Baum |
65432 |
W2.0 |
Finanzen |
Ausgaben |
36 |
36 |
5 |
Baum |
65432 |
W2.0 |
Contr |
Gesamt |
36 |
24 |
5 |
Baum |
65432 |
BPR |
Contr |
Einnahmen |
12 |
12 |
1 |
..... |
|
|
|
|
|
|
|
| |
Erläuterungen zu Aufbau und Semantik
|
|
- Schlüssel der Relation: #(PersonalNr, NameProj, Funktion)
- Funktion beschreibt, welche Funktion der Angestellte im Projekt wahrnimmt.
- Das Attribut FunktionsSpez beschreibt die Tätigkeit der Person im jeweiligen Projekt. Dies bedeutet, dass dieselbe Funktion bei einer anderen Person oder in einem anderen Projekt anders beschrieben sein kann.
- ProjDauer beschreibt, für wie viele Monate das Projekt eingerichtet wurde.
- ProjZugeh beschreibt, für wie viele Monate der Angestellte diesem Projekt zugeordnet wurde.
- ProjBudget gibt die finanziellen Mittel an, die dem Projekt zur Verfügung stehen.
- Die Abkürzung BPR bei der Funktionsspezifikation bedeutet Business Process Reengineering.
- Eine Person kann in verschiedenen Projekten dieselbe Funktion haben.
- Eine Person kann im selben Projekt mehrere Funktionen ausüben.
|
|
Führen Sie für obige Relation folgende Schritte durch: |
|
a) Erstellen Sie ein FA-Diagramm der obigen Relation.
|
|
b) Überführen Sie diese Relation in die 3NF und geben Sie die textliche Notation an. Erstellen Sie für jede neu entstehende Relation ein FA-Diagramm.
|
|
c) Geben Sie dann das Datenmodell in textlicher und grafischer Notation an.
|
|
5.9.2 Lösung |
|
a) |
|
Das FA-Diagramm ergibt sich wie folgt: |
|
|
|
Abbildung 5.9-1: FA-Diagramm Projektmitarbeit |
|
Begründung: |
|
- Da nur die drei Attribute Funktion, PersNr und BezProj zusammen die FunktionsSpez determinieren, müssen sie zusammen Schlüssel sein.
- Ein Teil des Schlüssels, (PersNr, BezProj), ist Determinante für die drei Attribute ProjZugeh, ProjBudget und ProjDauer.
- PersNr ist Determinante für Name
|
|
b) |
|
Die Lösung besteht darin, alle Determinanten zu Schlüsseln zu machen (=>BCNF!) und die neu entstehenden Relationen der Semantik gemäß zu verknüpfen. Gemäß der Aufgabenstellung entstehen Relationen mit FA-Diagrammen in BCNF: |
Von 1NF zu BCNF |
Funktionsspezifikation (#(Funktion, BezProj, PersNr), FunktionsSpez) |
|
|
|
Abbildung 5.9-2: FA-Diagramm zu Funktionsspezifikation |
|
Funktionsspezifikation.NameProj ist Fremdschlüssel bzgl. Projekte. |
|
Funktionsspezifikation.PersonalNr ist Fremdschlüssel bzgl. Personal |
|
Personal (#PersonalNr, Name) |
|
|
|
Abbildung 5.9-3: FA-Diagramm zu Personal |
|
Projektmitarbeit (#(PersNr, BezProj), Funktion, ProjZugeh) |
|
|
|
Abbildung 5.9-4: FA-Diagramm zu Projektmitarbeit |
|
Projektmitarbeit.NameProj ist Fremdschlüssel bzgl. Projekte. |
|
Projektmitarbeit.PersNr ist Fremdschlüssel bzgl. Personal |
|
Projekte (#NameProj, ProjBudget, ProjDauer) |
|
|
|
Abbildung 5.9-5: FA-Diagramm zu Projekte |
|
NF?: Alle obigen Relationen sind in der höchsten Normalform (5NF). |
|
c) |
|
Das Datenmodell in textlicher Notation |
|
Funktionsspezifikation (#(Funktion, BezProj, PersNr), FunktionsSpez) |
|
Personal (#PersNr, Name) |
|
Projekte (#BezProj, ProjBudget, ProjDauer) |
|
Projektmitarbeit (#(PersNr, NameProj), Funktion, ProjZugeh) |
|
Das Datenmodell in grafischer Notation |
|
|
|
Abbildung 5.9-6: Datenmodell Projektmitarbeit |
|
5.10 Von 1NF zu BCNF |
|
5.10.1 Aufgabe |
|
a) Zeichnen Sie das FA-Diagramm der folgenden Relation, bei der es um Projektmitarbeit geht.
|
|
Projektmitarbeit (#(AngNr, ProjNr, Beginn), Ende, NameAng, BezProjekt) |
|
Erläuterungen zu den Attributen: |
|
AngNr: Identifizierende Nummer für die Angestellten |
|
NameAng: Name Angestellte/r |
|
ProjNr: Identifizierende Nummer für die Projekte |
|
BezProjekt: Bezeichnung Projekte |
|
Beginn: Beginn der Mitarbeit im Projekt |
|
Ende: Ende der Mitarbeit im Projekt |
|
b) In welcher NF ist diese Relation? Begründen Sie Ihr Ergebnis.
|
|
c) Bringen Sie die Relation in die BCNF. Geben Sie die neuen Relationen als FA-Diagramme an.
|
|
5.10.2 Lösung |
|
a) |
|
FA-Diagramm: |
|
|
|
Abbildung 5.10-1: FA-Diagramm zu Projektmitarbeit_1NF |
|
Die 1NF wird aufgrund der Semantik erstmal angenommen. Mehrfacheinträge ergäben hier auch aufgabentechnisch keinen Sinn. |
|
b) |
|
Die 1NF ist ja gegeben (siehe oben). Die funktionalen Abhängigkeiten AngNr => NameAng und ProjNr => BezProj verstoßen gegen die 2NF. Also bleibt es bei der 1NF. |
|
c) |
|
Für die BCNF müssen alle Determinanten zu Schlüsseln werden und die entstehenden Relationen entsprechend der Semantik verknüpft werden. Dabei entstehen: |
|
Angestellte_BCNF (#AngNr, AngName) |
|
Projekte_BCNF (#ProjNr, BezProjekt) |
|
Projektmitarbeit_BCNF (#(AngNr, ProjNr, Beginn), Ende)) |
|
|
|
Abbildung 5.10-2: FA-Diagramme zu Projektmitarbeit in BCNF |
|
Tatsächlich sind diese Relationen bereits in der höchsten Normalform (5NF), da keine Verstöße gegen die 4NF und 5NF vorliegen. |
5NF |
6 Relationale Theorie II |
|
|
|
6.1 Redundanz 2NF, 3NF |
|
6.1.1 Aufgabe |
|
a) Erläutern Sie, warum bei einem Verstoß gegen die 2NF Redundanz in den Daten entsteht. |
|
b) Erläutern Sie, warum bei einem Verstoß gegen die 3NF Redundanz in den Daten entsteht. |
|
6.1.2 Lösung |
|
a) |
|
Bei einem Verstoß gegen die 2NF liegt eine funktionale Abhängigkeit zwischen einem Schlüsselattribut (Teil des Schlüssels!) und einem NSA vor. Da ein Schlüsselattribut typischerweise auch gleiche Attributsausprägungen hat, kommen beim funktional abhängigen NSA auch gleiche Ausprägungen mehrfach vor, was zu Redundanz führt. |
|
b) |
|
Bei einem Verstoß gegen die 3NF liegt eine funktionale Abhängigkeit zwischen 2 Nichtschlüsselattributen vor: NSA1 => NSA2. Da dann die Determinante (NSA1) dieselbe Attributsausprägung mehrfach haben kann, wird auch beim "Zielattribut" (dem anderen Nichtschlüsselattribut: NSA2) die entsprechende Attributsausprägung mehrfach vorkommen. |
|
6.2 2NF, nicht 3NF |
|
6.2.1 Aufgabe |
|
Erstellen Sie mit inhaltlich aussagekräftigen Attributen eine Relation (als FA-Diagramm), die in 2NF ist und nicht in 3NF. Erläutern Sie die Relation. |
|
6.2.2 Lösungsbeispiel |
|
Die folgende Relation erfüllt die 2NF, aber nicht die 3NF. Die funktionale Abhängigkeit KundenNr => KundenName verhindert die 3NF. Durch sie entsteht eine sog. transitive Abhängigkeit AuftragsNr => KundenNr => Kundenname, die auch als Kennzeichen für die Nichtexistenz der 3NF genommen werden kann. |
|
|
|
Abbildung 5.12-1: FA-Diagramm zu Aufträgen und Kunden |
|
6.3 FAD, Rechnungen |
|
6.3.1 Aufgabe |
|
Gegeben ist die folgende Relation Rechnungen als FA-Diagramm: |
|
|
|
Abbildung 5.13-1: FA-Diagramm Rechnungen |
|
RNr: Rechnungsnummer; PosNr: Positionsnummer; RechnDatum: Rechnungsdatum; ArtikelBez: Artikelbezeichnung |
|
a) Geben Sie die textliche Notation dieser Relation an.
|
|
b) In welcher NF ist diese Relation? Erläutern Sie alle erkennbaren Verstöße gegen Normalformen.
|
|
c) Normalisieren Sie bis zur höchsten Normalform. Geben Sie die textlichen Notationen der Relationen an. Vergeben Sie geeignete Relationenbezeichnungen.
|
|
6.3.2 Lösung |
|
a) |
|
Rechnungen (#(RNr, PosNr), RechnDatum, KundenNr, KundenTel, ArtNr, ArtikelBez, ArtikelPreis) |
|
b) |
|
Sie ist nicht in 3NF, wegen der funktionalen Abhängigkeiten zwischen Nichtschlüsselattributen: |
|
ArtikelNr => ArtikelBez |
|
ArtikelBez => ArtNr |
|
ArtikelNr => ArtikelPreis |
|
KundenNr => KundenTel |
|
Die Artikelbezeichnung wird auch als eindeutig angenommen. Sie ist auch nicht in 2NF, weil funktionale Abhängigkeiten zwischen Schlüsselattributen und Nichtschlüsselattributen bestehen: |
|
RNr => RechnDatum |
|
RNr => KundenNr |
|
RNr => KundenTel |
|
Sie ist also in 1NF. |
|
c) |
|
Die Zerlegung ergibt: |
|
Rechnungsköpfe (#RNr, RechnDatum, KundenNr) |
|
Der Fremdschlüssel Rechnungsköpfe.KundenNr verknüpft mit Kunden. |
|
Rechnungspositionen (#(RNr, PosNr), ArtikelNr)) |
|
Der Fremdschlüssel Rechnungspositionen.RNr verknüpft mit Rechnungsköpfe. Rechnungspositionen.ArtikelNr verknüpft mit Artikel. |
|
Kunden (#KundenNr, KundenTel) |
|
Artikel (#ArtikelNr, #ArtikelBez, Artikelpreis) |
|
Zwei "konkurrierende" Schlüssel kann es schon mal geben. ArtikelBez ist allerdings nur Schlüssel, wenn die Artikelbezeichnung tatsächlich identifizierend ist. |
|
6.4 BCNF - Definition |
|
6.4.1 Aufgabe |
|
Die Definition der BCNF ist sehr elegant und umfasst auch die der unteren Normalformen (bis auf die 1NF). Beschreiben Sie, warum das so ist, warum also, wenn die BCNF erfüllt ist, auch die 3NF und die 2NF erfüllt sind. |
|
6.4.2 Lösung |
|
Die BCNF ist erfüllt, falls alle Determinanten auch Schlüssel sind. Falls dies erfüllt ist, können keine Schlüsselattribute (Schlüsselbestandteile) Determinanten sein. Damit ist die 2NF erfüllt. Es ist dann auch nicht möglich, dass ein Nichtschlüsselattribut Determinante ist, denn es ist ja kein Schlüssel. Damit ist die 3NF auch erfüllt. |
|
6.5 FAD |
|
6.5.1 Aufgaben |
|
a) Zeichnen Sie das FA-Diagramm der folgenden Relation, die den Besuch von Lehrveranstaltungen beschreibt:
|
|
VB (#(MatrikelNr, LVNr, DozNr, Semester), NameStud, E-MailStud, BezLV, StudGang, DozName, Fakultät) |
|
Erläuterung der Abkürzungen und Attribute: |
|
VB: Vorlesungsbesuch |
|
LV: Lehrveranstaltung |
|
LVNr: Nummer der Lehrveranstaltung |
|
DozNr: Nummer des Dozenten |
|
DozName: Name des Dozenten |
|
Fakultät: Fakultät, zu der der Dozent gehört |
|
Semester, in dem der Studierende die LV besuchte z.B. SS2023 |
|
BezLV: Bezeichnung der LV, z.B. Datenbanksysteme 1 |
|
b) In welcher NF ist diese Relation? Begründen Sie Ihr Ergebnis. Erläutern Sie, wo hier Redundanz entsteht.
|
|
c) Bringen Sie die Relationen in die BCNF. Geben Sie die neuen Relationen in textlicher Form und als FA-Diagramme an. Vergeben Sie geeignete Relationenbezeichnungen.
|
|
6.5.2 Lösung |
|
a) |
|
Hier das FA-Diagramm. Falls es eine funktionale Abhängigkeit des Studiengangs von der Matrikelnummer gibt, |
|
MatrikelNr => StudGang, |
|
müsste diese noch ergänzt werden. |
|
|
|
Abbildung 5.15-1: FA-Diagramm Vorlesungsbesuch - unnormalisiert |
|
b) |
|
Alle funktionalen Abhängigkeiten von Schlüsselattributen zu Nichtschlüsselattributen stellen Verstöße gegen die 2NF dar. Die Relation ist also in 1NF. |
|
Bei jeder dieser funktionalen Abhängigkeiten entsteht Redundanz, weil Schlüsselteile gleiche Ausprägungen haben, was zu gleichen Ausprägungen bei dem funktional abhängigen Attribut führt. Z.B. bei DozNr => DozName. Die Dozentennummer kommt als Ausprägung eines Schlüsselattributs mehrfach vor. Entsprechend wird mehrfach der Dozentenname erfasst. |
|
c) |
|
Die Normalisierung besteht darin, alle Determinanten zu Schlüsseln neuer Relationen zu machen. Die neuen Relationen enthalten dann jeweils die vom Schlüssel funktional abhängigen Attribute: |
|
Studierende (#MatrikelNr, NameStud, E-MailStud) |
|
Lehrveranstaltungen (#LVNr, StudGang, BezLV) |
|
Dozenten (#DozNr, DozName, Fakultät) |
|
Lehrveranstaltungsbesuch (#(MatrikelNr, LVNr, DozNr, Semester)) |
|
Der Fremdschlüssel Lehrveranstaltungsbesuch.MatrikelNr verknüpft mit Studierende. |
|
Der Fremdschlüssel Lehrveranstaltungsbesuch.LVNr verknüpft mit Lehrveranstaltungen. |
|
Der Fremdschlüssel Lehrveranstaltungsbesuch.DozNr verknüpft mit Dozenten. |
|
Die Relationen sind alle in BCNF. |
|
Hier die FA-Diagramme: |
|
|
|
Abbildung 5.15-2: FA-Diagramme zu Vorlesungsbesuch - normalisiert |
|
6.6 BCNF |
|
Im Rahmen eines Datenbankentwurfs wurden zum Aspekt Projektmitarbeit folgende Attribute und funktionalen Abhängigkeiten gefunden: |
|
- PersNr (Personalnummer)
- AngName (Angestelltenname)
- Projektbezeichnung (ProjBez)
- Funktion (der Person im jeweiligen Projekt)
- Beginn (der Zugehörigkeit zum Projekt)
|
|
Die Namen sind, da es sich um ein kleines Unternehmen handelt, eindeutig. Die funktionalen Abhängigkeiten sind wie folgt: |
|
- PersNr => AngName
- AngName => PersNr
- (PersNr, ProjBez) => Funktion
- (PersNr, ProjBez) => Beginn
- (AngName, ProjBez) => Funktion
- (AngName, ProjBez) => Beginn
|
|
6.6.1 Aufgaben |
|
a) Erstellen Sie die Relation als FA-Diagramm.
|
|
b) Wo liegt hier Redundanz vor?
|
|
c) Ist diese Relation in BCNF?
|
|
d) Ist diese Relation in 3NF?
|
|
e) Ist diese Relation in 2NF?
|
|
f) Bringen Sie die Relation in 5NF und stellen sie das Ergebnis textlich sowie in FA-Diagrammen dar.
|
|
Wo nötig, begründen Sie Ihre Antwort. |
|
6.6.2 Lösung |
|
a) |
|
Es gibt zwei sich überlappende Schlüssel: (PersNr, ProjBez) und (AngName, ProjBez). Von ihnen sind jeweils Funktion und Beginn funktional abhängig. Damit ergibt sich das FA-Diagramm der Relation wie folgt: |
|
|
|
Abbildung 5.16-1: FA-Diagramm der Relation Projektmitarbeit. |
|
b) |
|
Die Redundanz entsteht durch die funktionalen Abhängigkeiten zwischen den Schlüsselattributen PersNr und AngName. Beide haben in dieser Relation Mehrfacheinträge (weil typischerweise in einem Projekt mehrere Personen mitarbeiten) wodurch mehrfach erfasst wird, dass z.B. die Person Müller die Personalnummer 12345 hat. |
|
c) |
|
Die BCNF ist erfüllt, falls alle Determinanten auch Schlüssel sind. Hier sind aber AngName und PersNr als Schlüsselteile Determinanten. Somit ist die BCNF nicht erfüllt. |
|
d) |
|
Sie ist in 3NF, da kein Nichtschlüsselattribut von einem anderen Nichtschlüsselattribut funktional abhängig ist. |
|
e) |
|
Da höhere Normalformen die niedrigeren umfassen, ist sie wegen d) auch in 2NF. Direkt auf die Definition bezugnehmend: Sie ist in 2NF, da kein Nichtschlüsselattribut(!) von einem Teil des Schlüssels funktional abhängig ist. Die funktionale Abhängigkeit zwischen Schlüsselattributen wird bei der 2NF nicht betrachtet. |
|
f) |
|
Für das Erreichen der BCNF muss der überlappende Schlüssel beseitigt werden. Hier wird (AngName, ProjBez) rausgenommen. Damit der Zusammenhang zwischen PersNr und AngName nicht verloren geht (Kein Informationsverlust durch Normalisierung!) wird dafür eine eigene Relation eingerichtet. Somit ergibt sich: |
Kein Informationsverlust |
Personal (#PersNr, #AngName) |
|
Projektmitarbeit (#(PersNr, ProjBez), Funktion, Beginn) |
|
Projektmitarbeit.PersNr wird zum Fremdschlüssel bzgl. Personal. |
|
|
|
Abbildung 5.16-2: FA-Diagramme der Relation Projektmitarbeit_5NF |
|
Da keine Verstöße gegen die 4NF und 5NF vorliegen ist die 5NF erreicht. |
|
6.7 Nicht 3NF |
|
6.7.1 Aufgabe |
|
Die folgende Relation ist nicht in 3NF. |
|
Abteilungen (#BezAbt, PersNrAbtLeiter, AnzahlMitarb, Standort, NameAbtLeiter) |
|
BezAbt: Bezeichnung der Abteilung, AbtLeiter: Abteilungsleiter, Standort: Ort, an dem die Abteilung angesiedelt ist. |
|
a) Geben Sie alle funktionalen Abhängigkeiten zwischen den Attributen von Abteilungen an.
|
|
b) Erläutern Sie an diesem Beispiel, wie und warum bei Nichterreichung der 3NF Redundanz entsteht, wenn Daten abgespeichert werden.
|
|
c) Erstellen sie ein FA-Diagramm zu dieser Relation (genau zu dieser!).
|
|
6.7.2 Lösung |
|
a) |
|
Folgende funktionalen Abhängigkeiten liegen vor: |
|
BezAbt => PersNrAbtLeiter
|
|
BezAbt => AnzahlMitarb
|
|
BezAbt => Standort
|
|
BezAbt => Name-AbtLeiter
|
|
PersNrAbtLeiter => NameAbtLeiter
|
|
b) |
|
Die 3NF wird durch die letzte funktionale Abhängigkeit verhindert. Hier wird für jede Abteilung der Zusammenhang zwischen der Personalnummer und dem Namen der Abteilungsleiter erfasst. Wenn also mehrere Abteilungen durch dieselbe Abteilungsleiterin geführt werden, wird der Zusammenhang zwischen PersNr und Name mehrfach erfasst. Auch wenn dies in diesem Beispiel nicht zu großer Redundanz führen dürfte, verbietet die 3NF eine solche funktionale Abhängigkeit zwischen Nichtschlüsselattributen. |
|
c) |
|
Das FA-Diagramm ergibt sich wie folgt: |
|
|
|
Abbildung 5.17-1: FA-Diagramm der Relation Abteilungen |
|
6.8 FA-Diagramm 1 |
|
6.8.1 Aufgaben |
|
In einem Workshop mit dem Ziel des Datenbankdesigns hat sich als erster Entwurf für die Modellierung von Projektmitarbeit die folgende Relation ergeben. |
|
Projektmitarbeit (PersonalNr, ProjektNr, Funktion, AngName, AngVorname, ProjektBez, ProjektDauer, BeginnFunktion, EndeFunktion) |
|
Erläuterung der Attribute/Semantik: |
|
Funktion : Funktion, die von der Person in einem bestimmten Projekt wahrgenommen wird. Eine Person kann in verschiedenen Projekten unterschiedliche oder auch dieselbe Funktion wahrnehmen sowie in einem Projekt mehrere Funktionen übernehmen. |
|
Beispiel : Person 1007 ist Controller im Projekt BPR, LeiterEntwicklung und Softwarearchitekt im Projekt ERP2.0 und im Projekt CRM2.0 wiederum Controller. |
|
BeginnFunktion: Monat, in dem die Person die Funktion übernahm. EndeFunktion: Monat, in dem die Person die Funktion abgab. AngName: Name des Angestellten. AngVorname: Vorname des Angestellten. ProjektBez: Bezeichnung des Projekts. ProjektDauer: Dauer des Projekts. |
|
a) Legen Sie den Schlüssel fest. Erstellen Sie dann für diese Relation ein FA-Diagramm.
|
|
b) An welchen Stellen entsteht in dieser Relation Redundanz?
|
|
c) In welcher Normalform ist diese Relation?
|
|
6.8.2 Lösung |
|
a) |
|
Als Schlüssel kann hier kein einzelnes Attribut dienen, weil keines für die Tupel identifizierenden Charakter hat. Es muss also eine Attributskombination sein. Beginnen können wir mit der PersonalNr. Ergänzen wir diese um die ProjektNr, wird die Projektmitarbeit modelliert, was nach der Anforderungsbeschreibung zielführend ist. Die Attributskombination (PersonalNr, ProjektNr) reicht aber nicht als Determinante für alle Attribute. Nicht für die Funktion, nicht für deren Beginn und Ende. Da nach der Beschreibung eine Person in unterschiedlichen Projekten verschiedene zeitliche Phasen haben kann, muss die Funktion auch in den Schlüssel. Von diesem Schlüssel mit drei Attributen sind dann auch BeginnFunktion und EndeFunktion funktional abhängig. |
Mit Semantik zum Schlüssel |
Damit entsteht die folgende Relation: |
|
Projektmitarbeit (#(PersonalNr, ProjektNr, Funktion), AngName, AngVorname, ProjektBez, ProjektDauer, BeginnFunktion, EndeFunktion) |
|
Das FA-Diagramm : |
|
|
|
Abbildung 5.18-1: FA-Diagramm Projektmitarbeit |
|
b) |
|
Die funktionalen Abhängigkeiten zwischen Nichtschlüsselattributen und Schlüsselattributen (Teilen des Schlüssels) sind immer Ursache von Redundanz. Das Schlüsselattribut hat ja üblicherweise mehrere gleiche Ausprägungen. Für jede dieser identischen Ausprägungen wird dann auch die Ausprägung des funktional abhängigen Nichtschlüsselattributs wiederholt gespeichert. Für folgende funktionalen Abhängigkeiten gilt dies hier: |
|
ProjektNr => ProjektBez
|
|
ProjektNr => ProjDauer
|
|
PersNr => AngName
|
|
PersNr => AngVorname
|
|
c) |
|
Die funktionalen Abhängigkeiten von Schlüsselattributen zu Nichtschlüsselattributen verhindern die 2NF. Damit ist die Relation in 1NF. |
|
6.9 FA-Diagramm 2 |
|
6.9.1 Aufgaben |
|
a) Erstellen Sie für die folgende Relation (so wie sie ist, mit der üblichen Semantik; eine Person kann mehrere Adressen haben) ein FA-Diagramm.
|
|
Angestellte (#(PersNr, AdrNr), Name, VName, AbtBez, AbtLeiter, PLZ, Ort, Straße) |
|
AdrNr: Adressnummer, AbtNr: Abteilungsnummer, AbtLeiter: Abteilungsleiter |
|
b) Normalisieren Sie die Relation bis zur 5NF. Geben Sie dafür die textlichen Notationen der Relationen an und beschreiben Sie bei jedem notwendigen Schritt die dabei beseitigten Redundanzen.
|
|
6.9.2 Lösung |
|
a) |
|
Die Aufgabenbeschreibung führt aus, dass es mehrere Adressen je Person geben kann. Dies bedeutet, dass die 1NF nicht erfüllt ist. Dieser Tatbestand ist in FA-Diagrammen nicht ausdrückbar. Für FA-Diagramme muss mindestens die 1NF erfüllt sein. Diese ist hier mit folgender Zerlegung realisiert: |
Kein FAD ohne 1NF |
Angestellte (#(PersNr, AdressNr), Name, Vname, AbtBez, AbtLeiter) |
|
Adressen (#AdrNr, PLZ, Ort, Straße) |
|
Die FA-Diagramme: |
|
|
|
Abbildung 5.19-1: FA-Diagramme Angestellte, Adressen |
|
b) |
|
In Angestellte liegen zahlreiche funktionale Abhängigkeiten zwischen Schlüsselattributen (Teilen des Schlüssels) und Nichtschlüsselattributen vor. Diese verhindern die 2NF und sind Ursache von Redundanz. Das Schlüsselattribut hat ja üblicherweise mehrere gleiche Ausprägungen. Für jede dieser identischen Ausprägungen wird dann auch die Ausprägung des funktional abhängigen Nichtschlüsselattributs wiederholt gespeichert. Für folgende funktionalen Abhängigkeiten gilt dies hier: |
Auf zur 2NF |
PersNr => AbtBezZ
|
|
PersNr => AbtLeiter
|
|
PersNr => Name
|
|
PersNr => Vorname
|
|
Die Herbeiführung der 2NF führt zu folgenden Relationen: |
|
Angestellte_2NF (#PersNr, Name, VName, AbtBez, AbtLeiter) |
|
PersAdr (#(PersNr, AdrNr) |
|
Relation Adressen ist bereits in 5NF: |
|
Adressen_5NF (#AdrNr, PLZ, Ort, Straße) |
|
Die 3NF in Angestellte wird durch die funktionale Abhängigkeit zwischen den zwei Nichtschlüsselattributen AbtBez und AbtLeiter verhindert: |
Auf zur 3NF |
AbtBez => AbtLeiter
|
|
Da AbtBez Nichtschlüsselattribut ist, gibt es identische Ausprägungen. Für jede dieser Ausprägungen wird der jeweilige Abteilungsleiter erfasst. Die Lösung besteht wieder in einer Zerlegung: |
|
Angestellte (#PersNr, Name, VName, AbtBez) |
|
Abteilungen (#AbtBez, AbtLeiter) |
|
Diese Relationen sind alle in 3NF. Da auch gilt, dass alle Determinanten Schlüssel sind, liegt die BCNF vor. Leicht zu erkennen ist, dass die Hindernisse für die 4NF und 5NF nicht vorliegen. Damit liegen hier insgesamt folgende Relationen vor: |
|
Abteilungen_5NF (#AbtBez, AbtLeiter) |
|
Adressen_5NF (#AdrNr, PLZ, Ort, Straße) |
|
Angestellte_5NF (#PersNr, Name, VName, AbtBez) |
|
PersAdr_5NF (#(PersNr, AdrNr)) |
|
6.10 "Attributshaufen" |
|
6.10.1 Gegenstand |
|
Gegenstand der folgenden Aufgabe sind folgende Attribute aus einem Anwendungsbereich Auftragsabwicklung: |
|
AuftragsNr, PositionsNr, ProduktNr, ProduktBez, Menge, AuftragsDatum, KundenNr, KundenName |
|
Beginnen Sie ihre Arbeit mit einer Universalrelation, die alle Attribute enthält. |
Universalrelation |
6.10.2 Aufgabe |
|
a) Bringen Sie Ordnung in diesen "Attributshaufen". Stellen Sie dazu in der Universalrelation alle funktionalen Abhängigkeiten fest.
|
|
b) Legen Sie die Relationen fest, mit Schlüsseln und Fremdschlüsseln. Falls Relationen noch nicht in 5NF sind, normalisieren sie weiter, bis diese erreicht ist.
|
|
6.10.3 Lösung |
|
a) |
|
Eine sinnvolle Vorgehensweise ist, alle funktionalen Abhängigkeiten in der Universalrelation festzustellen. Dies kann auch grafisch dargestellt werden. Die Universalrelation wird Aufträge genannt und stellt sich in der ersten Fassung so dar: |
|
Aufträge (AuftragsNr, PositionsNr, ProduktNr, ProduktBez, Menge, AuftragsDatum, KundenNr, KundenName) |
|
Zuerst wird der Schlüssel geklärt. Gibt es ein Attribut oder eine Attributskombination, von der alle anderen funktional abhängig sind? Nach längerem Reflektieren und mit Kenntnis der kaufmännischen "Tiefensemantik" ergibt sich, dass AuftrNr und PositionsNr zusammen diese Aufgabe erfüllen. Jede Kombination aus Ausprägungen dieser beiden Attribute ist eindeutig, wodurch diese zur Determinante für alle anderen und damit zum Schlüssel wird. Es ergibt sich: |
Schlüsselklärung |
Aufträge (#(AuftragsNr, PositionsNr), ProduktNr, ProduktBez, Menge, AuftragsDatum, KundenNr, KundenName) |
|
Das leichte Unbehagen, dass dabei (vielleicht / hoffentlich) aufkommt, ist berechtigt, denn der Schlüssel ist für einige Attribute "überausgestattet", zum Beispiel im Fall der KundenNr. Hier würde die AuftragsNr alleine als Determinante genügen. Es liegt also eine einfache funktionale Abhängigkeit vor (vgl [Staud 2021, S. 121]). |
Überausstattung |
Ohne überflüssige Attribute sind ProduktNr, ProduktBez und Menge vom Schlüssel abhängig. Diese vollen funktionalen Abhängigkeiten (vgl [Staud 2021, S. 121f]) sind in der folgenden Abbildung als Pfeillinien eingezeichnet: |
Im Einzelnen |
|
|
Abbildung 5.20-1: Die ersten funktionalen Abhängigkeiten im "Attributshaufen" zu Aufträgen |
|
Welche weiteren funktionalen Abhängigkeiten gibt es? Wiederum durch Reflektieren der Semantik finden wir: |
|
ProduktNr => ProduktBez |
|
Da hier die Produktbezeichnung eindeutig sein soll gilt auch: |
|
ProduktBez => ProduktNr |
|
Die funktionale Abhängigkeit zwischen Kundennummer und -name gilt nur in eine Richtung |
|
KundenNr => KundenName) |
|
Damit verändert sich die Abbildung: |
|
|
|
Abbildung 5.20-2: Weitere funktionalen Abhängigkeiten "im Attributshaufen" zu Aufträgen |
|
Das Ergebnis ist noch nicht zufriedenstellend. Auch ohne inhaltlich nachzudenken, fällt auf, dass AuftragsDatum noch nicht eingebunden ist. Das ist nicht möglich, denn es gilt: zumindest lose Kopplung ist im Datenmodell nötig. Die Überprüfung der Semantik führt zu dem Ergebnis, dass AuftragsDatum von der AuftragsNr abhängt. Weitere Reflektion der Semantik führt zur Erkenntnis, dass auch KundenNr und KundenName von der AuftragsNr abhängen. Somit ergeben sich folgende weiteren funktionalen Abhängigkeiten: |
Lose Kopplung |
AuftragsNr => AuftragsDatum |
|
AuftragsNr => KundenNr |
|
AuftragsNr => KundenName |
|
Damit ergibt sich die folgende wiederum ergänzte Abbildung. |
|
|
|
Abbildung 5.20-3: Die letzten funktionalen Abhängigkeiten im "Attributshaufen" zu Aufträgen |
|
b) |
|
Obiges macht die Relationenstruktur deutlich. Da kann gleich die BCNF umgesetzt werden. Wir fügen die Attribute zusammen, für die dann gilt, dass jede Determinante auch Schlüssel ist. Dazu nehmen wir jeden Schlüssel als Ausgangspunkt für eine Relation und ergänzen ihn um die Attribute, die von ihm funktional abhängig sind. Die Relationenbezeichnungen wählen wir inhaltlich passend: |
|
Produkte (#ProduktNr, #ProduktBez) |
|
Kunden (#KundenNr, KundenName) |
|
Auftragsköpfe (#AuftragsNr, AuftragsDatum, KundenNr) |
|
KundenName lassen wir oben weg, da dieser schon in Kunden erfasst ist und er hier zu einer transitiven Abhängigkeit führen würde. |
|
Auftragspositionen (#(AuftragsNr, PositionsNr), ProduktNr, Menge) |
|
ProduktBez lassen wir weg, da die Produktbezeichnungen schon in Produkte erfasst ist und sie hier zu einer transitiven Abhängigkeit führen würde. |
|
Hier fehlt noch etwas wichtiges, was bei jedem Datenmodell am Schluss gründlich bedacht werden muss: die relationalen Verknüpfungen und die dafür nötigen Fremdschlüssel. Denn es gilt: |
Verknüpfung |
Durch Zerlegungen von Relationen darf keine Information verloren gehen, die relationalen Verknüpfungen durch Schlüssel und Fremdschlüssel haben dies zu leisten. |
|
Hier gilt: |
|
- Auftragsköpfe.KundenNr ist Fremdschlüssel bzgl. Kunden.
- Auftragspositionen.AuftragsNr ist Fremdschlüssel bzgl. Auftragsköpfe.
- Auftragspositionen.ProduktNr ist Fremdschlüssel bzgl. Produkte.
|
|
Wir ergänzen diese und erhalten dann folgende Relationen: |
|
Produkte (#ProduktNr, #ProduktBez) |
|
Kunden (#KundenNr, KundenName) |
|
Auftragsköpfe (#AuftragsNr, AuftragsDatum, KundenNr) |
|
Auftragspositionen (#(AuftragsNr, PositionsNr), ProduktNr, Menge) |
|
Alle Relationen sind in der höchsten, der 5NF. |
|
7 Relationale Theorie III |
|
|
|
7.1 Anomalien |
|
7.1.1 Aufgabe |
|
Zeigen Sie am Beispiel einer Relation, die nicht in 2NF ist, die Aktualisierungs-Anomalie (Update-Anomalie), Einfüge-Anomalie (Insert-Anomalie) und Lösche-Anomalie (Delete-Anomalie) auf und erläutern Sie, welche Probleme diese bereiten. |
|
7.1.2 Lösungsbeispiel |
|
Folgende Relation zur Projektmitarbeit ist nicht in 2NF: |
|
ProjektMitarbeit (#(PersNr, ProjektBez), Name, Vorname, ProjektBudget) |
|
Der Grund sind folgende funktionalen Abhängigkeiten von einem Teil des Schlüssels: |
|
PersNr => Name
|
|
PersNr => Vorname
|
|
Die Anomalien entstehen, weil Name und Vorname nur von einem Teil des Schlüssels abhängig sind, von PersNr. Dies führt dazu, dass PersNr gleiche Ausprägungen aufweist (für jede Projektmitarbeit einer Person) und dass deshalb die Namen und Vornamen mehrfach erfasst werden. |
|
Die Aktualisierungs-Anomalie beschreibt die Notwendigkeit, Änderungen an mehreren Stellen vorzunehmen. Im Beispiel: Wenn Herr Müller bei der Heirat den Namen seiner Frau annimmt und er in mehreren Projekten mitarbeitet, müssen mehrere Aktualisierungen vorgenommen werden. |
|
Die Einfüge-Anomalie beschreibt das Problem, dass ein Eintrag bzgl. eines Schlüsselattributs nicht möglich ist, weil zum anderen Schlüsselattribut kein Wert vorliegt. Im Beispiel: Eine Person kann nicht erfasst werden, wenn sie nicht in einem Projekt mitarbeitet. |
|
Die Lösche-Anomalie beschreibt, dass beim Löschen eines Tupels Information gelöscht wird, die nicht gelöscht werden sollte. Im Beispiel: Verlässt die letzte Person das Projekt, geht auch die Information zum Projekt verloren. |
|
7.2 Normalformen |
|
7.2.1 Gegenstand |
|
Relation Aufträge_1NF |
|
Diese Relation hält Informationen zu Aufträgen fest. Die AuftrNr identifiziert den Auftrag, die PosNr die einzelnen Positionen eines Auftrags. Jede Position bezieht sich auf ein Produkt, das durch ProdBez(eichnung) benannt und zusätzlich durch die ProdNr identifiziert wird. Menge gibt an, wieviele Produkte in der Position aufgeführt sind. Das Attribut KuNr identifiziert den Kunden, auf den sich der Auftrag bezieht. Die Kundennamen (KuName) sind nicht eindeutig. |
|
Aufträge_1NF |
|
AuftrNr |
PosNr |
ProdNr |
ProdBez |
Menge |
Auftr- Datum |
KuNr |
KuName |
0001 |
1 |
9901 |
Laser Dr xyz |
1 |
30.06.23 |
1700 |
Müller |
0001 |
2 |
9910 |
Toner xyz |
3 |
30.06.23 |
1700 |
Müller |
0001 |
3 |
9905 |
Papier abc |
5.000 |
30.06.23 |
1700 |
Müller |
0010 |
1 |
9905 |
Papier abc |
30.000 |
01.07.22 |
1201 |
Sammer |
0010 |
2 |
9910 |
Toner xyz |
1 |
01.07.22 |
1201 |
Sammer |
0011 |
1 |
9901 |
Laser Dr xyz |
1 |
02.07.23 |
1600 |
Stanzl KG |
0011 |
2 |
9911 |
Tintenpatr x |
20 |
02.07.23 |
1600 |
Stanzl KG |
0011 |
3 |
9905 |
Papier abc |
5.000 |
02.07.23 |
1600 |
Stanzl KG |
0011 |
4 |
9906 |
InkJet-Dru y |
2 |
02.07.23 |
1600 |
Stanzl KG |
0012 |
1 |
9998 |
z-Bildschirm |
1 |
04.07.24 |
1900 |
Max OHG |
... |
|
|
|
|
|
|
|
| |
Schlüssel: #(AuftrNr, PosNr) |
|
Schlüssel der Relation. Es ist unschwer zu erkennen, dass die beiden Attribute AuftrNr und PosNr den Schlüssel der Relation darstellen, weil mit den Ausprägungen dieser Attribute jedes Tupel (jede Zeile) eindeutig identifiziert werden kann. |
|
7.2.2 Aufgabe |
|
Welche funktionalen Abhängigkeiten stellen in Aufträge_1NF Verstöße gegen welche Normalformen dar? |
|
7.2.3 Lösung |
|
AuftrNr => AuftrDatum stellt einen Verstoß gegen die 2NF dar. |
|
AuftrNr => KuNr stellt einen Verstoß gegen die 2NF dar. |
|
KuNr => KuName stellt einen Verstoß gegen die 3NF dar. |
|
ProdNr => ProdBez stellt einen Verstoß gegen die 3NF dar. Ebenso ProdBez => ProdNr. |
|
7.3 Anomalien 1 |
|
7.3.1 Gegenstand |
|
Relation Aufträge_1NF |
|
Diese Relation hält Informationen zu Aufträgen fest. Die AuftrNr identifiziert den Auftrag, die PosNr die einzelnen Positionen eines Auftrags. Jede Position bezieht sich auf ein Produkt, das durch ProdBez(eichnung) benannt und zusätzlich durch die ProdNr identifiziert wird. Menge gibt an, wieviele Produkte in der Position aufgeführt sind. Das Attribut KuNr identifiziert den Kunden, auf den sich der Auftrag bezieht. Die Kundennamen (KuName) sind nicht eindeutig. |
|
Aufträge_1NF |
|
AuftrNr |
PosNr |
ProdNr |
ProdBez |
Menge |
Auftr- Datum |
KuNr |
KuName |
0001 |
1 |
9901 |
Laser Dr xyz |
1 |
30.06.23 |
1700 |
Müller |
0001 |
2 |
9910 |
Toner xyz |
3 |
30.06.23 |
1700 |
Müller |
0001 |
3 |
9905 |
Papier abc |
5.000 |
30.06.23 |
1700 |
Müller |
0010 |
1 |
9905 |
Papier abc |
30.000 |
01.07.22 |
1201 |
Sammer |
0010 |
2 |
9910 |
Toner xyz |
1 |
01.07.22 |
1201 |
Sammer |
0011 |
1 |
9901 |
Laser Dr xyz |
1 |
02.07.23 |
1600 |
Stanzl KG |
0011 |
2 |
9911 |
Tintenpatr x |
20 |
02.07.23 |
1600 |
Stanzl KG |
0011 |
3 |
9905 |
Papier abc |
5.000 |
02.07.23 |
1600 |
Stanzl KG |
0011 |
4 |
9906 |
InkJet-Dru y |
2 |
02.07.23 |
1600 |
Stanzl KG |
0012 |
1 |
9998 |
z-Bildschirm |
1 |
04.07.24 |
1900 |
Max OHG |
... |
|
|
|
|
|
|
|
| |
Schlüssel: #(AuftrNr, PosNr) |
|
Die beiden Attribute AuftrNr und PosNr stellen den Schlüssel der Relation dar, weil mit den Ausprägungen dieser Attribute jedes Tupel (jede Zeile) eindeutig identifiziert werden kann. |
|
7.3.2 Aufgabe |
|
a) Wie sind Aktualisierungsanomalien definiert?
|
|
b) Welche Aktualisierungsanomalien liegen in Aufträge_1NF vor und welches Problem erzeugen sie?
|
|
7.3.3 Lösung |
|
a) |
|
Eine Aktualisierungsanomalie liegt vor, wenn die Änderung einer Information dazu führt, dass in mehreren Tupeln die Ausprägung des entsprechenden Attributs verändert werden muss. Dies ist grundsätzlich unerwünscht. Es hat bei der Aktualisierung des Werts die Konsequenz, dass die Zahl der zu ändernden Tupel im Vornehinein unbekannt ist. Unter Umständen muss die gesamte Relation durchsucht werden. |
|
b) |
|
Werden die Produktbezeichnungen geändert, indem z.B. der Produktnummer 9901 statt "Laser Dr(ucker) xyz" jetzt "HP Laser Dru Serie 5" zugeordnet wird, dann muss die Produktbezeichnung nicht nur in einem Tupel, sondern in mehreren geändert werden. |
|
Gleiches gilt für das AuftrDatum. Müssen wir dieses aus irgendwelchen Gründen ändern, muss dies mehrfach geschehen. Auch KuName weist diese Eigenschaft auf. Ändert sich der Kundenname des Kunden 1700 von "Müller" nach "Müller und Paul", sind bei der Aktualisierung wieder mehrfache Änderungen nötig. |
|
7.4 Anomalien 2 |
|
7.4.1 Gegenstand |
|
Relation Aufträge_1NF |
|
Diese Relation hält Informationen zu Aufträgen fest. Die AuftrNr identifiziert den Auftrag, die PosNr die einzelnen Positionen eines Auftrags. Jede Position bezieht sich auf ein Produkt, das durch ProdBez(eichnung) benannt und zusätzlich durch die ProdNr identifiziert wird. Menge gibt an, wieviele Produkte in der Position aufgeführt sind. Das Attribut KuNr identifiziert den Kunden, auf den sich der Auftrag bezieht. Die Kundennamen (KuName) sind nicht eindeutig. |
|
Aufträge_1NF |
|
AuftrNr |
PosNr |
ProdNr |
ProdBez |
Menge |
Auftr- Datum |
KuNr |
KuName |
0001 |
1 |
9901 |
Laser Dr xyz |
1 |
30.06.23 |
1700 |
Müller |
0001 |
2 |
9910 |
Toner xyz |
3 |
30.06.23 |
1700 |
Müller |
0001 |
3 |
9905 |
Papier abc |
5.000 |
30.06.23 |
1700 |
Müller |
0010 |
1 |
9905 |
Papier abc |
30.000 |
01.07.22 |
1201 |
Sammer |
0010 |
2 |
9910 |
Toner xyz |
1 |
01.07.22 |
1201 |
Sammer |
0011 |
1 |
9901 |
Laser Dr xyz |
1 |
02.07.23 |
1600 |
Stanzl KG |
0011 |
2 |
9911 |
Tintenpatr x |
20 |
02.07.23 |
1600 |
Stanzl KG |
0011 |
3 |
9905 |
Papier abc |
5.000 |
02.07.23 |
1600 |
Stanzl KG |
0011 |
4 |
9906 |
InkJet-Dru y |
2 |
02.07.23 |
1600 |
Stanzl KG |
0012 |
1 |
9998 |
z-Bildschirm |
1 |
04.07.24 |
1900 |
Max OHG |
... |
|
|
|
|
|
|
|
| |
Schlüssel: #(AuftrNr, PosNr) |
|
Die beiden Attribute AuftrNr und PosNr stellen den Schlüssel der Relation dar, weil mit den Ausprägungen dieser Attribute jedes Tupel (jede Zeile) eindeutig identifiziert werden kann. |
|
7.4.2 Aufgabe |
|
a) Wie sind Einfüge-Anomalien definiert?
|
|
b) Welche Einfüge-Anomalien liegen in Aufträge_1NF vor und welches Problem erzeugen sie?
|
|
7.4.3 Lösung |
|
a) |
|
Eine Einfüge-Anamolie liegt vor, wenn ein neues (noch) unvollständiges Tupel nicht in die Relation eingetragen werden kann, weil unter den fehlenden Attributen ein Schlüssel- oder Fremdschlüsselattribut ist. Täte man das doch, wäre es ein (unsinniger) Verstoß gegen die Forderung nach Objektintegrität. |
Objektintegrität |
b) |
|
Nehmen wir neue Produkte mit ProdNr und ProdBez auf, so können wir sie in der Relation erst erfassen, wenn wir zumindest einen Auftrag mit Positionsnummer haben, in dem sie erscheinen. Sonst wäre eine Erfassung nicht möglich, da ja kein Schlüsselattribut vorliegen würde. Ähnliches gilt für das AuftragsDatum. Es kann erst erfasst werden, wenn die erste Position des Auftrags bekannt ist. Auch bei den Informationen zu Kunden gäbe es Probleme. Ein neuer Kunde könnte mit KuNr und KuName nur aufgenommen werden, falls auch ein Auftrag vorliegt. |
|
7.5 Anomalien 3 |
|
7.5.1 Gegenstand |
|
Relation Aufträge_1NF |
|
Diese Relation hält Informationen zu Aufträgen fest. Die AuftrNr identifiziert den Auftrag, die PosNr die einzelnen Positionen eines Auftrags. Jede Position bezieht sich auf ein Produkt, das durch ProdBez(eichnung) benannt und zusätzlich durch die ProdNr identifiziert wird. Menge gibt an, wieviele Produkte in der Position aufgeführt sind. Das Attribut KuNr identifiziert den Kunden, auf den sich der Auftrag bezieht. Die Kundennamen (KuName) sind nicht eindeutig. |
|
Aufträge_1NF |
|
AuftrNr |
PosNr |
ProdNr |
ProdBez |
Menge |
Auftr- Datum |
KuNr |
KuName |
0001 |
1 |
9901 |
Laser Dr xyz |
1 |
30.06.23 |
1700 |
Müller |
0001 |
2 |
9910 |
Toner xyz |
3 |
30.06.23 |
1700 |
Müller |
0001 |
3 |
9905 |
Papier abc |
5.000 |
30.06.23 |
1700 |
Müller |
0010 |
1 |
9905 |
Papier abc |
30.000 |
01.07.22 |
1201 |
Sammer |
0010 |
2 |
9910 |
Toner xyz |
1 |
01.07.22 |
1201 |
Sammer |
0011 |
1 |
9901 |
Laser Dr xyz |
1 |
02.07.23 |
1600 |
Stanzl KG |
0011 |
2 |
9911 |
Tintenpatr x |
20 |
02.07.23 |
1600 |
Stanzl KG |
0011 |
3 |
9905 |
Papier abc |
5.000 |
02.07.23 |
1600 |
Stanzl KG |
0011 |
4 |
9906 |
InkJet-Dru y |
2 |
02.07.23 |
1600 |
Stanzl KG |
0012 |
1 |
9998 |
z-Bildschirm |
1 |
04.07.24 |
1900 |
Max OHG |
... |
|
|
|
|
|
|
|
| |
Schlüssel: #(AuftrNr, PosNr) |
|
Die beiden Attribute AuftrNr und PosNr stellen den Schlüssel der Relation dar, weil mit den Ausprägungen dieser Attribute jedes Tupel (jede Zeile) eindeutig identifiziert werden kann.. |
|
7.5.2 Aufgabe |
|
a) Wie sind Lösche-Anomalien definiert?
|
|
b) Welche Lösche-Anomalien liegen in Aufträge_1NF vor und welches Problem erzeugen sie?
|
|
7.5.3 Lösung |
|
a) |
|
Eine Lösche-Anomalie liegt vor, wenn beim Löschen einer Information, die nur einen Teil des Tupels betrifft, auch die übrigen Attributswerte verloren gehen. |
|
b) |
|
Löscht man den Auftrag 0012, der nur eine Position hat, geht auch die Information verloren, dass z-Bildschirme die Produktnummer 9998 haben. |
|
7.6 GenSpez |
|
Zum Muster Generalisierung / Spezialisierung vgl. [Staud 2021, Abschnitt 14.1]. |
|
7.6.1 Gegenstand |
|
Folgende Attribute liegen in einem Anwendungsbereich zu den Angestellten eines Unternehmens vor: Personalnummer (PersNr), Name (Name), Vorname (VName), Abteilungsbezeichnung (AbtBez), Einstellungsdatum (EinstDat). Für die Entwickler/innen sollen noch die Attribute Entwicklungsumgebung (EntwU), Programmiersprache (ProgSpr) (jeweils nur eine, die meist genutzte) erfasst werden. Für das leitende Management außerdem noch: Entgeltmodell (Entgelt) und Bereich, den sie verantworten (Bereich). |
|
7.6.2 Aufgaben |
|
a) Welches Muster findet sich in dieser Attributskonstellation?
|
|
b) Erstellen Sie für diesen Anwendungsbereich ein relationales Modellfragment. Erläutern Sie den Aufbau.
|
|
7.6.3 Lösung |
|
a) |
|
Diese Situation wird in der semantischen Modellierung und in der objektorientierten Theorie als Generalisierung / Spezialisierung (Gen/Spez) bezeichnet (vgl. [Staud 2021, Abschnitt 14.1]). |
|
b) |
|
In der relationalen Theorie kann dies wie folgt umgesetzt werden: alle gemeinsamen Attribute werden in eine eigene Relation getan, das ist die sog. Generalisierung. Die Attribute der Angestellten mit spezifischen Attributen kommen in eigene Relationen, die Spezialisierungen. Hier also: |
|
Angestellte (#PersNr, Name, VName, AbtBez, EinstDat) |
|
Entwickler (#PersNr, EntwU, ProgSpr) |
|
TopManagement (#PersNr, Entgelt, Bereich) |
|
In die Spezialisierungen wird der Schlüssel der Generalisierung übernommen. Obwohl diese keine Fremdschlüssel sind, werden sie in manchen Texten auch unterstrichen. Zu beachten ist: die Wertebereiche von Entwickler.PersNr und TopManagement.PersNr sind eine Teilmenge von Angestellte.PersNr. |
|
7.7 Einzel / Typ |
|
Zum Muster Einzel/Typ vgl. [Staud 2021, Abschnitt 14.2]. |
|
7.7.1 Gegenstand |
|
In einem Zoo sollen die größeren Tiere in einer Datenbank erfasst werden. Dabei haben sich folgende zu erfassenden Attribute ergeben: |
|
- Tiernummer (TNr, eindeutig), Namen (Name), Geburtstag (GebTag), Geschlecht.
|
|
- Gattung, zu der das Tier gehört (BezGatt). Anzahl der Tiere jeder Gattung (Anzahl). Bezeichnung der Tiergattung in einer umfassenden Tierklassifikation (Klassifikation)
|
|
- Nummer des Gebäudes (GebNr), in dem das Tier untergebracht ist.
|
|
7.7.2 Aufgaben |
|
a) Welches Muster findet sich in dieser Attributskonstellation?
|
|
b) Erstellen Sie für diesen Anwendungsbereich ein relationales Modell.
|
|
7.7.3 Lösung |
|
a) |
|
Hier muss erkannt werden, dass zum einen einzelne Tiere beschrieben werden, zum anderen Tiergattungen. Eine solche Struktur wird hier als Muster Einzel/Typ bezeichnet. |
|
b) |
|
Eine solche Attributskonstellation wird wie folgt modelliert. Für die Einzelobjekte (hier: einzelne Tiere) wird eine Relation angelegt. Schlüssel ist TNr: |
|
Tiere-Einzeln (#TNr, Name, GebTag, Geschlecht, GebNr. |
|
Für die Objekttypen (hier: Tiergattungen) wird ebenfalls eine Relation angelegt. Schlüssel ist hier BezGatt: |
|
Tiere-Gattung (#BezGatt, Anzahl, Klassifikation) |
|
Bleibt noch die Verknüpfung der beiden Relationen. Für Tiergattungen und Einzeltiere gilt eine 1:n-Beziehung. Deshalb wird die Gattungsbezeichnung in Tiere-Einzeln aufgenommen, so dass insgesamt folgendes Datenmodell entsteht: |
Verknüpfung |
Tiere-Einzeln (#TNr, Name, BezGatt, GebTag, Geschlecht, GebNr |
|
Tiere-Gattung (#BezGatt, Anzahl, Klassifikation) |
|
Diese beiden Relationen beschreiben den Sachverhalt absolut redundanzfrei. |
|
7.8 Aggregation |
|
Das Muster hier ist Enthaltensein ohne Existenzabhängigkeit. |
|
7.8.1 Gegenstand |
|
Hier geht es um die Modellierung von Attributen zu PCs und ihren Komponenten. Für die PC wird eine Inventarnummer (InvPC), die Bezeichnung des Prozessors (Proz) und die Größe des Arbeitsspeichers (ArbSp) erfasst. Für die Komponenten die Bezeichnung (BezKomp), eine Inventarnummer (InvNrKomp) und die Beschreibung der Funktion. |
|
Bei den Komponenten handelt es sich hier um solche (Grafikkarten, Speichermedien, . . .), die eine eigene Existenz aufweisen, die also z.B. auch mal in einen anderen PC wechseln. |
|
7.8.2 Aufgabe |
|
a) Welches Muster findet sich in dieser Attributskonstellation? Begründen Sie.
|
|
b) Erstellen Sie für diesen Anwendungsbereich ein relationales Modell.
|
|
7.8.3 Lösung |
|
a) |
|
Hier liegt eine enge Beziehung zwischen PC und Komponenten vor, ein Enthaltensein. Wegen der Forderung nach Eigenständigkeit handelt es sich um eine Aggregation und nicht um eine Komposition (vgl. dazu die nächste Aufgabe). |
|
b) |
|
Dieses Muster erfordert in relationalen Datenbanken folgende Modellierung. Eine Relation PC für die Personal Computer. Schlüssel ist InvPC, davon funktional abhängig sind ArbSp und Proz: |
|
PC (#InvPC, ArbSp, Proz) |
|
Eine Relation für die Komponenten. Schlüssel ist hier InvNrKomp, davon funktional abhängig sind Bez und Funktion: |
|
Komponenten (#InvNrKomp, Bez, Funktion) |
|
Die Aggregation wird durch eine eigene Relation PCKomp ausgedrückt. Wegen der 1:n-Beziehung (eine Komponente ist in genau einem PC) erhält PCKomp den Schlüssel InvNrKomp. Mit dem hinzugefügten Fremdschlüssel InvNrPC wird das Enthaltensein ausgedrückt. Das ist die relationale Lösung für das Muster Aggregation: |
Aggregation |
PCKomp (#InvNrKomp, InvNrPC) |
|
Damit kann eine Komponente datenbanktechnisch problemlos von einem zum anderen PC "wandern" und sie kann in Komponenten auch "existieren", falls sie nicht mehr in einem PC eingebaut ist. |
|
7.9 Komposition |
|
Hier geht es um das Muster Enthaltensein mit Existenzabhängigkeit. |
|
7.9.1 Gegenstand |
|
Es geht um Rechnungen. Erfasst werden sollen die Rechnungsnummer (ReNr), das Rechnungsdatum (ReDat), die Kundennummer (KuNr) und die Zahlungsvereinbarung (ZV). Außerdem für die Rechnungspositionen eine Positionsnummer (PosNr), die Artikelnummer (ArtNr), die Anzahl der Artikel auf der Position und der Einzelpreis (Preis) |
|
7.9.2 Aufgabe |
|
a) Welches Muster findet sich in dieser Attributskonstellation? Begründen Sie.
|
|
b) Erstellen Sie für diesen Anwendungsbereich ein relationales Modell.
|
|
7.9.3 Lösung |
|
a) |
|
Zu unterscheiden sind Rechnungsköpfe (ReKöpfe) und Rechnungspositionen (RePos). Zwischen diesen liegt eine sehr enge Beziehung vor, ein Enthaltensein mit Existenzabhängigkeit. Diese wird als Komposition bezeichnet. Vgl. dazu [Staud 2021, Abschnitt 14.4]. |
|
b) |
|
Es sind die zwei Relationen ReKöpfe (Rechnungsköpfe) und RePos (Rechnungspositionen) anzulegen. ReKöpfe hat den Schlüssel ReNr, von dem die Attribute ReDat, KuNr und ZV funktional abhängig sind: |
|
ReKöpfe (#ReNr, ReDat, KuNr, ZV) |
|
RePos erhält die Attribute PosNr, ArtNr, Anzahl und Preis. Wegen der 1:n-Beziehung zwischen ReKöpfe und RePos erhält RePos einen zusammengesetzten Schlüssel: (ReNr, PosNr). Außerdem wird RePos.ReNr zum Fremdschlüssel: |
|
RePos (#(ReNr, PosNr), ArtNr, Anzahl, Preis) |
|
Dieser Schlüssel ist die relationale Antwort auf das Muster Komposition. Damit gehören Rechnungsköpfe und -positionen untrennbar zusammen und die Rechnungspositionen werden gelöscht (sollten gelöscht werden!), wenn der zugehörige Rechnungskopf gelöscht wird. |
|
7.10 UN zu 1NF |
|
7.10.1 Aufgabe |
|
Wie bringt man eine unnormalisierte Relation mit Mehrfacheinträgen (Wiederholungsgruppen) in einem Attribut in die 1NF und weiter. Erläutern Sie, auch mit Hilfe eines aussagekräftigen Beispiels. |
|
7.10.2 Lösung |
|
Gibt es nur Mehrfacheinträge in einem Attribut, kann man zur Tupelvermehrung greifen (vgl. [Staud 2021, Abschnitt 7.3]). Dabei wird für jeden der Mehrfacheinträge ein eigenes Tupel angelegt. Der Schlüssel der neuen Relation besteht aus dem alten Schlüssel und dem Attribut mit Mehrfachausprägungen. |
Tupelvermehrung |
Die Relation Personal_UN beschreibt Angestellte eines Softwarehauses mit ihrem Namen, der Personalnummer und einer Kurzbezeichnung der Programmiersprachen, die sie beherrschen. |
Beispiel Personal_UN |
Personal_UN |
|
#PersNr |
Name |
ProgSpr |
123 |
Maier |
C, COBOL, PHP, C++ |
234 |
Primus |
C++, Java, C |
345 |
Wanderer |
C#, Java |
456 |
König |
PHP |
... |
|
|
| |
Die Tupelvermehrung führt zu folgender Lösung: |
|
Personal_1NF |
|
PersNr |
ProgSpr |
Name |
123 |
C |
Maier |
123 |
COBOL |
Maier |
123 |
PHP |
Maier |
123 |
C++ |
Maier |
234 |
C++ |
Primus |
234 |
Java |
Primus |
234 |
C |
Primus |
345 |
C# |
Wanderer |
345 |
Java |
Wanderer |
456 |
PHP |
König |
... |
|
|
| |
Der Schlüssel der normalisierten Relation ist #(PersNr, ProgSpr). Die Relation ist in 1NF, aber nicht in 2NF, und weist dementsprechend Redundanzen auf. |
|
|
|
|
|
|
|
8 Entity Relationship Modellierung |
|
Eine Einführung in die Entity Relationship - Modellierung findet sich hier: |
|
http://www.staud.info/erm2/er_t_1.htm |
|
Die Entity Relationship Modellierung ist ein Teilgebiet der sog. Semantischen Datenmodellierung. Diese hatte sich ab den 1970-er Jahren zum Ziel gesetzt, mehr Semantik als damals mit der relationalen Modellierung möglich war, in die Datenmodelle zu bringen. Heute wird sie vor allem in einführenden Lehrverantaltungen zur Datenbanktheorie und -praxis als Ausgangspunkt der Datenmodellierung verwendet. |
Semantische Datenmodellierung |
Im Bereich der Entity Relationship - Modellierung sind die Begriffe Entität (für Objekte) und Entitätstypen (für die Zusammenfassung gleich strukturierter Entitäten) üblich. Vgl. |
Entitäten und Entitätstypen |
http://www.staud.info/erm2/er_t_1.htm |
|
für eine Einführung. |
|
Das Ergebnis der ER-Modellierung ist ein grafisches Modell. Vgl. obige Quelle und die nachfolgenden Beispiele. |
|
Folgende Aufgaben sind zu lösen, um ein korrektes ER-Modell (ERM) zu erstellen: |
|
- Entitätstypen: Entitätstypen identifizieren. Dafür ist zuerst ein Schlüssel aus einem Attribut oder aus mehreren festzulegen. Die Vorgaben dafür sind so, dass sich alle Attribute auf alle Entitäten des Entitätstyps beziehen müssen. Damit werden semantisch bedingte Leereinträge in der späteren Datenbank vermieden. Mehrfacheinträge sind zugelassen, werden aber grafisch gekennzeichnet.
- Beziehungstypen: Beziehungstypen einschließlich der Min-/Max-Angaben festlegen. Wegweisend ist hier die Regel: Alle Entitätstypen sind (zumindest lose) miteinander verknüpft. Attribute von Beziehungstypen klären.
- Generalisierung / Spezialisierung: Auftretende Muster Gen/Spez klären und mit dem dafür vorgesehenen Methodenelement anlegen.
- Aggregation: Auftretende Muster Aggregation klären und mit dem dafür vorgesehenen Methodenelement anlegen.
- Komposition: Auftretende Muster Komposition klären und mit dem dafür vorgesehenen Methodenelement anlegen.
- Zeitaspekte: Zeitliche Aspekte klären und modellieren, auch die in der Anforderung vergessenen.
|
|
|
|
8.1 Mitglieder / Adressen |
|
In dieser einführenden Aufgabe geht es um die einfache Zuordnung von Attributen zu Entitätstypen. |
|
8.1.1 Anforderungen |
|
Im Rahmen des Datenbankdesigns für einen Sportverein wurden für die Mitglieder folgende Anforderungen formuliert: |
|
Die Mitglieder des Vereins werden durch Name, Vorname (VName), Telefon (Tel), Geburtstag (GebTag), Alter, eine Mitgliedsnummer (MiNr) und ihre Adressen (PLZ, Ort, Straße) festgehalten. Erfasst wird außerdem der Tag des Eintritts (Eintritt) in den Verein. |
|
Erstellen Sie dazu ein ER-Modell. Nutzen Sie auch die Möglichkeit, Attribute zu gruppieren. |
|
8.1.2 Lösung |
|
Sofort erkennbar als Entitätstyp sind die Vereinsmitglieder. Schlüssel ist die Mitgliedsnummer (MiNr). Die problemlosen beschreibenden Attribute sind VName, Name, Tel, GebTag und Alter. Problemlos sind sie deshalb, weil es genau eine Ausprägung je Mitglied gibt. Name und VName werden gruppiert zu Name. Dies dient nur der Übersichtlichkeit, es hat keine inhaltliche oder methodische Bedeutung. |
|
Das Attribut Alter ist ein sog. abgeleitetes Attribut, das mit gestrichelter Linie dargestellt werden muss. Seine Einträge werden vom Datenbanksystem berechnet. Hier aus dem abgespeicherten Geburtsdatum (GebTag) und dem vom System gelieferten Tagesdatum. Mit dem Datenbanksystem wird auch der Aktualisierungszeitpunkt festgelegt. |
abgeleitetes Attribut |
|
|
Abbildung 6.1-1: Entitätstyp Mitglieder |
|
Etwas mehr Aufwand verlangen die Adressangaben. Da es mehrere Adressen pro Mitglied gibt, erhalten sie einen eigenen Entitätstyp Adressen. Diese erhalten die Attribute PLZ, Ort und Straße. Ergänzen muss man einen Schlüssel AdrId. Auch hier wurden die Attribute der Übersichtlichkeit wegen gruppiert. |
|
|
|
Abbildung 6.1-2: Entitätstyp Adressen |
|
Bleibt noch die Verknüpfung der beiden Entitätstypen. Hier wird ein Beziehungstyp M_Adr eingerichtet. Auf Nachfrage erfahren wir, dass nicht nur ein Mitglied mehrere Adressen haben kann, sondern unter einer Adresse auch mehrer Mitglieder. Somit egibt sich die Kardinalität n:m. Da Mitglieder nur erfasst werden, wenn mindestens eine Adresse vorliegt und Adressen nur, wenn mindestens ein Mitglied dort wohnt, ergeben sich die Min-/Max-Angaben 1,n : 1,m. |
|
|
|
Abbildung 6.1-3: ER-Modell Mitglieder / Adressen |
|
8.2 Mitgliedergruppen |
|
In dieser einführenden Aufgabe geht es um die Bewältigung von Ähnlichkeit mittels Generalisierung / Spezialisierung. |
|
8.2.1 Ausgangspunkt |
|
Ausgangspunkt dieser Aufgabe ist das ER-Modell der vorigen Aufgabe, aus darstellungstechnischen Gründen grafisch etwas umgestellt. |
|
|
|
Abbildung 6.2-1: ER-Modell Mitglieder / Adressen |
|
8.2.2 Anforderungen |
|
Obiges Datenmodell soll ergänzt werden. Zusätzlich soll für die Vereinsmitglieder erfasst werden: |
|
(1) Bei ausgetretenen Mitgliedern der Grund (Grund) und Tag des Austritts (Austritt).
|
|
(2) Für verstorbene Mitgliedern der Todestag (Todestag). Außerdem wird festgehalten, wieviele Jahre das Mitglied im Verein war (AnzJahre).
|
|
(3) Die telefonischen Verbindungen (Telefon). Dies können durchaus mehrere sein. Z.B. neben dem Festnetzanschluss noch ein mobiler Anschluss.
|
|
Ergänzen Sie das ER-Modell aus obiger Aufgabe. |
|
8.2.3 Lösungsschritte |
|
Anforderung (1) |
|
Da die Daten der ausgetretenen Mitglieder erhalten bleiben sollen, wie wir auf Nachfrage erfahren, kann für die ausgetretenen Mitglieder ein neuer Entitätstyp als Spezialisierung von Mitglieder eingerichtet werden. Er erhält die Attribute Austritt und Grund. |
|
Anforderung (2) |
|
Auch für die verstorbenen Mitglieder gilt, dass ihre Daten erhalten bleiben sollen. Deshalb kann ebenfalls ein neuer Entitätstyp als Spezialisierung von Mitglieder eingerichtet werden. Er erhält die Attribute Todestag und AnzJahre. AnzJahre ist ein abgeleitetes Attribut, dessen Einträge aus dem Eintrittsdatum und dem Todestag vom Datenbanksystem berechnet werden. |
|
Anforderung (3) |
|
Auf den ersten Blick wird man mehrere telefonische Verbindungen einfach als mehrwertiges Attribut beim Entitätstyp Mitglieder einfügen. Dies wäre aber nicht sinnvoll, da für verstorbene und ausgetretene Mitglieder die Telefonverbindungen nicht erfasst werden sollen. Da bleibt nur, eine weitere Spezialisierung für nicht ausgetretene und nicht verstorbene Mitglieder anzulegen. Sie soll Aktive Mitglieder genannt werden und erhält Telefon als Attribut. |
|
Dabei wird deutlich, dass auch das Attribut Alter hierher gehört, denn dessen Bestimmung macht nur Sinn für aktive Mitglieder. |
|
8.2.4 Lösung |
|
Damit ergibt sich das ER-Modell der folgenden Abbildung. |
|
|
|
Abbildung 6.2-2: ER-Modell Mitglieder / Adressen |
|
8.3 Sportverein |
|
Aus eigenen Erfahrungen und aus vielen Diskussionen mit Teilnehmern von Schulungen und Studierenden in Vorlesungen weiß ich, dass reale Sportvereine eine viel reichere und tiefere Semantik haben. Ich bitte daher vor allem alle Sportvereinsmitglieder um Verzeihung für die Einfachheit des Beispiels, denke aber, dass es trotzdem seine Aufgabe erfüllen kann. |
|
Bei dieser Aufgabe werden die Lösungsschritte sehr viel ausführlicher erläutert als in den übrigen Aufgaben, um eventuelle Wissenslücken beim Leser aufzufüllen bzw. um Wissen zu vertiefen. |
|
8.3.1 Anforderungen |
|
Ein Sportverein beschließt, seine Aktivitäten (Mitgliederverwaltung, Sportveranstaltungen, usw. ) in Zukunft computergestützt abzuwickeln. Dazu soll im ersten Schritt eine einfache Datenbank aufgebaut werden, für die folgende Spezifikationen festgehalten werden: |
|
- Der Sportverein ist in Abteilungen gegliedert. Eine für Handball, eine für Fußball. Weitere können in der Zukunft dazukommen.
- Jede Abteilung hat einen Leiter.
- Jede Abteilung hat mehrere Mannschaften.
- Von jeder Mannschaft werden die Spieler, der Kapitän und die Liga festgehalten, in der sie spielt (Bundesliga, usw.)
- Jede Mannschaft hat einen Trainer.
- Die Begegnungen von Mannschaften des Vereins mit Datum, gegnerischer Mannschaft und Ergebnis sollen festgehalten werden.
- Die Mitglieder des Vereins werden durch Name, Vorname, PLZ, Ort, Straße, Telefon, Geburtstag, Alter und eine Mitgliedsnummer festgehalten.
|
|
Außerdem wird für die Mitglieder erfasst, ob es sich um ein passives oder ein aktives Mitglied handelt. Für jedes aktive Mitglied wird dann noch festgehalten, welche Sportart es in welcher Leistungsstufe betreibt; für die passiven Mitglieder wird erfasst, für welche ehrenamtliche Tätigkeit sie zur Verfügung stehen. |
|
8.3.2 Erste Schritte |
|
Wie sehen nun die konkreten Modellierungsschritte aus? Sinnvoll ist es, zuerst die Entitätstypen zu suchen. Dies ist dann allerdings keine endgültige Festlegung, sondern eine, die im Verlauf der Modellierung auch wieder korrigiert werden kann. |
|
Beginnen wir also mit Entitäten und Entitätstypen. Diese erkennt man im modellierungstechnischen Sinne daran, dass es sich erstens um Objekte im allgemeinen Sinn handelt und dass zweitens diese Objekte durch Attribute beschrieben werden. Zweiteres ist von zentraler Bedeutung, denn sonst kann es sich auch um ein Attribut handeln, wie auch dieses Beispiel gleich zeigen wird. |
Entitäten und Entitätstypen erkennen |
Natürlich etablieren auch andere nicht-konventionelle Attribute einen Entitätstyp. Z.B. Grafiken, Bilder, Videos, usw. Allerdings sind diese nur Ergänzungen der Basisbeschreibung durch Attribute, die auf jeden Fall vorhanden sein muss. |
|
Hier ist ein Entitätstyp sofort erkennbar, die Mitglieder. Die Vereinsmitglieder existieren - auch im allgemeinen Sinn - und sie werden durch Attribute beschrieben: |
|
|
|
Abbildung 6.3-1: Entitätstyp Mitglieder |
|
Offen bleibt nun noch die Frage, wie die Eigenschaft, aktives oder passives Vereinsmitglied zu sein, erfasst wird. Ginge es nur um diese Eigenschaft, würde einfach ein Attribut "aktiv/passiv" mit diesen zwei Eigenschaften an den Entitätstyp Mitglieder angefügt. Nun ist es hier aber so, dass für die aktiven und passiven Mitglieder jeweils unterschiedliche Attribute festgehalten werden sollen. Deshalb müssen diese Teilgruppen der Mitglieder getrennt erfasst und - da sie ja als Mitglieder auch gemeinsame Attribute haben - in der im ersten Teil vorgestellten Notation als Generalisierung / Spezialisierung angelegt werden: |
aktiv / passiv |
|
|
Abbildung 6.3-2: Aktive und passive Mitglieder in einer Generalisierung / Spezialisierung |
|
Soweit der erste Entitätstyp Mitglieder. Hinzugenommen wurde ein Attribut Status mit den Ausprägungen passiv und aktiv, mit dem es später beim Umgang mit der Datenbank möglich ist, die Spezialisierungen gezielt anzusprechen. Dies verlangt die Theorie nicht, empfiehlt sich aber aus Gründen der Pragmatik. |
Differenzierung |
Das Attribut mit den Punkten soll oben und im folgenden die schon vorher eingeführten Attribute andeuten. |
Hinweis: |
Die aktiven Mitglieder erhalten die Attribute Sportart (derzeit nur Handball oder Fußball) und Leistungsstand. Es wird davon ausgegangen, dass ein Spieler nur eine Sportart betreibt. Das Attribut ehrenamtliche Tätigkeit der passiven Mitglieder erfasst in einer irgendwie verkodeten Form, für was das Mitglied zur Verfügung steht. Es handelt sich um ein mehrwertiges Attribut. |
|
Oftmals möchte man bei einer Spezialisierung ausdrücken, dass alle Entitäten des übergeordneten Typs an der Spezialisierung teilnehmen müssen. Dies geschieht, wie in der obigen Abbildung, durch einen Doppelstrich zwischen dem übergeordneten Typ und dem d-Kreis. Er signalisiert hier, dass alle Mitglieder entweder aktive oder passive Mitglieder sein müssen. Eine andere Mitgliedschaft gibt es somit modelltechnisch nicht. Alternativ könnten hier statt der Spezialisierung passive Mitglieder nur die ehrenamtlich tätigen Mitglieder erfasst sein. Dann müsste der Doppelstrich beseitigt werden, da es dann Mitglieder gäbe, die in keine der beiden Spezialisierungen eingehen (die passiven, die nicht ehrenamtlich tätig sind). |
Totale
Beteiligung |
Bei Beziehungen wird "totale Beteiligung" durch die Min-/Max-Angaben festgelegt. Steht als Mindestwert ein Wert größer 0 da, müssen alle Entitäten des Entitätstyps an der Verbindung teilhaben. |
|
8.3.3 Die Mannschaften |
|
Betrachten wir nun die Mannschaften. Sie tauchen mit folgenden Beschreibungen auf: |
|
- Jede Abteilung hat mehrere Mannschaften, insofern könnte "Mannschaft" ein Attribut von Abteilung sein.
- Von jeder Mannschaft werden Spieler, Kapitän, Liga, Trainer und Begegnungen festgehalten.
|
|
Letzteres macht die Mannschaften zu Entitätstypen, da sie durch weitere Attribute beschrieben werden. Die Klärung der Frage, ob sie evtl. ein Beziehungstyp sein können, wird auf eine spätere Phase des Modellierungsvorgangs verschoben. Damit ergibt sich folgender erster Entwurf: |
|
|
|
Abbildung 6.3-3: Entitätstyp Mannschaften |
|
Hinzugefügt wurde ein Attribut Name, mit der Bezeichnung der Mannschaften. Das Attribut Spieler ist mehrwertig, da jede Mannschaft mehrere Spieler hat. |
|
Auf die Aufnahme eines Attributs Begegnung wurde verzichtet, da die Begegnungen durch weitere Attribute zu einer eigenständigen Existenz kommen. |
|
8.3.4 Begegnungen |
|
In den Anforderungen wurde festgelegt, dass alle Begegnungen von Mannschaften des Vereins mit Tagesdatum, Gegner und Ergebnis festgehalten werden sollen. Damit entsteht ein entsprechender Entitätstyp. Gleichzeitig wird hier der erste Beziehungstyp deutlich, der mit M-B bezeichnet werden soll und schlicht die Tatsache beschreibt, dass die Mannschaften des Vereins an den Begegnungen teilnehmen. Da auch nur solche Begegnungen erfasst werden, handelt es sich um einen singulären Entitätstyp, der durch ein Rechteck mit Doppellinie dargestellt wird. Der zugehörige Beziehungstyp erhält ebenfalls eine solche. |
|
|
|
Abbildung 6.3-4: Singulärer Entitätstyp Begegnungen |
|
Das Attribut Beginn wurde zusätzlich aufgenommen, um mehrere Begegnungen an einem Tag, z.B. im Rahmen eines Turniers, unterscheiden zu können. Schlüssel für diesen Entitätstyp sind die Attribute Tag, Beginn und Gegner zusammen. |
|
Zu beachten ist, dass es nur um die Spiele des betrachteten Vereins geht, nicht um alle Spiele einer Liga, was die Situation verändern würde. |
|
Als Schlüssel wurde hier ein zusammengesetzter genommen, der bei der Überführung in konkretere Strukturen (Z.B. in Relationen) um den Schlüssel von Mannschaften ergänzt werden müsste. Dies ist typisch für singuläre Entitätstypen. Ihre Existenzabhängigkeit zeigt sich auch darin, dass ihr Schlüssel um den des anderen Entitätstyps ergänzt werden muss. |
Existenzabhängigkeit |
8.3.5 Abteilungen |
|
Jetzt müssen noch die Abteilungen betrachtet werden. Für sie wurde in den Anforderungen festgehalten, dass der Verein in Abteilungen gegliedert ist (Handball und Fußball), dass jede Abteilung eine/n Leiter/in und mehrere Mannschaften hat. |
|
In Konfrontation mit den schon erstellten Modellfragmenten lässt sich damit festhalten, dass Abteilungen ein Entitätstyp mit den Attributen Leiter und Sportart ist. Die Tatsache, welche Mannschaft zu welcher Abteilung gehört, wird nicht durch ein Attribut festgehalten, sondern durch einen Beziehungstyp M-A zwischen Mannschaften und Abteilungen: |
|
|
|
Abbildung 6.3-5: Mannschaften in Abteilungen |
|
8.3.6 Zusammenstellung |
|
Damit sind die wichtigsten Komponenten des zu erstellenden Datenmodells realisiert. In der folgenden Abbildung werden sie zusammengestellt. Die Min-/Max-Angaben in der Abbildung haben folgende Bedeutung: |
|
- 1,1 bei Mannschaften zu Abteilungen (M-A): Eine Mannschaft gehört zu genau einer Abteilung.
- 1,n bei Abteilungen zu Mannschaften (M-A): Eine Abteilung hat mindestens eine Mannschaft.
- 0,n bei Mannschaften zu Begegnungen (M-B): Eine Mannschaft hat an keiner (z.B., wenn sie neu aufgestellt wurde) oder an mehreren Begegnungen teilgenommen.
- 1,1 bei Begegnungen zu Mannschaften (M-B): Eine Begegnung wird nur dann als solche aufgenommen, wenn genau eine Mannschaft "unseres" Vereins teilgenommen hat. Wir schließen hier also bewusst Begegnungen zwischen zwei Mannschaften unseres Vereins aus.
|
|
|
|
Abbildung 6.3-6: Entity Relationship-Modell Sportverein - Erster Versuch |
|
Dieses Gesamtmodell ist nun aber in einem wichtigen Punkt fehlerhaft: Eine Trennung eines Datenmodells in zwei unverbundene Teile ist nicht möglich. So etwas gibt es nicht, da ein Datenmodell ja gerade dadurch ausgezeichnet ist, dass zusammengehörige Informationen über einen Weltausschnitt verwaltet werden. Sonst sind es zwei Datenmodelle mit zwei verschiedenen Datenbanken. |
Defizit: Trennung |
8.3.7 Lösung durch Verschmelzung |
|
Bei genauerer Betrachtung zeigt sich nun aber, dass natürlich die Mitglieder mit den organisatorischen Aspekten des Vereins auf vielfältige Weise verknüpft sind. Insbesondere sind dies folgende Aspekte: |
|
- Aktive Mitglieder spielen in Mannschaften
- Aktive Mitglieder können Kapitän einer Mannschaft sein
- Aktive Mitglieder trainieren die Mannschaften (wir gehen davon aus, dass die Trainer als aktive Mitglieder zum Verein gehören)
- Aktive Mitglieder leiten die Abteilungen
|
|
Alle diese Informationen wurden im obigen ersten Entwurf - herrührend von den Modellkomponenten - als Attribute von Entitätstypen definiert. Dies muss nun geändert werden. |
|
Beginnen wir mit den Spielern der Mannschaften. Diese Information sollte nicht als mehrwertiges Attribut von Mannschaften erfasst werden, sondern als Beziehungstyp zwischen Mannschaften und Aktive Mitglieder: AM-S. Damit ist nicht nur die Information der Mannschaftszugehörigkeit eindeutig erfasst, sondern es stehen auch die Adressen der Mannschaftsmitglieder zur Verfügung und die Namen der Spieler werden nur einmal erfasst, im Mitgliederverzeichnis, wo sie hingehören. |
Korrektur |
Ganz ähnlich bei der Erfassung der Trainer. Bisher als Attribut von Mannschaft erfasst, werden sie nun zu einer Beziehung zwischen Trainern und Mannschaften mit dem Beziehungstyp AM-T. |
|
Die Kapitäne der Mannschaften werden ebenfalls durch eine Beziehung zwischen Mannschaften und Aktive Mitglieder erfasst, AM-K, denn die Kapitäne sollen in unserem Datenmodell aktive Mitglieder sein. |
|
Die Leiter der Abteilungen werden dementsprechend als Beziehung zwischen Abteilungen und Aktive Mitglieder erfasst: AM-A. |
|
In der folgenden Abbildung nun das Gesamtmodell mit den besprochenen Korrekturen. Weggefallen sind die Attribute, mit denen vorher die Beziehungen festgelegt wurden. Die weiteren Min-/Max-Angaben sind ebenfalls angegeben. Sie bedeuten: |
|
- 0,1 bei Aktive Mitglieder zu Mannschaften und Beziehung AM-S: Ein aktives Mitglied spielt in maximal einer Mannschaft. Selbstverständlich wäre an der zweiten Position auch ein höherer Wert möglich, falls die Semantik es erfordert. Ebenso ein Wert größer Null an der ersten Position.
- 0,1 bei Aktive Mitglieder zu Mannschaften und Beziehung AM-T: Ein aktives Mitglied kann in maximal einer Mannschaft Trainer sein.
- 0,1 bei Aktive Mitglieder zu Mannschaften und Beziehung AM-K: Ein aktives Mitglied ist in maximal einer Mannschaft Kapitän.
- 0,1 bei Aktive Mitglieder zu Abteilungen und Beziehung AM-A: Ein aktives Mitglied leitet maximal eine Abteilung.
- 1,1 bei Mannschaften zu Aktive Mitglieder und Beziehung AM-T: Eine Mannschaft wird von genau einem aktiven Mitglied trainiert.
- 11,15 bei Mannschaften zu Aktive Mitglieder und Beziehung AM-S: Eine Mannschaft besteht aus mindestens 11 und maximal 15 Spielern (aktive Mitglieder).
- 0,1 bei Mannschaften zu Aktive Mitglieder und Beziehung AM-K: Eine Mannschaft hat maximal einen Kapitän.
|
|
Für alle diese Festlegungen gilt, dass die Semantik und deren modelltechnische Umsetzung auch eine andere sein kann. |
|
|
|
Abbildung 6.3-7: Entity Relationship-Modell Sportverein |
|
8.4 PC-Beschaffung |
|
8.4.1 Anforderungen |
|
In einem Unternehmen soll der Vorgang der PC-Beschaffung durch eine Datenbank festgehalten werden. Dafür soll ein ER-Modell erstellt werden. Folgende Festlegungen ergaben sich in den Interviews, die im Vorfeld mit den Betroffenen geführt wurden. Die Attributsnamen wurden, soweit möglich, auch gleich geklärt: |
Vgl. Abschnitt 1.4 zur Typographie |
(1) Jeder PC erhält eine Inventarnummer (InvPC). Neben dieser wird der Prozessortyp (Proz) und die Größe des Arbeitsspeichers (ArbSp) festgehalten. Für die PC der Entwickler wird festgehalten, welche Programmiersprachen (PS) installiert sind und welches die hauptsächlich verwendete Entwicklungsumgebung (EntwUmg) ist.
|
|
(2) Für jede Festplatte wird festgehalten: Bezeichnung und Größe (PlBez, Größe) sowie die Zugriffsgeschwindigkeit (Zugriff), die Seriennummer (SerNr) (diese ist eindeutig, auch über Hersteller hinweg) und der Tag, an dem die Platte in den Rechner eingebaut wurde (TagEinb).
|
|
(3) Ein PC kann mehrere Festplatten haben, eine Festplatte ist aber nur einem PC zugeordnet.
|
|
(4) Für jeden PC wird weiterhin festgehalten, wer ihn nutzt (PersNr), in welcher Abteilung er steht (AbtBez) und wer der Abteilungsleiter der Abteilung ist (AbtLeiter).
|
|
(5) Ein PC wird von genau einem Mitarbeiter genutzt. Jeder Mitarbeiter nutzt auch einen PC, es gibt einzelne Mitarbeiter, die mehrere PC nutzen.
|
|
(6) Die Nutzer werden durch ihre Personalnummer (PersNr), den Namen (Name, Vorname) und ihre Telefonnummer (Tel) erfasst. Außerdem wird festgehalten, ab welchem Datum er/sie den PC nutzt (Beginn). Gibt er/sie ihn später ab, wird auch dies festgehalten (Ende).
|
|
8.4.2 Lösungsschritte |
|
Auch hier gilt: Realweltphänomene, die durch Attribute identifiziert und durch mindestens ein Attribut beschrieben werden, sind Kandidaten für die elementaren Modellfragmente (hier: Entitätstypen). |
PC |
Der erste Punkt liefert auch gleich einen Entitätstyp. Wir nennen ihn PC und weisen ihm den Schlüssel InvPC sowie die beschreibenden Attribute Proz und ArbSp zu. Die Formulierung "Für die PC der Entwickler . . ." gibt den Hinweis auf eine Generalisierung / Spezialisierung. Wir können daher die Spezialisierung Entw-PC mit den Attributen ProgSpr (mit Mehrfacheinträgen) und EntwU(mgebung) anlegen. Die Tatsache, dass bei ProgSpr (Programmiersprachen) pro Entwickler-PC mehrere Einträge möglich sind, wird durch die Doppellinie ausgedrückt. |
|
|
|
Abbildung 6.4-1: Generalisierung / Spezialisierung mit PC und EntwPC |
|
Vgl. zur grafischen Gestaltung von ER-Modellen: www.staud.info/erm2/er_t_1.htm |
|
Der zweite Punkt signalisiert einen Entitätstyp zu Festplatten (FP). Beim Studium der Attribute erkennen wir aber, dass zum einen einzelne Festplatten beschrieben werden (Seriennummer, SerNr; Tag des Einbaus, TagEinbau), zum anderen Gerätetypen (Bezeichnung und Größe (PlBez, Größe), Zugriffsgeschwindigkeit (Zugriff)). Es liegt also das Muster Einzel/Typ vor. Entsprechend müssen zwei Entitätstypen angelegt werden: FP-Typen und FP-Einzeln. Diese werden durch einen Beziehungstyp (FP-T/E) verknüpft. Die Kardinalität (Typen => Einzeln) ist 1:n, die Min-/Max-Angaben sind 1,n bzw. 1,1 (vgl. auch Abschnitt 2.4.1). Damit ergibt sich das folgende Fragment. |
Festplatten |
|
|
Abbildung 6.4-2: Muster Einzel/Typ für Festplatten |
|
Punkt 3 klärt die Beziehung zwischen PC und Festplatten. Um diese eindeutig zu erfassen, sollte sie mit Hilfe von FP-Einzeln realisiert werden. Für den dabei entstehenden Beziehungstyp PC-F gelten (für die Richtung PC => FP-Einzeln) die Kardinalität 1:n und die Min-/Max-Angaben 1,n : 1,1. Vgl. die folgende Abbildung. Wir legen also fest, dass jede Festplatte sofort nach Beschaffung einem PC zugeordnet werden muss und dass jeder PC mindestens eine Festplatte besitzt. |
Beziehungstyp PC-F |
Punkt 4 klärt die organisatorische Zuordnung der PC. Da ist zum einen der Nutzer oder die Nutzerin, die durch die Personalnummer (PersNr) identifiziert wird. Ein Blick auf den letzten Punkt der Anforderungsbeschreibung zeigt, dass die Nutzer tatsächlich auch in der Datenbank erfasst werden, sodass der Schlüssel PersNr noch um weitere Attribute ergänzt wird. Somit kann ein Entitätstyp Nutzer mit den Attributen PersNr, Name, Vorname, Tel(efon) angelegt werden. |
Nutzer |
In Punkt 4 wird auch festgelegt, dass die Abteilung festgehalten wird, die den PC erhält. Dies könnte einfach zu einem weiteren Attribut von PC führen. Da aber für die Abteilungen auch der Abteilungsleiter festgehalten wird (AbtLeiter), muss ein eigener Entitätstyp Abteilungen angelegt werden mit den Attributen AbtBez und AbtLeiter. Die Verknüpfung mit PC erfolgt durch einen Beziehungstyp PC-A mit der Kardinalität 1:n und den Min-/Max-Angaben 0,n : 1,1 (Abteilungen => PC). Es wird hier also angenommen, dass man auch Abteilungen in der späteren Datenbank anlegen möchte, denen noch kein PC zugewiesen ist und dass jeder erfasste PC sofort einer Abteilung zugeordnet wird. |
Abteilung |
Punkt 5 klärt die Nutzung der PC durch die Mitarbeiter, also den Beziehungstyp zwischen PC und Nutzer. Er soll PC-N genannt werden. Die Min-/Max-Angaben (Nutzer=>PC) sind 1,n : 1,1. |
Nutzung |
Punkt 6 verlangt, dass Beginn und Ende der Nutzungszeit festgehalten werden. Wohin gehören diese Attribute, worauf beziehen sie sich? Sicherlich nicht auf den PC, dieser kann ja von verschiedenen Personen genutzt werden. Sicherlich auch nicht auf die Nutzer, denn diese nutzen verschiedene PC zu verschiedenen Zeiten. Sie gehören auf die Kombination PC/Nutzer, denn genau dafür sind sie jeweils eindeutig. Dies drückt der Beziehungstyp PC-N aus. Deshalb fügen wir hier die beiden Attribute dazu. |
Nutzungszeit |
Damit sind die verschiedenen Aspekte der Anforderungen modelliert und die Modellfragmente können zusammengefügt werden. |
|
8.4.3 Lösung |
|
In der Grafik werden nur die Min-/Max-Angaben ausgewiesen. Die Kardinalitäten können von diesen abgeleitet werden. |
|
|
|
Abbildung 6.4-3: Entity Relationship - Modell PC-Beschaffung |
|
Vgl. zur Gestaltung von ER-Modellen in allen Aspekten: |
|
http://www.staud.info/erm2/er_t_1.htm |
|
8.5 Fahrzeugvermietung |
|
8.5.1 Anforderungen |
|
Es geht um ein Unternehmen, das Fahrzeuge aller Art vermietet und dies durch eine Datenbank unterstützen möchte. Folgende Attribute werden für die Fahrzeuge erfasst: |
|
(1) Für alle Fahrzeuge: Tag der Anschaffung (TagAnsch), Preis, nötiger Führerschein zum Fahren des Fahrzeugs (Führerschein)
|
|
(2) Für PKW: Motorart (Diesel oder Benziner), Motorstärke (PS). Hierunter fallen Cabriolets (Dach fest oder flexibel: Dachart), Sportwagen (Beschleunigung von 0 auf 100: Beschl) und Familienautos (Zahl der Sitzplätze)
|
|
(3) Für LKW: Getriebeart (Getriebe)
|
|
(4) Für Busse: Zahl der Sitzplätze (Plätze)
|
|
(5) Für Kettenfahrzeuge: bewältigbare Steigung (Steigung)
|
|
(6) Für militärische Kettenfahrzeuge: mit oder ohne Bewaffnung (Waffejn). Hier wird außerdem festgehalten, ob es sich um Kampfpanzer (für diese wird Feuerkraft erfasst) oder um Brückenlegepanzer (für diese wird Brückenlänge erfasst) handelt.
|
|
(7) Für zivile Kettenfahrzeuge: Schiebekraft (wieviel Erde sie maximal wegschieben können)
|
|
Die Ausleihe eines jeden Fahrzeugs wird mit Beginn (Tag der Ausleihe) und Ende (Tag der Rückgabe) festgehalten. Es versteht sich, dass ein Kunde öfters ein Fahrzeug ausleihen kann und dass ein Fahrzeug im Zeitverlauf möglichst oft ausgeliehen werden soll. |
|
Nach jeder Rückgabe des Fahrzeugs durch einen Kunden wird der Fahrzeugzustand festgehalten (ZustandF). Die Ausprägungen sind tadellos, normal, beschädigt, schwer beschädigt, funktionsunfähig. Ziel ist hier, die Historie der Zustandsentwicklung festzuhalten. |
|
Von den Ausleihern werden die Adressangaben (nur eine Adresse) erhoben (Name, Vorname, PLZ, Ort, Straße, Telefon). Sie erhalten außerdem einen Status, der folgende Ausprägungen haben kann: Neukunde (0), langjähriger solider Kunde (1), nicht solider Kunde (2). |
|
8.5.2 Lösungsschritte |
|
Ein Entitätstyp ist hier gleich erkennbar: Fahrzeuge. Das Durchlesen der Anforderungen macht dann deutlich, dass es hier um Einzelfahrzeuge geht, die aber nach Fahrzeugtypen gruppiert werden und bei denen neben Attributen für alle Fahrzeuge auch spezifische Attribute für die Fahrzeugtypen vorliegen. Es liegt hier also eine Generalisierung / Spezialisierung vor. |
|
Beginnen wir mit der Generalisierung, mit den Attributen für alle Fahrzeuge. Diese werden im ersten Punkt angeführt, allerdings müssen wir einen Schlüssel ergänzen: FNr (Fahrzeugnummer). |
|
Durch die Generalisierung / Spezialisierung geraten die Bezeichnungen der Spezialisierungen auf eine Metaebene, "über" den Datenbestand. Sie stehen zwar als Relationenbezeichnungen, aber nicht im Datenbestand zur Verfügung. Dies kann Abfragen kompliziert machen, weshalb es empfehlenswert ist, in der Generalisierung die Bezeichnungen der Spezialisierungen zu erfassen. Wir ergänzen hier also Ftyp (Fahrzeugtyp). Damit ergibt sich der erste Entitätstyp. |
|
|
|
Abbildung 6.5-1: Entitätstyp Fahrzeuge |
|
Der zweite Punkt legt als Spezialisierung von Fahrzeuge einen Entitätstyp PKW mit Motorart und PS fest. Der anschließende Satz definiert dann noch Spezialisierungen der Spezialisierung PKW: Cabriolets mit Dachart, Sportwagen mit Beschl und Familienautos mit Sitzplätze. Damit haben wir an dieser Stelle der Spezialisierungshierarchie drei Ebenen. |
Spezialisierung der Spezialisierung |
|
|
Abbildung 6.5-2: Generalisierung / Spezialisierung 1 - Fahrzeuge mit PKW |
|
In Punkt 3 werden die LKW (mit Getriebe), in Punkt 4 die Busse (mit Plätze) und in Punkt 5 die Kettenfahrzeuge (mit Steigung) eingeführt. Dies sind alles Spezialisierungen von Fahrzeuge. |
|
In Punkt 6 werden die Kettenfahrzeuge weiter spezifiziert in militärische Kettenfahrzeuge (KettenfahrzeugeMilitärisch) und diese wiederum in Kampfpanzer und Brückenlegepanzer. Da in Punkt 7 noch zivile Kettenfahrzeuge spezifiziert werden, liegt ab Kettenfahrzeuge, folgende Spezialisierungshierarchie vor: |
|
Kettenfahrzeuge |
Kettenfahrzeuge Zivil |
Kettenfahrzeuge Militärisch |
Brückenlegepanzer |
Kampfpanzer |
Steigung |
Steigung |
Steigung |
Steigung |
Steigung |
|
Schiebekraft |
WaffeJN |
WaffeJN |
WaffeJN |
|
|
|
Brückenlänge |
Feuerkraft |
| |
Damit ist die Generalisierung / Spezialisierung vollständig modelliert. |
|
|
|
Abbildung 6.5-3: Generalisierung / Spezialisierung 1 - Fahrzeuge mit PKW |
|
In den nachfolgenden Absätzen wird die Ausleihe von Fahrzeugen modelliert. Die Ausleiher sind gleich als Entitätstypen erkennbar mit den Attributen Name, Vorname, PLZ, Ort, Straße, Telefon und Status. Wir ergänzen noch eine Kundennummer (KNr). |
Ausleiher und Fahrzeuge |
Für die Ausleihe legen wir einen Beziehungstyp F_A fest, denn der Beginn und das Ende der Ausleihe gehören zu der Beziehung zwischen Ausleihe und Fahrzeuge. Auch die Erfassung des Zustands nach der Rückgabe durch das Attribut ZustandF gehört hierher. Die Forderung, eine Ausleihhistorie und eine Historie der Zustandsentwicklungzu erfassen, ist durch diesen Beziehungstyp auch erfüllt. |
|
Sehen wir davon ab, das Ende des Ausleihvorgangs gleich beim Erfassen der Ausleihe festzulegen, gibt es hier, ähnlich wie in der relationalen Modellierung bei der Erfassung von Zeitabschnitten, eine Ungereimtheit. Das Ende der Ausleihe steht beim Eintrag des Ausleihvorgangs noch nicht zur Verfügung. Dieses Attribut kann also erstmal nicht beschrieben werden. Solche semantisch bedingten Leereinträge sind eigentlich nicht gewollt, hier aber aus pragmatischen Gründen akzeptiert. Die vollständig korrekte Lösung wäre die getrennte Erfassung von Beginn und Ende des Ausleihzeitraums. |
Zeitabschnitte mit Pragmatik |
Der Entitätstyp Ausleiher kann direkt der Anforderungsbeschreibung entnommen werden. Die Wertigkeiten können wie folgt festgelegt werden: 0,n bei Fahrzeuge, da wir neue Fahrzeuge auch aufnehmen wollen, wenn sie noch nicht verliehen wurden. 1,n bei Ausleiher legt fest, dass wir nur Personen aufnehmen, die auch ausgeliehen haben. |
|
Damit ergibt sich das folgende Modellfragment. |
|
|
|
Abbildung 6.5-4: Modellfragment Ausleiher - Fahrzeuge |
|
8.5.3 Lösung |
|
Jetzt bleibt nur noch, die Modellierung der Generalisierung / Spezialisierung und der Ausleihe zusammenzufügen und das Gesamtmodell ist fertig. |
|
|
|
Abbildung 6.5-5: ER-Modell der Aufgabe Fahrzeuge. |
|
Die in der Anforderungsbeschreibung angeführten zulässigen Einträge in die Attribute ZustandF und Status betreffen nicht die Datenmodellierung, sondern die nachfolgende Einrichtung der Datenbank. |
|
8.6 WebShop |
|
8.6.1 Anforderungen |
|
Für einige Aspekte eines WebShops soll eine Datenbank erstellt werden. Hier die Anforderungen. |
Zeitliche Aspekte |
(1) Wenn die Warensendung im WebShop fertig ist wird die Rechnung erstellt und der Sendung beigelegt. Damit ist das kaufmännische Konstrukt Rechnung existent. Wie üblich, wird es über Rechnungsköpfe (ReKöpfe) und Rechnungspositionen (RePos) erfasst. Die Rechnungsköpfe erhalten als identifizierendes Attribut eine Rechnungsnummer (RNr) und als beschreibende Attribute das Rechnungsdatum (RDatum), die Zahlungsart (ZahlArt) (L (per Lastschrift), U (per Überweisung)) und die Versandart (VersArt). Die Rechnung wird als PDF-Dokument mit versandt, deshalb wird dessen Identifikation (PDFId) hier ebenfalls festgehalten.
|
|
(2) Die Kunden werden durch ihre Kundennummer (KNr) und durch ihre Adressangaben (Name, Vorname (VN), PLZ, Ort, Straße) erfasst. Es versteht sich, dass ein Kunde u.U. mehrere Rechnungen beim WebShop hat.
|
|
(3) Unsere Artikel erfassen wir durch eine Artikelnummer ArtNr, eine Artikelbezeichnung ArtBez, den Preis und eine Artikelbeschreibung (ArtBeschr).
|
|
(4) Die einzelnen Rechnungspositionen einer Rechnung erhalten eine Positionsnummer (PosNr), die Bezeichnung, den Preis des Artikels, die Anzahl (Anzahl) und den Gesamtpreis der Position (PosPreis).
|
|
(5) Für alle Artikel wird auch der gültige Mehrwertsteuersatz (MWStSatz) und bei jedem Verkauf die einbehaltene Mehrwertsteuer (MWStBetrag) erfasst. Zu beachten ist, dass verschiedene Produkte des WebShops unterschiedliche Mehrwertsteuersätze haben).
|
|
(6) Für Produkte von Fremdanbietern (Firmen, die über unseren WebShop auch verkaufen) wird noch die Firmennummer (FiNr) des Fremdanbieters erfasst und seine Lieferzeit (LiefZeit).
|
|
(7) Auch die ausgesandten Mahnungen und Zahlungserinnerungen werden erfasst. Jede wird identifiziert (MahnId) und bezieht sich auf genau eine Rechnung. Es versteht sich, dass es zu einer Rechnung mehrere Mahnungen geben kann. Festgehalten wird, an welchem Tag die Mahnung (Versand) verschickt wurde und von welchem Typ sie war.
|
|
(8) Eine Rechnung kann sich in verschiedenen Zuständen befinden. Folgende sind möglich:
|
|
Zustände einer Rechnung |
|
ZustandsNr |
Bezeichnung |
100 |
neu (nach Erstellung) |
200 |
offen (nach Versand zum Kunden) |
300 |
nicht bezahlt |
310 |
nicht bezahlt (1. Zahlungserinnerung) |
320 |
nicht bezahlt (2. Zahlungserinnerung) |
330 |
nicht bezahlt (1. Mahnung) |
340 |
nicht bezahlt (2. Mahnung) |
350 |
nicht bezahlt (rechtsanwaltliche Mahnung) |
400 |
Widerspruch |
500 |
Gutschrift |
600 |
storniert |
700 |
bezahlt (Rückbuchbar) |
710 |
bezahlt |
| |
(9) Diese Zustände sollen für jede Rechnung erfasst werden. Nach der Erstellung hat sie den Zustand (ZustNr) "neu", nach Zusendung zum Kunden den Zustand "offen", nach Bezahlung den Zustand "bezahlt". Zu beachten ist, dass ALLE sich im Zeitverlauf ergebenden Zustände erfasst werden sollen, so dass die gesamte Historie einer Rechnung erfasst wird. Deshalb wird auch bei jedem neuen Zustand das Datum (DatumZ) erfasst, zu dem er eintrat.
|
|
8.6.2 Lösungsschritte |
|
Anforderung (1), (3), (4), (5) |
|
Der erste Punkt weist auf das Konstrukt Rechnung über die Entitätstypen Rechnungsköpfe (ReKöpfe) und Rechnungspositionen (RePos) hin. Einige Attribute sind direkt angegeben. ReKöpfe erhält RNr als Schlüssel und RDatum, ZahlArt, VersArt sowie PDFId als weitere beschreibenden Attribute. |
|
Die Rechnungspositionen werden in (4) beschrieben. Sie erhalten eine Positionsnummer (PosNr), die Bezeichnung und den Preis des Artikels sowie die Anzahl der Artikel auf der Position und den Gesamtpreis der Position (PosPreis). |
|
Diese Attribute verweisen auf einen weiteren Entitätstyp, Artikel, der in (3) und (5) beschrieben ist. Nach den Regeln der ER-Modellierung werden alle Attribute, die Entitäten des Entitätstyps Artikel beschreiben, diesem zugeordnet. Dies sind ArtNr (als Schlüssel), ArtBez, Preis, ArtBeschr und MWStSatz. |
|
Der Entitätstyp RePos erhält die Attribute PosNr, Anzahl, den MWStBetrag und den PosPreis. MWStBetrag und PosPreis werden gleich hier, im ER-Modell, als Attribute gekennzeichnet, die durch das Datenbanksystem berechnet werden. PosPreis als Produkt von Preis (von Artikel) und Anzahl, MWStBetrag als Produkt von PosPreis und MWStSatz (von Artikel). |
Abgeleitete (berechnete) Attribute |
Die Beziehungstypen ergeben sich wie folgt: RePos ist existenzabhängig von ReKöpfe, da es Rechnungspositionen nicht ohne zugehörigen Rechnungskopf gibt. Dies wird in der ER-Modellierung durch einen singulären Entitätstyp (weak entity type) ausgedrückt, wie in der Grafik gezeigt. Er wird RK_RP genannt. Für den Beziehungstyp zwischen Artikel und RePos sind die Kardinalitäten 1:n, die Min-/Max-Angaben 0,n : 1,1. Er wird A_RP genannt. Damit ergibt sich die folgende Abbildung. |
Beziehungstypen |
|
|
Abbildung 6.6-1: ER-Fragment zu Rechnungen / Artikel |
|
Anforderung (2) |
|
Im zweiten Punkt der Anforderungen wird auf die Kunden und deren Adressen verwiesen. Da es mehrere Adressen pro Kunde geben kann, ist eine theoriekonforme Aufteilung der Attribute wie folgt: |
|
- Entitätstyp Kunden mit KNr, Name, Vorname (VN) und ein
- Entitätstyp Adressen mit PLZ, Ort, Straße
|
|
Letzterer wird noch ergänzt um eine Adressnummer (AdrNr), die als Schlüssel dient. |
|
Die Beziehungstypen ergeben sich wie folgt: Kunden muss mit ReKöpfe verknüpft werden (Beziehungstyp RK_Ku) mit den Kardinalitäten 1:n und den Min-/Max-Angaben 1,n : 1,1. Kunden muss aber auch mit Adressen verknüpft werden (Kunden haben Adressen, Adressen gehören zu Kunden; Beziehungstyp Ku_Ad)) mit den Kardinalitäten 1:n und den Min-/Max-Angaben 1,n : 1,1. Es wird also darauf verzichtet den Fall zu erfassen, dass unter einer Adresse mehrere Kunden wohnen. |
|
Damit ergibt sich das folgende ER-Modell. |
|
|
|
Abbildung 6.6-2: ER-Fragment zu Rechnungen / Artikel / Kunden |
|
Anforderung (6) |
|
Hier werden Produkte angesprochen, die auch Artikel des WebShops sind, die aber von Fremdanbietern stammen. Da dafür Attribute vorliegen, die nicht bei den oben schon angelegten Artikeln vorliegen (FiNr, LiefZeit), diese also ergänzen, handelt es sich um eine Spezialisierung. Sie soll F-Artikel genannt werden und wird als Spezialisierung an Artikel angefügt. |
|
|
|
Abbildung 6.6-3: ER-Fragment zu Artikel / F-Artikel |
|
Anforderung (7) |
|
Punkt 7 befasst sich mit Mahnungen. Der erste Gedanke ist, die Attribute zu Mahnungen dem Entitätstyp ReKöpfe hinzuzufügen. Dies wäre aber methodisch falsch, da Mahnungen einen eigenen Entitätstyp darstellen: Sie haben einen Schlüssel (MahnId) und weitere beschreibende Attribute (Versand, Typ), die Mahnungen beschreiben und nicht Rechnungsköpfe. Außerdem gibt es auch Rechnungen ohne Mahnungen und u.U. mehrere Mahnungen pro Rechnung. |
|
Dieser Entitätstyp Mahnungen wird an das schon vorliegende ER-Modell mit Hilfe eines Beziehungstyps RK_M zwischen ReKöpfe und Mahnungen angefügt. Die Kardinalitäten sind 1:n, die Min-/Max-Angaben 0.n : 1,1. Vgl. die Abbildung unten. |
Anbindung |
Anforderung (8), (9) |
|
Der letzte Punkt bringt ein wenig die Geschäftsprozessthematik in die Aufgabe. Eine Rechnung ist ein Geschäftsobjekt und nimmt im Prozess der Zahlungsabwicklung verschiedene Zustände ein. Diese sind in den Anforderungen angeführt. In den Anforderungen wird verlangt, dass die Entwicklung der Zustände protokolliert wird. Jedesmal, wenn ein Zustand eintritt, wird das Datum mit erfasst. |
|
Dies soll über einen singulären Entitätstyp modelliert werden. Dann können die Werte in ZustNr für jede Rechnung hochgezählt werden. Außerdem verschwinden damit diese Informationen, wenn die Rechnung gelöscht wird. |
|
Ausgehend von den Rechnungsköpfen ist die Kardinalität 1:n, die Min-/Max-Angaben sind 0,n : 1,1. Die grafische Umsetzung findet sich in der Abbildung unten. |
|
8.6.3 Lösung |
|
Die folgende Abbildung fasst obige Ergebnisse zusammen. |
|
|
|
Abbildung 6.6-4: ER-Modell WebShop |
|
8.7 Zoo |
|
8.7.1 Anforderungen |
|
Für einen Zoo soll eine Datenbank rund um die vorhandenen Tiere erstellt werden. Dafür wird zuerst ein ER-Modell erstellt. |
|
Im ersten Schritt erfolgt eine Konzentration auf größere Tiere (Säugetiere, Reptilien, . . .). Allen diesen Tieren wird eine identifizierende Tiernummer (TierNr), ihr Name (Name; vom Pflegepersonal vergeben), ihr Geburtstag (GebTag) und das Geschlecht zugewiesen. Außerdem wird das Gebäude erfasst, in dem Sie gehalten werden und die Gattung, zu der sie gehören (z.B. Afrikanische Elefanten, Bengalen-Tiger, Schimpansen, Nil-Krokodile). Für jede Gattung wird auch festgehalten, wie viele Tiere dieser Gattung der Zoo hat (z.B. 5 Afrikanische Elefanten oder 20 Schimpansen) (Anzahl). Wegen der Bedeutung der Information für die Gebäude und das Außengelände wird bei Elefanten noch zusätzlich das Gewicht und bei Giraffen die Größe erfasst, jeweils mit dem Datum der Messung (DatumMessung). |
|
Auch die Rahmenbedingungen der Fütterung der Tiere wird festgehalten: Welches Futter (Bez) ein Tier bekommt (durchaus mehrere Futterarten, z.B. Heu und Frischkost), wieviel Mindestvorrat (MindMenge) gehalten werden muss und welche Menge davon ein Tier typischerweise täglich (MengeJeTag) verzehrt. |
|
Für die einzelnen Gebäude des Zoos wird eine Gebäudenummer (GebNr), die Größe, der Typ (für Säugetiere, für Reptilien, usw.) und die Anzahl der Plätze (AnzPlätze) erfasst. |
|
8.7.2 Lösungsschritte |
|
Ganz klar ist bei diesem Anwendungsbereich, dass die Tiere essentieller Bestandteil des Entity Relationship-Modells sind. Für sie wird daher ein Entitätstyp mit den angegebenen Attributen angelegt. Der Entitätstyp wird Tiere-Einzeln genannt, weil zu Beginn die gesamte Anforderung gelesen wurde (immer empfehlenswert!) und dabei deutlich wurde, dass auch noch Tiergattungen erfasst werden sollen. |
|
|
|
Abbildung 6.7-1: ER-Modell Zoo - Entitätstyp Tiere-Einzeln |
|
Für bestimmte Tiere werden noch zusätzliche Attribute erfasst. Für die Giraffen die Größe, für die Elefanten das Gewicht, jeweils mit dem Datum der Messung. Dies erfordert eine Generalisierung / Spezialisierung mit den Entitätstypen Giraffen und Elefanten und den angeführten Attributen. |
|
|
|
Abbildung 6.7-2: ER-Modell Zoo - Generalisierung / Spezialisierung |
|
Auch die Gebäude sollen, so die Anforderungen, mit GebNr (Schlüssel), Größe, Typ, AnzPlätze erfasst werden. Es entsteht ein Beziehungstyp G_T, die Min-/Max-Angaben ergeben sich mit 1,1 bei den Tieren und 0,m bei den Gebäuden. |
Gebäude |
Für die Tiergattungen wird der Entitätstyp Tiere-Gattung angelegt mit den Attributen Bez als Schlüssel und Anzahl. Er wird mit einem Beziehungstyp TG_T mit Tiere-Einzeln verknüpft. Die Min-/Max-Angaben sind 1,1 bei Tiere-Einzeln und 1,m bei Tiere-Gattung. |
Gattung |
Bleiben noch die Rahmenbedingungen der Fütterung. Da die Futterarten nicht nur erwähnt sondern beschrieben werden, entsteht für sie ein Entitätstyp Futterarten mit dem Schlüssel Bez und den Attributen MinMenge und Vorrat. Der typische tägliche Verzehr wird über einen Beziehungstyp Fütt zwischen Tiere-Einzeln und Futterarten festgehalten. Der Beziehungtyp erhält das Attribut MengeJeTag. Die Min-/Max-Angaben sind bei beiden Etn 1,1, denn jedes Tier wird mindestens einmal am Taag gefüttert und von jeder Futterart wird mindestens einmal am Tag etwas verabreicht. |
Fütterung |
8.7.3 Lösung |
|
Damit ergibt sich das folgende Gesamtmodell. |
|
|
|
Abbildung 6.7-3: ER-Modell Zoo |
|
8.8 Vorlesungsbetrieb |
|
8.8.1 Anforderungen |
|
Für den Vorlesungsbetrieb einer Hochschule soll ein ER-Modell (ERM) erstellt werden. Folgende Realweltaspekte sind zu erfassen: |
|
- Die Lehrveranstaltungen (LV) als solche mit ihrer Bezeichnung (BezLV) und der Angabe des Semesters, indem sie nach Studienplan stattfinden (SemPlan). Außerdem soll festgehalten werden, in welchem Studiengang (SG) sie stattfinden (Bachelor WI, Bachelor AI, Master WI, usw.).
- Die Dozenten mit Name, Vorname, E-Mail und Typ (intern / extern).
- Die konkreten Termine einer jeden Lehrveranstaltung mit Tag, Beginn, Ende, Raum, Semester. Die Redundanz, die in der gleichzeitigen Erfassung von Tag und Semester liegt, soll akzeptiert werden.
- Welcher Dozent welche Lehrveranstaltung grundsätzlich zu halten bereit (und fähig) ist.
- Welcher Dozent die Termine einer LV konkret wahrnimmt. Es ist durchaus möglich, dass sich mehrere Dozenten die Veranstaltungstermine einer Lehrveranstaltung aufteilen, allerdings ist zu einem Vorlesungstermin immer nur ein Dozent anwesend.
- Für externe Dozenten, welche konkreten LV (BezLV) sie zu geben in der Lage sind.
- Die Studierenden mit Matrikelnummer MatrNr, Name, Vorname.
- Der Besuch der Veranstaltungstermine durch die Studierenden. An dieser Hochschule ist es üblich, die Anwesenheit zu kontrollieren. Deshalb wird für jeden Veranstaltungstermin einer Lehrveranstaltung festgehalten, welche Studierenden anwesend waren.
8.8.2 Lösungsschritte |
|
Sofort erkennbar als Entitätstyp (Identifikation + Beschreibung) sind die Lehrveranstaltungen (LV) mit den angeführten Attributen. Schlüssel ist BezLV. |
|
|
|
Abbildung 6.8-1: Entitätstyp zu Lehrveranstaltungen |
|
Danach kommt die Beschreibung der Dozenten und Dozentinnen. Für sie wird ein Entitätstyp Doz mit dem Schlüssel DozNr und den weiteren angeführten Attributen geschaffen. Der Text verrät, dass es interne und externe Dozenten gibt. Erstere bei der Hochschule beschäftigt, zweitere von außerhalb kommend. Das deutet eine Generalisierung / Spezialisierung an. Da aber im weiteren keine spezifiaschen Attribute für die internen Dozenten genannt werden, muss nur eine Spezialisierung für die externen Dozenten (Doz-Extern) angelegt werden. Das kommt nicht oft vor, ist aber möglich. Weiter unten ist angeführt, dass externe Dozenten durchaus auch mehrere Vorlesungen halten können. Deshalb ist das Attribut BezLV (Bezeichnung Lehrveranstaltung) hier mehrwertig. |
Generalisierung / Spezialisierung |
Weiter unten in den Anforderungen ist zu lesen, dass erfasst werden soll, welcher Dozent welche Lehrveranstaltung grundsätzlich zu halten bereit und fähig ist. Das ist eine für die Vorlesungsplaner wichtige Information, die durch einen Beziehungstyp Doz-LV dargestellt werden kann. Doz-LV verknüpft Doz und LV mit den Min-/Max-Angaben 1,n bzw. 1,m. |
Doz |
|
|
Abbildung 6.8-2: ER-Fragment Dozenten und ihre Lehre |
|
An dieser Hochschule wird die Anwesenheit bei den einzelnen Terminen der Lehrveranstaltungen festgehalten. Dies erfordert einen entsprechenden Entitätstyp, der hier LV-Termine genannt werden soll. Er hat (natürlich) eine zeitliche Dimension. Die angeführten Attribute sind identifizierend, ja sogar schon Teile davon. Es ist trotzdem nicht sinnvoll, daraus einen Schlüssel zu konstruieren, da ein solcher im späteren praktischen Umgang mit den Daten zu großer Komplexität bei Abfragen und Auswertungen führen würde. Wir legen deshalb einen Schlüssel LVTNr (Lehrveranstaltungsterminnummer) an, der jeden einzelnen Termin identifiziert. |
|
LV und LV-Termine sind verknüpft. Der Beziehungstyp wird LV-T genannt. Die Min-/Max-Angaben sind 1,m bei LV (zu einer Lehrveranstaltung gehören typischerweise mehrere Termine) und 1,1 bei LV-Termine (jeder Termin gehört zu einer Lehrveranstaltung). |
|
|
|
Abbildung 6.8-3: ER-Fragment zu Lehrveranstaltungen und ihren Terminen |
|
Bleiben noch die Studierenden und der Besuch der einzelnen Veranstaltungstermine durch diese. Der Entitätstyp Studierende erhält als Schlüssel MatrNr (Matrikelnummer) und als beschreibende Attribute Name und Vorname. Für die Anwesenheitskontrolle wird ein Beziehungstyp S-LVT angelegt. Er verknüpft LV-Termine und Studierende. Die Min-/Max-Angaben sind 0,n bei Studierende (ein/e Studierende/r starte mit Null, kann dann aber viele Termine besuchen) und 3,n bei LV-Termine (ein Termin findet statt, falls mindestens 3 Studierende anwesend sind). |
Studierende |
Die Information zur Anwesenheit kannn über ein Attribut AnwesendJN auf dem Beziehungstyp S-LVT erfassbar gemacht werden. |
|
Die Anforderungen verlangen auch noch, dass festgehalten wird, wer welche konkreten Lehrveranstaltungstermine wahrnimmt. Dafür wird ein Beziehungstyp D-LVT zwischen Dozenten und LV-Termine eingefügt. Er erhält die Min-/Max-Angabe 0,m bei Dozenten (ein Dozent kann mehrere Termine wahrnehmen) und 1,1 bei LV-Termine, da in den Anforderungen steht, dass maximal eine Lehrkraft bei jedem Termin anwesend ist. |
Lehrbetrieb |
Diese letzten Fragmente des Entity Relationship-Modells sind unten in die Lösung eingefügt. |
|
8.8.3 Lösung |
|
Damit sind alle Fragment des ER-Modells modelliert. Fügen wir sie zussammen, erhalten wir untenstehende Lösung. |
|
|
|
Abbildung 6.8-4: Entity Relationship-Modell Vorlesungsbetrieb |
|
|
8.9 Wörterbuchverlag |
|
8.9.1 Anforderungen |
|
Es geht um die Produkte eines Verlages, der Wörterbücher (z.B. Deutsch nach Englisch), digital oder auch gedruckt, herstellt und verkauft und der seit einiger Zeit auch Übersetzungsprogramme anbietet. Seine Produkte sollen in einer Datenbank verwaltet werden. Einige Attribute sind schon angeführt. Zu erfassen ist folgendes: |
|
- Alle Wörterbücher und Volltextübersetzer (vgl. unten) mit den Sprachen, die abgedeckt sind (z.B. Deutsch nach Englisch und Englisch nach Deutsch, Deutsch nach Französisch und Französisch nach Deutsch), . . .). Es ist grundsätzlich möglich, dass ein Wörterbuch auch nur eine Richtung abdeckt.
- Für jedes gedruckte Wörterbuch wird auch festgehalten, wieviele Einträge es hat (Einträge), für welche Zielgruppe es gedacht ist (Schüler, Studierende, "Anwender", "Profi-Anwender", Übersetzer) (Zielgruppe), wann es auf den Markt gebracht wurde (ErschDatum) und wieviele Seiten es hat (AnzSeiten).
- Für jedes digitale Wörterbuch wird auch festgehalten, wann es auf den Markt gebracht wurde (ErschDatum), welche Bezeichnung (SWBez) die aktuelle Software hat (z.B. Professional English 7.0), wieviele Einträge es hat (Einträge) und für welche Zielgruppe es gedacht ist (Schüler, Studierende, "Anwender", "Profi-Anwender", Übersetzer) (Zielgruppe).
- Für jeden "Volltextübersetzer" (Programm zur automatischen Übersetzung) wird auch festgehalten, welche Sprachen abgedeckt sind, wieviele Einträge das Systemlexikon hat (Einträge), für welche Zielgruppe das Produkt gedacht ist und wann es auf den Markt gebracht wurde. Festgehalten wird außerdem, ob das Systemlexikon durch den Anwender erweiterbar ist (Erweiterbarkeit) und ob man den Käufern anbietet, es durch Internetzugriffe regelmäßig aktualisieren zu lassen. Falls ja, wie lange dies möglich ist (AktJahre), z.B. 5 Jahre ab Kauf. Falls ein Produkt mit der Möglichkeit der Internetaktualisierung nicht mehr angeboten wird, wird dies auch festgehalten (RunterVomMarkt).
- Die Volltextübersetzer beruhen jeweils auf einem Übersetzungsprogramm. Es kann sein, dass ein Volltextübersetzer mit verschiedenen Programmen angeboten wird (z.B. Zielgruppenspezifisch). Natürlich dient ein Programm u.U. vielen Volltextübersetzern (z.B. Deutsch nach Englisch, Französisch nach Deutsch). Für diese Programme wird festgehalten, welche Dokumentarten (DokArten) sie auswerten können (Word, PDF, Bildformate, usw.) und ob es möglich ist, die Programmleistung in Textprogramme zu integrieren (Integrierbarkeit).
- Die Programme für die digitalen Wörterbücher werden nicht erfasst.
- Für die Programme der Volltextübersetzer werden außerdem die Softwarehäuser, die an der Erstellung mitgearbeitet haben, mit ihrer Anschrift (nur die Zentrale) und ihrer zentralen E-Mail-Adresse erfasst. Es kommt durchaus vor, dass ein Programm von mehreren Softwarehäusern erstellt wird. Festgehalten wird auch, wann die Zusammenarbeit mit dem Softwarehaus bzgl. eines Programmes begann (Beginn) und - gegebenenfalls - wann sie endete (Ende). Diese Angaben sind natürlich i.d.R. je nach Produkt, bei dem zusammengearbeitet wurde, unterschiedlich.
|
|
8.9.2 Lösungsschritte |
|
Hier wird nun obiger Text Schritt für Schritt bearbeitet und in ein Entity Relationship-Modell überführt. |
|
- Alle Wörterbücher und Volltextübersetzer (vgl. unten) mit den Sprachen, die abgedeckt sind (z.B. deutsch nach englisch und englisch nach deutsch, deutsch nach französisch und französisch nach deutsch), . . .). Es ist grundsätzlich möglich, dass ein Wörterbuch auch nur eine Richtung abdeckt. |
|
Zwei Tatsachen sind direkt ableitbar. Erstens, dass es wohl Wörterbücher und Volltextübersetzer als solche gibt - und zwar wahrscheinlich als "Spitze" einer Generalisierungshierarchie. Nennen wir sie Produkte und geben ihnen den Schlüssel ProdNr. Zweites, dass die abgedeckten Sprachen zu erfassen sind, und zwar als mehrwertige Attribute an diesem Entitätstyp: |
|
|
|
Abbildung 6.9-1: Entitätstyp Produkte - Version 1 |
|
Nächste Anforderungen: |
|
- Für jedes gedruckte Wörterbuch wird auch festgehalten, wieviele Einträge es hat (Einträge), für welche Zielgruppe es gedacht ist (Schüler, Studierende, "Anwender", "Profi-Anwender", Übersetzer) (Zielgruppe), wann es auf den Markt gebracht wurde (ErschDatum), wieviele Seiten es hat (AnzSeiten). |
|
Hier wird eine erste Spezialisierung deutlich: Gedruckte Wörterbücher. Sie werden WöBüBuch genannt und haben (erstmal) die angeführten Attribute. |
|
- Für jedes digitale Wörterbuch wird auch festgehalten, wann es auf den Markt gebracht wurde (ErschDatum), welche Bezeichnung (SWBez) die aktuelle Software hat (z.B. Professional English 7.0), wieviele Einträge es hat (Einträge) und für welche Zielgruppe es gedacht ist (Schüler, Studierende, "Anwender", "Profi-Anwender", Übersetzer) (Zielgruppe). |
|
Damit ist die zweite Spezialisierung klar: digitale Wörterbücher. Dieser Entitätstyp wird WöBüDigital genannt. Da hier zum Teil dieselben Attribute wie in WöBüBuch auftauchen, gibt es also Attribute, die der Generalisierung zuzuordnen sind: Einträge, ErschDatum und Zielgruppe. Damit ergibt sich das folgende ER-Fragment. |
|
|
|
Abbildung 6.9-2: Entitätstyp Produkte - Version 2 |
|
Es kann aufgrund der Anforderungen vermutet werden, dass die Generalisierung / Spezialisierung noch weitergeführt wird, deshalb legen wir eine Tabelle mit den zugehörigen Entitätstypen und Attributen an. |
|
Attributtabelle: Produkte und ihre Spezialisierungen - 1 |
|
Produkte |
Gedruckte Wörterbücher (WöBüBuch) |
Digitale Wörterbücher (WöBüDigital) |
ProdNr |
ProdNr |
ProdNr |
Sprachen (mehrwertig) |
Sprachen (mehrwertig) |
Sprachen (mehrwertig) |
Einträge |
Einträge |
Einträge |
Zielgruppe |
Zielgruppe |
Zielgruppe |
ErschDatum |
ErschDatum |
ErschDatum |
|
AnzSeiten |
|
|
|
SWBez |
| |
Der Übersichtlichkeit halber wurde der Schlüssel der Generalisierung auch in den Spalten der Spezialisierungen angeführt. |
|
Nun wieder die Anforderungen: |
|
- Für jeden "Volltextübersetzer" (Programm zur automatischen Übersetzung) wird auch festgehalten, welche Sprachen abgedeckt sind, wieviele Einträge das Systemlexikon hat (Einträge), für welche Zielgruppe das Produkt gedacht ist und wann es auf den Markt gebracht wurde. Festgehalten wird außerdem, ob das Systemlexikon durch den Anwender erweiterbar ist (Erweiterbarkeit) und ob man den Käufern anbietet, es durch Internetzugriffe regelmäßig aktualisieren zu lassen. Falls ja, wie lange dies möglich ist (AktJahre), z.B. 5 Jahre ab Kauf. Falls ein Produkt mit der Möglichkeit der Internetaktualisierung nicht mehr angeboten wird, wird dies auch festgehalten (RunterVomMarkt). |
|
Dies zeigt eine weitere Spezialisierung: Volltextübersetzer. Ergänzen wir damit die Attributtabelle: |
|
Attributtabelle: Produkte und ihre Spezialisierungen - 2 |
|
Produkte |
WöBüBuch |
WöBüDigital |
Volltextübersetzer (VTÜ) |
ProdNr |
ProdNr |
ProdNr |
ProdNr |
Sprachen |
Sprachen |
Sprachen |
Sprachen |
Einträge |
Einträge |
Einträge |
Einträge |
Zielgruppe |
Zielgruppe |
Zielgruppe |
Zielgruppe |
ErschDatum |
ErschDatum |
ErschDatum |
ErschDatum |
|
AnzSeiten |
|
|
|
|
SWBez |
|
|
|
|
Nur bestimmte: ErweiterbarkeitJN |
|
|
|
Nur bestimmte: AktJahre |
| |
Wir wissen, dass in der ER-Modellierung eine Situation wie hier beim Entitätstyp VTÜ (Volltextübersetzer) mit den spezifischen Attributen für Volltextübersetzer mit Aktualisierung zu einer weiteren Spezialisierung führt, weshalb wir die Attributtabelle gleich verändern und einen weiteren Entitätstyp VTÜmitAkt (Volltextübersetzer mit Aktualisierung) anlegen können. |
|
Attributtabelle: Produkte und ihre Spezialisierungen - 3 |
|
Produkte |
WöBüBuch |
WöBüDigital |
VTÜ |
VTÜmitAkt |
ProdNr |
ProdNr |
ProdNr |
ProdNr |
ProdNr |
Sprachen |
Sprachen |
Sprachen |
Sprachen |
Sprachen |
Einträge |
Einträge |
Einträge |
Einträge |
Einträge |
Zielgruppe |
Zielgruppe |
Zielgruppe |
Zielgruppe |
Zielgruppe |
ErschDatum |
ErschDatum |
ErschDatum |
ErschDatum |
ErschDatum |
|
AnzSeiten |
|
|
|
|
|
SWBez |
|
|
|
|
|
ErweiterbarkeitJN |
|
|
|
|
|
AktJahre |
|
|
|
|
RunterVomMarkt |
| |
Damit wird folgende Generalisierung / Spezialisierung deutlich: Die Zahl der Einträge, die Sprachen, die Zielgruppe und das Erscheinungsdatum (ErschDatum) erfassen wir weiterhin in der Generalisierung Produkte. Das Attribut SWBez bei WöBüDigital, das Attribut AnzSeiten bei WöBüBuch, ErweiterbarkeitJN bei VTÜ und AktJahre sowie RunterVomMarkt bei VTÜmitAkt. |
|
|
|
Abbildung 6.9-3: Generalisierung / Spezialisierung rund um Produkte |
|
Nun wieder die Anforderungen: |
|
- Die Volltextübersetzer beruhen jeweils auf einem Übersetzungsprogramm. Es kann sein, dass ein Volltextübersetzer mit verschiedenen Programmen angeboten wird (z.B. zielgruppenspezifisch). Natürlich dient ein Programm u.U. vielen Volltextübersetzern (z.B. Deutsch nach Englisch, Französisch nach Deutsch). Für diese Programme wird festgehalten, welche Dokumentarten (DokArt) sie auswerten können (Word, PDF, Bildformate, usw.) und ob es möglich ist, die Programmleistung in Textprogramme zu integrieren (IntegrierbarkeitJN). |
|
Hier werden nun die Übersetzungsprogramme zu einem Entitätstyp, der ÜbProgramme genannt werden soll. Er erhält die oben angeführten Attribute. Da Programme mehrere Dokumentarten auswerten können, ist das Attribut DokArt mehrwertig. |
|
|
|
Abbildung 6.9-4: Entitätstyp ÜbProgramme |
|
Es wird auch gleich die Beziehung zwischen Übersetzungsprogrammen und den Volltextübersetzern geklärt. Für diese muss ein eigener Beziehungstyp VTÜ-P eingerichtet werden. |
|
|
|
Abbildung 6.9-5: Beziehungstyp VTÜ-P |
|
Da ein Übersetzungsprogramm vielen Volltextübersetzern dienen kann, umgekehrt aber ein bestimmter Volltextübersetzer nur ein Übersetzungsprogramm hat, werden die Min-/Max-Angaben wie folgt: |
|
- 1:1 beim Entitätsty Vollextübersetzer
- 1:n beim Entitätstyp ÜbProgramme
|
|
Die Anforderungen: |
|
- Die Programme für die digitalen Wörterbücher werden nicht erfasst. |
|
Daraus folgt, dass beim "Einbau" der Programme in das Datenmodell an die digitalen Wörterbücher nicht gedacht werden muss. |
|
Weiter mit den Anforderungen: |
|
Für die Programme der Volltextübersetzer werden außerdem die Softwarehäuser, die an der Erstellung mitgearbeitet haben, mit ihrer Anschrift (nur die Zentrale) festgehalten. Es wird auch die zentrale E-Mail-Adresse erfasst. Es kommt durchaus vor, dass ein Programm von mehreren Softwarehäusern erstellt wird. |
|
Festgehalten wird auch, wann die Zusammenarbeit mit dem Softwarehaus bzgl. eines Programmes begann (Beginn) und - gegebenenfalls - wann sie endete (Ende). Diese Angaben sind natürlich i.d.R. je nach Produkt, bei dem zusammengearbeitet wurde, unterschiedlich. |
|
Obiger Punkt führt die Softwarehäuser als Entitätstyp ein. Er wird SWH genannt. Wir legen die Bezeichnung (Bez) als Schlüssel und die Attribute Ort, PLZ, Straße, E-Mail als Adressattribute fest. |
|
Der zweite Satz gibt den Hinweise, dass zwischen Programmen und Softwarehäusern eine n:m-Beziehung vorliegt, wenn man davon ausgeht, dass ein Softwarehaus im Zeitverlauf auch an mehreren Programmen des Verlags mitgearbeitet hat. Dies wird durch einen Beziehungstyp SH-P modelliert. Zusammen mit dem Hinweise auf die zu erfassenden Start- und Endtermine (Beginn, Ende) für die Zusammenarbeit ergibt sich das folgende Modellfragment. |
|
|
|
Abbildung 6.9-6: Beziehung zwischen Übersetzungsprogrammen und Softwarehäusern |
|
8.9.3 Lösung |
|
Fügt man die einzelnen Modellfragmente zusammen, ergibt sich das folgende Datenmodell. |
|
|
|
Abbildung 6.9-7: ER-Modell Wörterbuchverlag |
|
|
|
9 Von ERM zu RM |
|
Irgendwann passiert es, dass Semantische Datenmodelle umgewandelt werden in Modelle, die näher an den konkreten Strukturen datenverwaltender Systeme sind. Denn sie sollen ja zum Einsatz kommen. Im Fall von Entity Relationship-Modellen sind dies meist relationale Datenmodelle, die mit relationalen Datenbanksystemen umgesetzt werden können. Diese Umwandlung soll mit den folgenden Aufgaben geübt werden. |
|
|
|
9.1 Entitätstypen 1 |
|
9.1.1 Aufgabe |
|
Erstellen Sie für folgenden Entitätstyp ein relationales Modellfragment. |
|
|
|
Abbildung 7.1-1: Entitätstyp mit Attributen |
|
9.1.2 Lösung |
|
Entitätstypen ohne mehrwertige Attribute werden in eine einzelne eigene Relation überführt. In der folgenden Relation wird angenommen, dass das Attribut Name ebenfalls Schlüsselcharakter hat. |
|
Angestellte (#PersNr, #Name, Alter, Geschlecht, Gehalt) |
|
9.2 Entitätstypen 2 |
|
9.2.1 Aufgabe |
|
Erstellen Sie für folgenden Entitätstyp ein relationales Modellfragment. |
|
|
|
Abbildung 7.2-1: Attributsonderfälle |
|
9.2.2 Lösung |
|
Die Abbildung zeigt die Sonderfälle zusammengesetzte Attribute, abgeleitete Attribute und mehrwertige Attribute. Diese Attributsonderfälle werden wie folgt in relationale Datenmodelle abgebildet: |
|
- Bei zusammengesetzten Attributen werden nur die "äußersten" Attribute übernommen. Die Information, dass die Attribute etwas zusammen modellieren, dass sie "zusammengehören", geht verloren. Hier bleiben also Ort, PLZ und Straße sowie Nachname und Vorname übrig.
- Abgeleitete Attribute können nicht direkt modelliert werden. Bei vielen Datenbanksystemen ist es allerdings möglich, im Rahmen der Einrichtung der Datenbank, ein solches "berechnetes" Attribut anzulegen.
- Jedes mehrwertige Attribut wird zu einer eigenen Relation, entsprechend der Behandlung mehrwertiger Attribute im relationalen Ansatz.
|
|
Aus dem obigen ER-Modell werden damit die folgenden zwei Relationen: |
|
Mitglieder (#Nr, Nachname, Vorname, PLZ, Ort, Straße) |
|
Mitgliedertätigkeiten (#(Nr, Tätigkeit)) |
|
9.3 Beziehungstypen 1 |
|
9.3.1 Aufgabe |
|
Erstellen Sie für das folgende Entity Relationship-Modell ein relationales Modellfragment. Das ERM gehört zu einem Anwendungsbereich Datenbanksysteme. Es enthält technische und preisliche Beschreibungen von Datenbanksystemen. Der Grund für deren Trennung ist, dass die technischen Informationen immer erhoben werden, die kaufmännischen aber nur für einen Teil der Datenbanksysteme. Diese Situation könnte, so wie hier in der folgenden Abbildung, zur Bildung zweier Entitätstypen geführt haben, die durch eine 1:1 - Beziehung T_P verknüpft sind. |
|
Außerdem wird zwischen Produzenten und DBS_T eine 1:n- und zwischen Datentypen und DBS_T eine n:m - Beziehung angenommen. Es liegen somit drei Kardinalitäten in einem Modellfragment vor. |
|
|
|
Abbildung 7.3-1: Drei Kardinalitäten in einem Modellfragment |
|
Entitätstyp DBS_P: Datenbanksysteme / Preisinformation |
|
Entitätstyp DBS_T: Datenbanksysteme / Technische Information |
|
LPreis: Listenpreis |
|
MaxZahlDs: Maximale Anzahl der Datensätze, die das Datenbanksystem verwalten kann |
|
Typ: Typ des Datentyps: numerisch, alphanumerisch, . . . |
|
9.3.2 Lösung |
|
Beziehungstypen werden unterschiedlich modelliert, je nach der Kardinalität und dem Min-/Max-Wert der Beziehung. Für die Übertragung in ein relationales Modell wird zuerst für jeden Entitätstyp eine Relation angelegt: |
|
Produzenten (#ProdNr, Name) |
|
Datentypen (#Bezeichnung, Typ) |
|
DBS_T (#Bezeichnung, MaxZahlDs) |
|
DBS_P (#Bezeichnung, LPreis, KostenWartung) |
|
Für jede n:m - Beziehung muss (unabhängig von den Kardinalitäten) bei der Übertragung eine eigene Relation angelegt werden, so also auch hier für den Beziehungstyp DBS-T: |
Lösung für
n zu m |
DBS_T-Typ (#(BezeichnungDB, BezeichnungDatentyp)) |
|
Alle 1:n - Beziehungen werden in eine Schlüssel/Fremdschlüssel - Beziehung übertragen. Hier muss also die Relation DBS_T ergänzt werden um den Schlüssel von Produzenten: |
Lösung für
1 zu n |
DBS_T (#Bezeichnung, MaxZahlDs, ProdNr) |
|
Bei 1:1 - Beziehungen ist die Regellösung die, dass einer der beiden Schlüssel als Fremdschlüssel in die andere Relation genommen wird. Mit obigem Beispiel und der Annahme, dass es sich um eine Pflichtbeziehung handelt (beide Min-/MAX-Angaben also 1,1 sind), ergeben sich folgende möglichen Lösungen: |
Lösung für
1 zu 1 |
DBS_T (#BezTech, MaxZahlDs, BezPreis) |
|
Oder |
|
DBS_P (#BezPreis, LPreis, KostenWartung, BezTech)) |
|
DBS_T und DBS_P sind hier bei jeder Beziehung identisch. Die unterschiedlichen Bezeichnungen wurden nur aus didaktischen Gründen gewählt. |
|
9.4 Beziehungstypen 2 |
|
9.4.1 Aufgabe |
|
Erstellen Sie für folgende Entity Relationship-Modelle jeweils ein relationales Modellfragment. Es geht um das Zusammenwirken von Trainern und Mannschaften, jeweils mit derselben Kardinalität, aber mit unterschiedlichen Min-/Max-Angaben. |
|
|
|
Abbildung 7.4-1: Verschiedene Min-/Max-Angaben |
|
9.4.2 Lösung |
|
Im ersten Beispiel wird auf beiden Seiten von einer Min-/Max-Angabe des Typs 1,1 ausgegangen. Dies bedeutet, dass es für jede Mannschaft einen Trainer gibt und für jeden Trainer eine Mannschaft. Dies wird so modelliert, dass in einer der beiden Relationen der Schlüssel der anderen als Fremdschlüssel eingefügt wird: |
|
Mannschaften (#MNr, TrNr, ...) |
|
Trainer (#TrNr, ...) |
|
Oder |
|
Mannschaften (#MNR, ...) |
|
Trainer (#TrNr, MNr, ...) |
|
Im zweiten Beispiel liegt auf einer Seite die Min-/Max-Angabe 0,1 vor. Dies bedeutet: Eine Mannschaft kann, muss aber nicht einen Trainer haben. Umgekehrt liegt 1,1 vor. Hier ist also den Trainern immer eine Mannschaft zugeordnet, nicht aber den Mannschaften ein Trainer. In einer solchen Situation muss der Relation mit der Min-/Max-Angabe 1,1 der Schlüssel der anderen als Fremdschlüssel hinzugefügt werden. Hier also: |
|
Mannschaften (#MNR, ...) |
|
Trainer (#TrNr, MNr, ...) |
|
Im untersten Fall liegt auf beiden Seiten die Min-/Max-Angabe 0,1 vor. Dies bedeutet bei einer Fremdschlüssellösung, dass auf jeden Fall semantisch bedingte Leereinträgeentstehen. D.h., nicht Leereinträge, die durch fehlende Angaben entstehen, sondern solche, die dadurch entstehen, weil es die entsprechende Information einfach nicht gibt. In einem solchen Fall ist die Anlage einer eigenen Relation notwendig, in der die Schlüssel der beiden Relationen jeweils auch Schlüssel sind: |
|
Mannschaften (#MNR, ...) |
|
Trainer (#TrNr, ...) |
|
Mannschaften-Trainer (#MNr, #TrNr)) |
|
Weil dieser Tatbestand und vor allem die dabei entstehende Relation erfahrungsgemäß Probleme bereitet, hier die tabellarische Darstellung. Es gibt vier Mannschaften und drei Trainer. Zwei der Trainer sind für zwei Mannschaften eingesetzt. Die übrigen Trainer und Mannschaften sind nicht in einem Trainingsverhältnis. Die Relation Mannschaften-Trainer zeigt, dass in einer solchen Situation tatsächlich beide Attribute für sich Schlüsselcharakter haben. |
|
Mannschaften |
|
#MNr |
..... |
M123 |
..... |
M234 |
..... |
M345 |
..... |
M456 |
..... |
| |
Trainer
|
|
#TrNr |
..... |
T010 |
..... |
T009 |
..... |
T007 |
..... |
| |
Mannschaften_Trainer
|
|
#TrNr |
#MNr |
T010 |
M123 |
T007 |
M345 |
| |
Diese Lösung erinnert an die Verbindungsrelation bei n:m - Beziehungen, hat aber eine andere Ursache. Da in der neuen Relation jeder Mannschaftsname und auch jede Trainernummer nur einmal vorkommen kann, können beide als Schlüssel dienen. Durch ihre verbindende Funktion mit Mannschaften bzw. Trainer sind sie gleichzeitig auch Fremdschlüssel. |
Keine Verbindungsrelation! |
9.5 Singuläre Entitätstypen |
|
9.5.1 Aufgabe |
|
Erstellen Sie für das folgende Entity Relationship-Modell mit einem singulären Entitätstyp ein relationales Modell. Es geht um die Beziehung zwischen Auftragsköpfen und Auftragspositionen, wie sie üblicherweise modelliert wird. |
|
|
|
Abbildung 7.5-1: Singulärer Entitätstyp Auftragspositionen |
|
Die Attribute mit Punkten deuten die Vielzahl von Attributen an, die bei solchen Entitätstypen normalerweise noch vorliegen. |
|
9.5.2 Lösung |
|
Singuläre Entitätstypen erfassen so etwas wie Existenzabhängigkeit eines Entitätstyps von einem anderen . Damit beruhen sie auf einer Beziehung, die auf einer Seite eine Min-/Max-Angabe mit einem unteren Wert von 1 haben muss, da auf dieser Seite jede Entität an der Beziehung teilnimmt. |
|
Die Umsetzung erfolgt so, dass für die beiden Entitätstypen Relationen angelegt werden, wobei - und das ist zwingend für singuläre Entitätstypen mit ihren Existenzabhängigkeiten - der Schlüssel der Relation, die aus dem singulärem Entitätstyp hervorging, um den Schlüssel der anderen ergänzt wird. Das ist der Grund, weshalb einige Autoren diese Schlüsselergänzung auch gleich im ER-Modell vornehmen, was aber nicht notwendig ist, da der Tatbestand ja durch die Singularität ausgedrückt wird. Hier also: |
|
Auftragsköpfe (#AuftrNr, KundNr, ...) |
|
Auftragspositionen (#(AuftrNr, PosNr), ArtikelNr, Menge, ...) |
|
Damit ergibt sich - wiederum notwendigerweise - in der "singulären" Relation ein zusammengesetzter Schlüssel mit einem Fremdschlüssel, der dem Schlüssel der anderen entspricht. |
|
9.6 Mehrstellige Beziehungen |
|
Mit Pflichtbeteiligung. |
|
9.6.1 Aufgabe |
|
Erstellen Sie für das folgende Entity Relationship-Modell mit einer mehrstelligen Beziehung ein relationales Modell. Es geht um Trainingsaktivitäten. |
|
|
|
Abbildung 7.6-1: Dreistellige Beziehungen |
|
9.6.2 Lösung |
|
Mehrstellige Beziehungen werden so aufgelöst, dass für jeden Entitätstyp und für den Beziehungstyp je eine eigene Relation entsteht. In die so entstehende Verbindungsrelation werden die Schlüssel der beteiligten anderen Relationen als Fremdschlüssel aufgenommen. |
|
Hier entsteht somit: |
|
Trainer (#Name, ...) |
|
Trainingsort (#Name, ...) |
|
Mannschaften (#Name, ...) |
|
Training (#(TrainerName, TrOrtName, MannschName), Datum, Beginn, Ende) |
|
Sind die Min-/Max-Angaben nicht 1,1 wird bei der Schlüsselbildung entsprechend dem relationalen Regelwerk verfahren. |
|
Beispielsdaten |
|
Trainingsort |
Trainer |
Mannschaften |
Datum |
Beginn |
Ende |
TO1 |
T1 |
M1 |
1.1.24 |
8.00 |
12.00 |
TO1 |
T2 |
M1 |
1.1.24 |
8.00 |
12.00 |
TO1 |
T1 |
M2 |
10.1.24 |
14.00 |
16.00 |
| |
9.7 Generalisierung / Spezialisierung |
|
9.7.1 Aufgabe |
|
Erstellen Sie für das folgende Entity Relationship-Modell mit einer Generalisierung / Spezialisierung ein relationales Modell. Die Attribute mit Punkten deuten weitere beschreibende Attribute an. Im Fall der Relation Kunden solche, die alle Kunden gemeinsam haben, bei den anderen die jeweils spezifischen. |
|
|
|
Abbildung 7.7-1: Generalisierung / Spezialisierung bzgl. Kunden |
|
9.7.2 Lösung |
|
Eine Generalisierung / Spezialisierung kann auf verschiedene Weise übertragen werden. Die Variante, die der relationalen Philosophie am nächsten kommt, ist die folgende: Aus dem generalisierten Entitätstyp und aus allen Spezialisierungen wird jeweils eine eigene Relation. |
|
Der Entitätstyp Kunden ist hier spezialisiert in Privatkunden und GewerbKunden (gewerbliche Kunden), letztere dann noch in Großkunden. Damit entstehen folgende Relationen: |
|
Kunden (#Name, Typ, ...) |
|
Privatkunden (#Name, ...) |
|
GewerbKunden (#Name, ...) |
|
Grosskunden (#Name, ...) |
|
Die Punkte stehen für weitere Attribute. Im Fall der Relation Kunden für solche, die alle Kunden gemeinsam haben, bei den anderen für die jeweils spezifischen Attribute. Die Schlüssel der Relationen, die Spezialisierungen darstellen, sind gleichzeitig auch Fremdschlüssel. Dies entspricht nicht der üblichen relationalen Verknüpfung, ist aber unvermeidbar. Hier gilt nicht, dass es für jede Ausprägung des Schlüssels eine oder mehrere Ausprägungen des Fremdschlüssels gibt, sondern dass die Menge der Ausprägungen des Schlüssels in der "Generalisierungsrelation" die Ausprägungen der anderen enthält und dass es für jede Schlüsselausprägung in der "Generalisierungsrelation" genau eine Ausprägung in einer der Spezialisierungen gibt. |
Fremdschlüssel besonderer Art |
Das relationale Modell enthält damit nicht mehr die Information, dass es sich um eine Generalisierung / Spezialisierung handelt. Diese Information muss über die Anwendung in das System gebracht werden. |
|
Die zweite Lösung für die Übertragung einer Generalisierung / Spezialisierung besteht darin, für jede Spezialisierung eine Relation anzulegen, die zusätzlich zu den spezifischen Attributen auch die allgemeinen enthält. Für die Generalisierung wird keine Relation angelegt. Im obigen Beispiel entstünden damit folgende Relationen: |
Zweite Lösung |
Privatkunden (#Name, "allgemeine Attribute", "spezifische Attribute") |
|
GewerbKunden (#Name, "allgemeine Attribute", "spezifische Attribute") |
|
Grosskunden (#Name, "allgemeine Attribute", "Attribute von GewerbKunden", "spezifische Attribute") |
|
Hier wurde eine totale Beteiligung angenommen, d.h., die Spezialisierungen decken alle Entitäten der Generalisierung ab. Liegt keine totale Beteiligung vor, ist diese Lösung nicht geeignet. |
|
Die dritte Lösung besteht darin, eine einzige Relation zu erstellen, die alle Attribute enthält. Im Beispiel: |
Dritte Lösung |
Kunden (#Name, Typ, "allgemeine Attribute Kunden", "spezifische Attribute Privatkunden", "spezifische Attribute GewerbKunden", "spezifische Attribute Großkunden") |
|
Eine solche Relation ist allerdings nicht für effizientes Arbeiten geeignet, denn die Attribute beziehen sich ja, bis auf die allgemeinen, nur jeweils auf eine Auswahl der Tupel. |
|
9.8 Angestellte / Kinder |
|
9.8.1 Aufgabe |
|
Wandeln Sie das folgende Modellfragment in ein relationales Modell um. |
|
|
|
Abbildung 7.9-1: ER-Modell Angestellte / Kinder |
|
AbtBez: Abteilungsbezeichnung |
|
GebTag: Geburtstag |
|
9.8.2 Lösung |
|
Der Entitätstyp Kinder ist ein sog. schwacher Entitätstyp (singulärer Entitätstyp; weak entity type), vgl. auch Aufgabe 7.5. Das bedeutet, dass die Existenz einer Entität in Kinder davon abhängt, dass in einem anderen Entitätstyp (hier: Angestellte) eine bestimmte Entität vorliegt (hier: ein Elternteil). Es liegt also eine Existenzabhängigkeit vor. Im Beispiel ist es so, dass Kinder nur in der Datenbank erfasst werden, wenn mindestens ein Elternteil im Unternehmen ist. |
Singulärer Entitätstyp |
Die Überführung in ein relationales Datenmodell erfolgt so, dass jeweils eine Relation zu den Angestellten und Kindern angelegt wird: |
|
Angestellte (#PersNr, Name, Vorname, AbtBez) |
|
Kinder (Name, Vorname, GebTag) //vorläufig |
|
Wegen der Herkunft von einem schwachen Entitätstyp benötigt die identifizierende Information von Kinder (Name, Vorname) der Ergänzung durch PersNr.Angestellte, um Schlüsselcharakter zu erhalten. Mit den vorliegenden Min-/Max-Angaben kann die Verknüpfung so realisiert werden, dass in Kinder der Schlüssel von Angestellte zum Fremdschlüssel wird. Damit ergibt sich: |
|
Angestellte (#PersNr, Name, Vorname, AbtBez) |
|
Kinder (#(PersNr, Name, Vorname), GebTag) //final |
|
|
|
|
|
|
|
10 Objektorientierte Modellierung mit der UML 2.5 |
|
Für eine umfassende Einführung in die objektorientierte (Daten-)Modellierung vgl. [Staud 2019]: |
|
Staud, Josef Ludwig: Unternehmensmodellierung - Objektorientierte Theorie und Praxis mit UML 2.5. Berlin u.a. 2019 (Springer Verlag) |
|
Ausrichtung |
|
Die folgenden Aufgabenbeispiele beziehen sich auf den inhaltlichen Teil einer objektorientierten Anwendung, die objektorientierte Datenbank. Um die objektorientierte Programmierung und die dafür notwendige Klassenbildung geht es nicht. |
|
Wenn Sie also eine objektorientierte Sprache gelernt haben, haben Sie hauptsächlich von programmtechnischen Aspekten gehört, wenig von der inhaltlichen Struktur der zu verwaltenden und verarbeitenden Daten. Diese kommen nur in einführenden Beispielen vor. Das ist verwunderlich, zumal mit der UML 2.5 eine umfassendes Theoriegebäude vorliegt. Deshalb die Ergänzung in [Staud 2019] und die Aufgaben hier. |
|
Ein paar grundsätzliche Anmerkungen zum Klassenkonzept der objektorientierten Theorie: Auch hier in der objektorientierten Datenbankgestaltung gilt, dass die Grundelemente des Ansatzes, die Klassen, i.d.R. durch Attribute gebildet werden, die ein Realweltphänomen (Angestellte, Produkte, Verträge, . . .) beschreiben. Ganz ähnlich wie in der ER-Modellierung und der relationalen Theorie gibt es das Einzelne (hier: Objekte, Instanzen) und die Zusammenfassung der Objekte mit identischem Aufbau (die Klasse). Und auch hier umfasst "das Ganze" viele gleich aufgebaute "Einzelne". Auch wenn die Objekte der Klassen eine systemgetragene Id erhalten, gibt es im Datenteil i.d.R. Attribute, die Schlüsselcharakter haben. Diese werden hier verwendet. Ein Attribut identifiziert also die Objekte und weitere Attribute beschreiben sie. |
Klassen |
Notationen |
|
Wie in [Staud 2019] sind hier alle Klassendiagramme und sonstigen Modelle sowie die typographische Notation, nach der UML 2.5 gestaltet. |
|
In den hier gezeigten Klassendiagrammen werden auch Datentypen angegeben. Folgende werden in den Texten der UML und in [Rumbaugh, Jacobson und Booch 2005] verwendet und kommen deshalb auch hier zum Einsatz: Category, Money, String, Date, Integer, Boolean, TimeofDay. Einige Beispiele werden auch in C++ angegeben. Da finden folgende Datentypen Verwendung: Char, Float, Double, Int. Wo nötig und sinnvoll sind noch selbsterklärende weitere Datentypen eingefügt. |
UML-Datentypen |
Lesehilfe |
|
Da das Lesen der Wertigkeiten der Assoziationen oft Schwierigkeiten bereitet, vor allem wenn man vorher die Wertigkeiten (Min-/Max-Angaben) in der relationalen und semantischen Modellierung gelernt hat, hier eine Anmerkung dazu. Die Wertigkeiten (Min-/Max-Angaben) der Assoziationen sind in der UML wie in der folgenden Abbildung gezeigt angeordnet. |
|
|
|
Abbildung 8.1-1: Lesehilfe für Min-/Max-Angaben in der UML 2.5 |
|
Nun die Aufgaben |
|
|
|
10.1 Klassenfindung |
|
10.1.1 Aufgabe |
|
Für die Angestellten eines Softwarehauses soll eine Klasse erstellt werden. Erfasst werden sollen Personalnummer (persNr; identifizierend), Name (name), Vorname (vorname) und Geburtstag (gebTag). Als Methoden sollen einstellen, entlassen und Gehalt zahlen (zahlenGehalt) angelegt werden. |
|
10.1.2 Lösung |
|
Die Darstellung einer Klasse ist in der UML wie folgt. Oben wird die Klassenbezeichnung angegeben, darunter die Attribute mit Datentypen, ganz unten die Methoden. Eines der Attribute ist Schlüssel. Der Schlüssel identifiziert Realweltphänomene, die hier meist Objekte bzw. Instanzen genannt werden. Sie werden durch die übrigen Attribute beschrieben. Und zwar so, dass alle Attribute für alle einzelnen Objekte Gültigkeit haben. Ähnliches gilt für die Methoden einer Klasse. Sie müssen auf die Objekte der Klasse anwendbar sein. |
|
Die Klasse wird in der objektorientierten Theorie, insbesondere der objektorientierten Programmierung, deshalb auch als Vorlage für die einzelnen Objekte gesehen. Alle Objekte sind also gleich aufgebaut. Ergibt sich dies einmal anders, müssen weitere Modellierungskonstrukte gewählt werden. |
|
|
|
Abbildung 8.2-1: Klassen in der UML 2.5 |
|
10.2 Projektmitarbeit |
|
10.2.1 Aufgabe |
|
Für die Angestellten eines Softwarehauses soll ein Klassendiagramm zur Projektmitarbeit erstellt werden. Folgende Aspekte sind zu erfassen: |
|
- Die Angestellten, so wie in Aufgabe 8.2 geschehen.
- Die Projekte, an denen sie teilnehmen mit einer Bezeichnung (bez; identifizierend) und dem Standort (standort).
- Die Mitarbeit: Ein Angestellter kann in mehreren Projekten sein und ein Projekt hat typischerweise mehrere Mitwirkende.
|
|
10.2.2 Lösung |
|
Die Klasse Angestellte kann von Aufgabe 8.2 übernommen werden. Für die Projekte ergibt sich eine eigene Klasse, da sie identifiziert und beschrieben werden. Die Mitarbeit bringt die beiden Klassen in eine Beziehung, die in der objektorientierten Theorie Assoziation genannt wird. Die Wertigkeiten sind hier klar angegeben. Ein Angestellter kann in keinem, einen oder mehreren Projekten mitarbeiten, das wird durch einen Stern ausgedrückt: *. Ein Projekt hat mindestens einen zugeordneten Angestellten (z.B. den Projektleiter bei Einrichtung des Projekts), kann aber auch beliebig viele haben. Die wird durch 1..* festgelegt. |
|
Da man vermuten kann, dass die Angestellten im Gesamtgeschehen noch mehrere Assoziation aufweisen werden, wird hier eine Rollenbezeichnung (Projektmitarbeiter) vergeben. |
|
|
|
Abbildung 8.3-1: Assoziation zur Projektmitarbeit |
|
10.3 Abteilungszugehörigkeit |
|
10.3.1 Aufgabe |
|
Für die Angestellten eines Softwarehauses soll ein Klassendiagramm zur Abteilungszugehörigkeit erstellt werden. Folgende Aspekte sind zu erfassen: |
|
- Die Angestellten, so wie in Aufgabe 8.2 geschehen.
- Die Zugehörigkeit der Angestellten zu Abteilungen: In einer Abteilung sind mehrere Angestellte, ein Angestellter gehört aber zu genau einer Abteilung. Die Abteilungen werden durch die Abteilungsbezeichnung (abtBez; identifizierend), den Standort (standort) und den Abteilungsleiter mit seiner Personalnummer (Id), seinem Namen (Name) und seine Büronummer (Raum) erfasst.
|
|
10.3.2 Lösung |
|
Die Klasse Angestellte kann von Aufgabe 8.2 übernommen werden. Für die Abteilungszugehörigkeit, wie sie in der Anforderung beschrieben wird, müssen zwei Klassen angelegt werden, da zwei unterschiedliche Realweltphänomene beschrieben werden: |
|
- Abteilungen mit dem Schlüssel abtBez und dem Attribut standort
- Abteilungsleiter mit dem Schlüssel Id und den Attributen Name und Raum
|
|
Dies ist notwendig, weil beide Realweltphänomene identifiziert und beschrieben werden. Diese Aufteilung in Klassen erfordert Assoziationen. Zum einen zwischen Angestellte und Abteilungen, zum anderen ein zwischen Abteilungen und Abteilungsleiter. Die Wertigkeiten müssen teilweise festgelegt werden (normalerweise würde man nachfragen): |
|
- Für Angestellte / Abteilungen soll gelten: Ein/e Angestellte/r ist höchstens in einer einzigen Abteilung, es gibt aber auch Mitarbeiter, die keiner Abteilung zugeordnet sind.
- Für Abteilungen / Abteilungsleiter soll gelten: Eine Abteilung hat einen einzigen Abteilungsleiter, soll aber in den Daten schon angelegt werden können, wenn noch kein Abteilungsleiter feststeht. Umgekehrt gilt, ein Abteilungsleiter leitet genau eine Abteilung.
|
|
Damit ergibt sich die folgende Lösung. |
|
|
|
Abbildung 8.4-1: Projektmitarbeit im Klassendiagramm |
|
10.4 PC-Nutzung |
|
10.4.1 Aufgabe |
|
Für die Angestellten eines Softwarehauses soll ein Klassendiagramm zur PC-Nutzung erstellt werden. Folgende Aspekte sind zu erfassen: |
|
- die Angestellten (w/m/d)
- die PC
- die Nutzung der PC durch die Angestellten
|
|
Folgende Informationen sollen festgehalten werden: |
|
- Für die Angestellten wie in Aufgabe 8.2 die Personalnummer (persNr; identifizierend), der Name (name), Vorname (vorname) und Geburtstag (gebTag). Als Methoden sollen einstellen, entlassen und Gehalt zahlen (zahlenGehalt) angelegt werden.
- Für die von den Angestellten benutzten PC die Inventarnummer (inventarNr; identifizierend), die Bezeichnung (bez) und der Typ (typ).
- Die Nutzung der PC entlang folgender Feststellung: Ein PC ist genau einem Angestellten zugeordnet und ein Angestellter nutzt maximal einen PC.
- Außerdem soll durch eine Methode jederzeit die Anzahl aller PC festgestellt und gespeichert werden können.
|
|
10.4.2 Lösung |
|
Die Klasse Angestellte kann von Aufgabe 8.2 übernommen werden. Für die Personal Computer kann ebenfalls eine Klasse angelegt werden, PC, da sie durch die inventarNr identifiziert und durch bez und typ weiter beschrieben werden. Die Methode für die Feststellung der Anzahl PC wird feststellenAnzahl() genannt und der Klasse PC zugeordnet. Dort passt auch das Attribut hin, in dem die jeweils aktuelle Anzahl festgehalten wird, anzahlPC. Wir merken uns vor, in der nächsten Besprechung mit den Auftraggebern zu fragen, wie es um die Erfassung des Datums der Messung steht. |
|
Die PC-Nutzung wird durch eine Assoziation zwischen den beiden Klassen ausgedrückt. Entsprechend den Anforderungen ist sie 1 für die PC und 0..1 für die Angestellten, da es hier wohl auch Angestellte geben kann ("maximal einen"), die keinen PC nutzen. Für die Angestellten vergeben wir die Rollenbezeichnung PC-Nutzer. |
|
Die folgende Abbildung zeigt die Lösung. |
|
|
|
Abbildung 8.5-1: Assoziation zur Projektmitarbeit |
|
10.5 PS-Kompetenz |
|
10.5.1 Aufgabe |
|
Für die Angestellten eines Softwarehauses soll ein Klassendiagramm zur Programmiersprachenkompetenz der Beschäftigten erstellt werden. Folgende Aspekte sind zu erfassen: |
|
- die Angestellten (w/m/d)
- die von den Angestellten beherrschten Programmiersprachen mit Angabe der Jahre Programmiererfahrung.
|
|
Folgende Informationen sollen dabei festgehalten werden: |
|
- Für die Angestellten wie in Aufgabe 8.2 die Personalnummer (persNr; identifizierend), Name (name), Vorname (vorname) und Geburtstag (gebTag). Als Methoden sollen einstellen, entlassen und Gehalt zahlen (zahlenGehalt) angelegt werden.
- Für die Programmiersprachen, die von den Angestellten beherrscht werden die Bezeichnung der Sprache (bezPS; identifizierend), die Bezeichnung des Compilers (bezComp) und der Preis (preisLiz) für eine Lizenz.
|
|
Weiterhin gilt: Es ist in diesem Unternehmen so, dass nur Mitarbeiter eingestellt werden, die mindestens zwei Programmiersprachen beherrschen und außerdem wird darauf geachtet, dass für jede Programmiersprache mindestens zwei kompetente Angestellte da sind. Wegen der Bedeutung der Programmiererfahrung wird außerdem festgehalten, wieviel Jahre Programmierpraxis (erfahrPS) jeder Angestellte in seinen Programmiersprachen hat. |
|
10.5.2 Lösung |
|
Für die Angestellten übernehmen wir die in Abschnitt 8.2 entwickelte Klasse. Da für die Programmiersprachen ein identifizierendes Attribut (bezPS) und mehrere beschreibende vorliegen, wird für sie auch eine Klasse angelegt, PSn. Zwischen Angestellte und PSn ist eine Assoziation anzulegen, da ja festgehalten werden soll, wer welche Programmiersprachen beherrscht. Diese hat gemäß den Anforderungen auf beiden Seiten die Wertigkeiten 2..*. |
|
Bleibt noch die Programmiererfahrung, die Kompetenz in den einzelnen Programmiersprachen. Diesbezüglich soll die Anzahl der Jahre Programmierpraxis erfasst werden. Dies ist eine einfache numerische Angabe, die aber weder den Angestellten, noch den Programmiersprachen zugeordnet werden kann. Sie beschreibt die Verknüpfung der beiden, die Assoziation. Für eine solche Situation, Beschreibung einer Beziehung, sieht die objektorientierte Theorie Assoziationsklassen vor. Sie haben den üblichen Aufbau von Klassen und werden mit gestrichelter Linie an die Assoziation angefügt, wie es die folgende Abbildung zeigt. |
|
Der obere Teil zeigt die Standarddarstellung, wobei die Angestellten hier die Rolle Programmierer haben. Im unteren Teil der Abbildung ist eine Alternative für die Darstellung einer Assoziationsklasse angeben, eine sog. aufgelöste Assoziationsklasse. Sie ist leichter überführbar in die Programmierkonstrukte objektorientierter Programmiersprachen. |
|
Die folgende Abbildung zeigt die Lösung. |
|
|
|
Abbildung 8.6-1: Programmiersprachenkompetenz mit und ohne aufgelöste Assoziationsklasse |
|
Unten: aufgelöste Assoziationsklasse |
|
10.6 Softwarehaus |
|
In dieser Aufgabe werden die Themen der obigen Aufgaben, etwas vereinfacht, integriert betrachtet. Sie kann unabhängig von den obigen bearbeitet werden. Es geht um einen Anwendungsbereich, der in einfacher Form wichtige Aspekte eines Softwarehauses erfasst. |
|
10.6.1 Anforderungen |
|
Erfasst werden sollen: |
|
- die Angestellten (w/m/d)
- die Projekte, an denen sie teilnehmen
- die Abteilungen, denen sie zugehörig sind
- die genutzten PCs
- die von den Angestellten beherrschten Programmiersprachen mit Angabe der Jahre Programmiererfahrung.
|
|
Folgende Informationen sollen für das objektorientiertes Modell festgehalten werden: |
|
- Für die Angestellten Personalnummer (persNr; identifizierend), Name (name), Vorname (vorname) und Geburtstag (gebTag). Als Methoden sollen einstellen, entlassen und Gehalt zahlen (zahlenGehalt) angelegt werden.
- Für die Projekte Bezeichnung (bez; identifizierend) und Standort (
| |