Entwurf und Implementierung einer Oracle-Datenbank
für einen fiktiven Mobilfunkanbieter
Im Rahmen des Lernfelds LF08 wurde eine relationale Datenbank für einen fiktiven Mobilfunkanbieter entworfen und in Oracle SQL implementiert. Ziel war es, ein vollständiges Datenbanksystem zu schaffen, das alle geschäftsrelevanten Daten eines Mobilfunkanbieters strukturiert und konsistent speichert. Die Datenbank umfasst die Verwaltung von Kunden, deren Verträgen, den zugehörigen Tarifen sowie alle anfallenden Verbindungsdaten (Anrufe und SMS).
Ausgangspunkt der Datenbankmodellierung war ein Anforderungskatalog, der folgende Kernanforderungen definiert: Ein Kunde kann bei dem Mobilfunkanbieter mehrere Verträge abschließen. Dabei werden personenbezogene Daten wie Name, Adresse und Ausweisdaten erfasst. Jeder Vertrag ist genau einem Tarif zugeordnet. Ein Tarif besitzt eine Tarifbezeichnung und setzt sich aus einer variablen Kombination von Tarifbausteinen zusammen — beispielsweise einer Anzahl von Freiminuten, einem Preis pro SMS oder einer Daten-Flatrate. Für jeden Vertrag werden vollständige Verbindungsdaten gespeichert: Beginn und Ende einer Verbindung, die Nummer des Gesprächspartners, die Richtung (eingehend/ausgehend) sowie die Art der Verbindung (Gespräch oder SMS).
Aus den Anforderungen wurden sechs Tabellen abgeleitet. Die Tabelle Kunde speichert alle Kundenstammdaten. Sie ist über eine 1:N-Beziehung mit Vertrag verbunden, da ein Kunde mehrere Verträge haben kann. Jeder Vertrag referenziert genau einen Eintrag in der Tabelle Tarif (N:1-Beziehung). Die Tabelle Tarifbaustein enthält die einzelnen Leistungsbausteine eines Tarifs — da ein Tarif aus mehreren Bausteinen bestehen kann und ein Baustein in mehreren Tarifen verwendet werden kann, wird diese M:N-Beziehung durch die Brückentabelle Tarif_Baustein aufgelöst. Verbindungsdaten werden in der Tabelle Verbindung gespeichert, die jeweils einem Vertrag zugeordnet ist (N:1).
Bei der Modellierung wurde konsequent auf die Einhaltung der dritten Normalform geachtet. Alle Nicht-Schlüsselattribute sind ausschließlich vom Primärschlüssel der jeweiligen Tabelle abhängig — transitive Abhängigkeiten wurden durch die konsequente Aufteilung in separate Entitäten eliminiert. So wurden Tarif und Tarifbaustein bewusst getrennt, da Tarifbestandteile (z. B. Freiminuten, SMS-Preise) eigene Entitäten darstellen, die unabhängig von einem konkreten Tarif existieren und mehrfach verwendet werden können.
Die Datenbank wurde speziell für Oracle Database implementiert. Primärschlüssel werden über GENERATED BY DEFAULT AS IDENTITY automatisch vergeben. Zeichenketten nutzen den Oracle-spezifischen Datentyp VARCHAR2. Zeitstempel für Verbindungen werden als TIMESTAMP gespeichert, um Beginn und Ende einer Verbindung sekundengenau erfassen zu können. Für die Verbindungsart und -richtung wurden CHECK-Constraints eingesetzt, um nur gültige Werte zuzulassen. Fremdschlüsselbeziehungen sind durch FOREIGN KEY ... REFERENCESexplizit definiert, was die referentielle Integrität auf Datenbankebene sicherstellt.
Um die Funktionsfähigkeit der Datenbank zu demonstrieren, wurden realistische Beispieldaten eingefügt: vier Kunden, drei Tarife (Basis, Comfort, Premium), fünf Tarifbausteine, sieben Tarif-Baustein-Zuordnungen, fünf Verträge und fünf Verbindungseinträge. Drei SQL-SELECT-Abfragen demonstrieren typische Anwendungsfälle: die Ausgabe aller Verträge eines Kunden mit Tarifinformation, alle Verbindungen eines bestimmten Kunden sowie die Bausteine des Premium-Tarifs — jeweils unter Verwendung von JOIN-Operationen über mehrere Tabellen.
Das folgende Entity-Relationship-Diagramm wurde in Chen-Notation erstellt. Rechtecke repräsentieren Entitäten, Rauten symbolisieren Beziehungen und Ellipsen stellen Attribute dar. Unterstrichene Attribute kennzeichnen Primärschlüssel. Die Kardinalitäten (1, N, M) sind an den Verbindungslinien zwischen Entitäten und Beziehungsrauten eingetragen.
Abb. 1: ER-Diagramm der Handytarif-Datenbank in Chen-Notation. Entitäten: KUNDE, TARIF, TARIFBAUSTEIN, VERTRAG, VERBINDUNG. Beziehungen: hat (1:N), gehört zu (N:1), besteht aus (N:M), erzeugt (1:N).
Das relationale Modell leitet sich aus dem ER-Diagramm ab. Jede Entität wird zu einer Tabelle, Primärschlüssel sind fett hervorgehoben, Fremdschlüssel mit FK gekennzeichnet. Die N:M-Beziehung zwischen Tarif und Tarifbaustein wird durch die Brückentabelle Tarif_Baustein realisiert.
| Attribut | Datentyp | Constraint / Bemerkung |
|---|---|---|
| KundeID 🔑 | NUMBER | PK, NOT NULL, IDENTITY |
| Vorname | VARCHAR2(50) | NOT NULL |
| Nachname | VARCHAR2(50) | NOT NULL |
| Strasse | VARCHAR2(100) | NOT NULL |
| PLZ | VARCHAR2(10) | NOT NULL |
| Ort | VARCHAR2(50) | NOT NULL |
| Ausweisnummer | VARCHAR2(20) | NOT NULL, UNIQUE |
| Attribut | Datentyp | Constraint / Bemerkung |
|---|---|---|
| TarifID 🔑 | NUMBER | PK, NOT NULL, IDENTITY |
| Tarifbezeichnung | VARCHAR2(100) | NOT NULL |
| Attribut | Datentyp | Constraint / Bemerkung |
|---|---|---|
| BausteinID 🔑 | NUMBER | PK, NOT NULL, IDENTITY |
| Bezeichnung | VARCHAR2(100) | NOT NULL |
| Typ | VARCHAR2(30) | NOT NULL |
| Wert | NUMBER(10,2) | NOT NULL |
| Einheit | VARCHAR2(20) | NOT NULL |
| Attribut | Datentyp | Constraint / Bemerkung |
|---|---|---|
| TarifID 🔑 | NUMBER | PK, FK → Tarif |
| BausteinID 🔑 | NUMBER | PK, FK → Tarifbaustein |
| Attribut | Datentyp | Constraint / Bemerkung |
|---|---|---|
| VertragID 🔑 | NUMBER | PK, NOT NULL, IDENTITY |
| Abschlussdatum | DATE | NOT NULL |
| KundeID | NUMBER | NOT NULL, FK → Kunde |
| TarifID | NUMBER | NOT NULL, FK → Tarif |
| Attribut | Datentyp | Constraint / Bemerkung |
|---|---|---|
| VerbindungID 🔑 | NUMBER | PK, NOT NULL, IDENTITY |
| Startzeit | TIMESTAMP | NOT NULL |
| Endzeit | TIMESTAMP | NOT NULL |
| Partnernummer | VARCHAR2(20) | NOT NULL |
| Richtung | VARCHAR2(20) | NOT NULL, CHECK IN ('eingehend','ausgehend') |
| Art | VARCHAR2(10) | NOT NULL, CHECK IN ('Gespraech','SMS') |
| VertragID | NUMBER | NOT NULL, FK → Vertrag |
Die Umsetzung des Datenbankprojekts war eine lehrreiche Erfahrung, die sowohl fachliche als auch technische Herausforderungen mit sich brachte. Im Folgenden werden die wesentlichen Probleme und Lösungsansätze beschrieben.
Zu Beginn war unklar, wie die Beziehung zwischen Tarifen und Tarifbausteinen korrekt modelliert werden sollte. Der naheliegende Ansatz, die Tarifbausteine direkt in der Tarif-Tabelle zu speichern, würde gegen die 1. Normalform verstoßen (Mehrfachwerte in einer Spalte) und eine flexible Wiederverwendung von Bausteinen verhindern. Die Lösung war die Einführung der Brückentabelle Tarif_Baustein mit einem zusammengesetzten Primärschlüssel aus TarifID und BausteinID. Dadurch kann ein Baustein (z. B. "500 Freiminuten") mehreren Tarifen zugeordnet werden, ohne Daten zu duplizieren.
Bei der ersten Entwurfsversion wurden Tarifdetails (Typ, Wert, Einheit) direkt in der Vertragstabelle gespeichert. Dies führte zu transitiven Abhängigkeiten: Die Tarifdetails hingen von der TarifID ab, nicht direkt vom Vertrag. Die Lösung war die Auslagerung in eine eigenständige Tarifbaustein-Tabelle und die Trennung von Tarif (nur Bezeichnung) und den zugehörigen Bausteinen. Damit wurde die 3. Normalform vollständig eingehalten.
Oracle SQL weist einige Besonderheiten auf, die im Vergleich zu MySQL oder PostgreSQL beachtet werden müssen. So existiert in Oracle kein AUTO_INCREMENT — stattdessen wird GENERATED BY DEFAULT AS IDENTITY verwendet. Der Datentyp für Zeichenketten heißt VARCHAR2 statt VARCHAR. Datum und Uhrzeit werden in Oracle mit TO_DATE() eingefügt, Zeitstempel mit dem TIMESTAMP-Literal. Diese Unterschiede erforderten eine genaue Auseinandersetzung mit der Oracle-Dokumentation.
Da Fremdschlüsselbeziehungen die Reihenfolge von DDL-Operationen erzwingen, mussten beim Löschen die abhängigen Tabellen zuerst entfernt werden. Die Tabelle Verbindung muss vor Vertrag gelöscht werden, Vertrag vor Kunde und Tarif, usw. Für das SQL-Skript wurde daher ein CASCADE CONSTRAINTS PURGE-Pattern verwendet, das alle Constraints und den Recycle Bin berücksichtigt.
Die Strukturierung der Anforderungen in ein ER-Modell verlief nach kurzer Einarbeitungszeit problemlos. Die Chen-Notation ermöglichte eine übersichtliche Darstellung aller Entitäten, Beziehungen und Attribute. Die Ableitung des relationalen Modells aus dem ER-Diagramm nach den drei Überführungsregeln war logisch nachvollziehbar. Die SQL-SELECT-Abfragen mit JOIN-Operationen über mehrere Tabellen lieferten korrekte Ergebnisse und demonstrieren den praktischen Nutzen der Datenbankstruktur.
Das Projekt hat gezeigt, wie wichtig eine sorgfältige Datenbankmodellierung vor der eigentlichen Implementierung ist. Fehler in der Konzeptionsphase — etwa fehlende Normalisierung oder falsch modellierte Beziehungen — lassen sich in der Implementierungsphase nur mit erheblichem Aufwand korrigieren. Besonders wertvoll war die Erkenntnis, dass die 3. Normalform nicht nur eine theoretische Anforderung ist, sondern praktische Vorteile bringt: weniger Datenredundanz, einfachere Updates und eine zuverlässigere Datenkonsistenz. Der Umgang mit Oracle-spezifischer Syntax hat außerdem den Blick dafür geschärft, dass SQL-Standards zwar existieren, die Implementierungen der verschiedenen Datenbanksysteme jedoch erheblich voneinander abweichen können.