12 Datenbanken
Sammle erst die Fakten, dann kannst du sie verdrehen, wie es dir passt.
– Mark Twain
Eine der wichtigsten Rechneranwendungen ist die Speicherung, Verwaltung und Manipulation beliebiger Informationen. Datenbanken erfüllen diesen Verwendungszweck am besten. In diesem Kapitel werden zunächst die verschiedenen Arten von Datenbanken vorgestellt. Anschließend werden die Installation und die Anwendung der beliebten Open-Source-Datenbank MySQL behandelt. Danach erhalten Sie einen Überblick über die bedeutendsten Optionen und Funktionen der in den meisten Datenbanksystemen verwendeten Abfragesprache SQL. Als Beispiel für die Datenbankprogrammierung wird schließlich JDBC vorgestellt, eine allgemeine Schnittstelle für den Zugriff auf Datenbanken aus Java-Programmen.
Zunächst ist es wichtig, genau zu definieren, was eine Datenbank eigentlich ist. Der Begriff bezeichnet nämlich zwei verschiedene Dinge: zum einen die Datensammlung selbst, zum anderen das Programm, das diese Daten verwaltet. Bei den Daten handelt es sich um eine nach bestimmten Regeln strukturierte Ansammlung von Informationen zu verschiedenen Themengruppen, beispielsweise Kundendaten von Unternehmen, Diagnose- und Behandlungsinformationen von Ärzten oder die private CD-Sammlung eines Musikfans.
Das Anwendungsprogramm, mit dem diese Daten verwaltet werden können, enthält mehr oder weniger mächtige Funktionen zum Suchen, Sortieren, Filtern und formatierten Ausgeben dieser Daten. Ein solches Programm wird als Database Management System (DBMS), also als Datenbankverwaltungssystem, bezeichnet.
Die Daten, die von einem DBMS verwaltet werden, lassen sich nach verschiedenen Kriterien unterscheiden – übrigens ein beliebtes Thema für IHK-Fragen, insbesondere im EDV-Bereich kaufmännischer Berufe.
Jede Information, die in einer Datenbank gespeichert wird, ist Stammdatum oder Bewegungsdatum und gleichzeitig Rechendatum oder Ordnungsdatum. Die folgenden Definitionen können Ihnen helfen, diese Begriffe zu unterscheiden:
- Stammdaten sind unveränderliche (oder zumindest selten veränderte) Informationen, die dauerhafte Auskunft über die Objekte oder Sachverhalte geben, die in der Datenbank gespeichert sind. Beispiele wären der Name einer Person oder die Bestellnummer eines Artikels.
- Bewegungsdaten sind dagegen Informationen, die sich ständig im Fluss befinden und die Dynamik von Geschäftsabläufen und anderen Prozessen abbilden. Der Saldo auf einem Konto oder die Körpertemperatur eines Patienten sind gute Beispiele dafür.
- Rechendaten sind Daten, die entweder selbst als Glied in einer Berechnung stehen oder aber als Berechnungsgrundlage dienen. Dazu gehören etwa Preise, Zinssätze oder gefahrene Kilometer.
- Ordnungsdaten dienen dagegen der Einteilung, Klassifizierung und Filterung von Informationen. Zu den Ordnungsdaten zählen etwa Namen, Postleitzahlen oder Kfz-Kennzeichen.
Wichtig ist, wie bereits erwähnt, dass jedes Datum stets zwei der zuvor genannten Eigenschaften aufweist. Die folgende Liste zeigt Beispiele für jede der vier möglichen Kombinationen:
- Stammdatum und Rechendatum sind beispielsweise der Preis einer Ware, das Grundgehalt eines Mitarbeiters oder der effektive Jahreszins eines Kredits.
- Stammdatum und Ordnungsdatum sind etwa der Name eines Kunden, die Bestellnummer eines Artikels oder der Titel eines Buches.
- Bewegungsdaten und Rechendaten sind zum Beispiel die Anzahl der abgeleisteten Überstunden eines Mitarbeiters, die Anzahl der gefahrenen Kilometer oder der aktuelle Wechselkurs für eine Fremdwährung.
- Bewegungsdaten und Ordnungsdaten sind unter anderem das aktuelle Kalenderdatum, die Anzahl der Resturlaubstage eines Mitarbeiters oder die auf Lager befindliche Stückzahl eines Artikels.
12.1 Die verschiedenen Datenbanktypen
Da Daten zu vielen verschiedenen Zwecken gespeichert werden müssen, existieren unterschiedliche Arten von Datenbanken. Das wichtigste Modell ist die relationale Datenbank, zu der auch das in diesem Kapitel ausführlich vorgestellte MySQL gehört. In diesem Abschnitt werden die verschiedenen Datenbanktypen vorgestellt. Dies sind im Wesentlichen folgende:
- Einzeltabellendatenbanken dienen der einfachen Verwaltung von Daten eines bestimmten Typs, beispielsweise Anschriften oder Briefmarkensammlungen.
- Relationale Datenbanken bieten die Möglichkeit, mehrere Einzeltabellen miteinander zu verknüpfen, um die Daten konsistent zu halten: Informationen, die an verschiedenen Stellen vorkommen, müssen nur einmal aufgeführt werden.
- Objektorientierte Datenbanken arbeiten auf der Grundlage von Klassen und Objekten wie die objektorientierten Programmiersprachen C++ oder Java. Im Gegensatz zu relationalen Datenbanken sind sie in der Lage, sehr komplexe, nichtlineare Beziehungen zwischen den gespeicherten Informationen abzubilden.
- Volltextdatenbanken sind nicht unbedingt ein eigener Datenbanktyp. Speziell geht es hier um die Implementierung einer effektiven Volltextsuche in vorhandenen Textarchiven. Inzwischen sind auch relationale und objektorientierte Datenbanken mit Volltext-Suchfunktionen ausgestattet.
- XML-Datenbanken speichern die Informationen in Form von XML-Dokumenten ab. XML ist eine Metasprache für die Definition von Dokumentstrukturen und wird in Kapitel 15, »XML«, ausführlich behandelt.
- Bild- und Multimedia-Datenbanken sind meist erweiterte relationale Datenbanken, die die Verwaltung von Mediadaten wie Bildern, Sounddateien oder Digitalvideos realisieren. In der Regel ermöglichen sie die Suche nach Media-Dateien auf den diversen Datenträgern sowie deren Katalogisierung nach verschiedenen Kriterien. Bekannte Beispiele sind Canto Cumulus, das häufig von DTP- oder Presse-Profis eingesetzt wird, oder das kostengünstige Programm ThumbsPlus, das eher für kleine Büros oder Privatleute geeignet ist, die Ordnung in ihr Mediadaten-Chaos bringen möchten. Inzwischen verfügen die Desktops der meisten Betriebssysteme allerdings auch selbst über Bildvorschaufunktionen und zusätzliche Informationen zu Mediendateien.
- NoSQL-Datenbanken bilden einen recht neuen Ansatz in der Datenbanktechnik. Es handelt sich um Datenbanken, die auf die traditionelle Datenbankabfrage SQL und meist auch auf den relationalen Ansatz verzichten. Stattdessen speichern viele von ihnen die Daten als Dokumente mit beliebigen, frei definierbaren Meta-Datenfeldern, über die sie gesucht und gegebenenfalls auch verknüpft werden können. Ein bekanntes Beispiel ist CouchDB; am Ende dieses Kapitels erhalten Sie einen kurzen Überblick über die Möglichkeiten dieser Datenbank.
Neben diesen Grundtypen gibt es auch konkrete Datenbanksoftware, die verschiedene Misch- oder Übergangsformen bildet. Beispielsweise verwenden XML-Datenbanken oft keine reinen XML-Dokumente, sondern legen diese in einer relationalen Grundstruktur ab. Umgekehrt bieten die meisten modernen relationalen Datenbanksysteme spezielle Funktionen für Daten im XML-Format.
In den folgenden Abschnitten werden nur die Einzeltabelle, die relationale Datenbank und die objektorientierte Datenbank näher vorgestellt. Volltext- und Media-Datenbanken sind zu speziell und zu unterschiedlich, um sie allgemein zu beschreiben, und die Behandlung von XML-Datenbanken ohne XML-Kenntnisse ergibt keinen Sinn.
12.1.1 Einzeltabellendatenbanken
Die einfachste Datenbankart verwendet nur eine einzige Tabelle zur Abspeicherung aller Informationen. Die Einzeltabelle ist das Grundprinzip aller einfachen Adressverwaltungs- oder CD-Sammlungsprogramme. Die meisten Eigenschaften von Einzeltabellendatenbanken gelten auch für die professionelleren und erheblich vielseitigeren relationalen Datenbanken, schließlich handelt es sich bei Letzteren um eine Sammlung miteinander verknüpfter Einzeltabellen.
In den Spalten einer Datenbanktabelle stehen die verschiedenen Informationskategorien. Die einzelnen Zellen werden Datenfelder genannt und sind die kleinste Informationseinheit der Datenbank: Sie enthalten je eine Einzelinformation über ein Element der Datenbank. Eine ganze Zeile ist die Kombination aller Informationen über ein Element und wird Datensatz (Record) genannt. Übrigens wird das jeweilige Element, über das ein Datensatz Informationen enthält, als Entität (Entity) bezeichnet.
In Tabelle 12.1 sehen Sie ein Beispiel für eine Datenbanktabelle, die verschiedene Informationen über die Mitarbeiter eines Unternehmens enthält.
Von einer Einzeltabellendatenbank dürfen Sie nicht die komplexe Funktionalität eines relationalen DBMS erwarten, aber von den folgenden Grundfunktionen sollten Sie dennoch ausgehen können:
- Sortieren der Tabelle auf- und absteigend nach einer beliebigen Kategorie (im Beispiel sind die Datensätze aufsteigend nach Namen sortiert). Eine absteigende Sortierung nach Gehältern würde beispielsweise die folgende Reihenfolge erzeugen: Huber, Juarez, Becker, Klein.
- Suchen nach einem beliebigen Feldinhalt und Ausgabe der relevanten Datensätze. Beispielsweise würde die Suche nach dem Eintrittsjahr 1996 Frau Huber zurückgeben.
- Einen Schritt weiter als die einfache Suche geht die Filterung der Tabelle. Dies bedeutet, dass nur noch diejenigen Zeilen angezeigt werden, die bestimmten Kriterien entsprechen. Beispielsweise enthielte eine Liste aller Mitarbeiter, die mehr als 4.000 € verdienen, nur noch Frau Huber und Herrn Juarez.
Darüber hinaus enthalten die meisten Einzeltabellendatenbanken je nach Verwendungszweck zahlreiche Formatierungsoptionen, um Eingabemasken oder ausdruckbare Berichte und Ähnliches zu erzeugen. Schließlich gibt es nicht allzu viele universelle Einzeltabellen-DBMS, sondern viel häufiger Programme, die für die Verwaltung einer bestimmten Datenart wie Adressen oder DVD-Sammlungen geeignet sind.
Die Grenzen der Einzeltabelle
Wenn Sie eine Weile mit einer Einzeltabellendatenbank arbeiten, werden Sie feststellen, dass vor allem eine Einschränkung besonders stört: Es gibt keine Möglichkeit, Inkonsistenzen auszugleichen. Wird beispielsweise die zuvor gezeigte Mitarbeitertabelle um fünf Kollegen erweitert, die alle in der Abteilung Verkauf arbeiten, dann gibt es keine Möglichkeit des Schutzes davor, dass der Name »Verkauf« in einem dieser fünf Datensätze falsch geschrieben wird. Daraus ergäbe sich natürlich eine vollkommen falsche Tabellenlogik mit Auswirkungen auf Such- und Filterfunktionen.
Noch schwieriger wird es, wenn Daten benötigt werden, die im Grunde gar nicht das Entity betreffen, das im Datensatz beschrieben wird, sondern zusätzliche Informationen über eines der anderen Felder enthalten. Beispielsweise könnten Sie es nützlich finden, neben der Abteilung auch deren Leiter zu erwähnen. Stellen Sie sich den Aufwand vor, wenn dieser Leiter wechselt, oder die Probleme, wenn Sie den Namen irgendwo falsch schreiben.
Einzeltabellen sind also nur für ganz einfache Anwendungszwecke geeignet: Eine kleine Adress- oder Briefmarkensammlungsverwaltung geht gerade noch, während sämtliche Unternehmensanwendungen nur mit relationalen Datenbanken vernünftig funktionieren. Diese ermöglichen es nämlich, dass Sie verschiedene Arten von Daten jeweils in eigenständigen Tabellen ablegen und sie anschließend über sogenannte Schlüssel miteinander verknüpfen.
12.1.2 Relationale Datenbanken
Genau wie Einzeltabellen verwenden auch relationale Datenbanken ein Tabellenmodell zum Ablegen von Daten. Eine relationale Datenbank besteht allerdings aus beliebig vielen Einzeltabellen, die auf vielfältige Weise miteinander verknüpft werden können. Dieser Aufbau sorgt dafür, dass die Daten in der Datenbank konsistent sind: Jede Information muss nur ein einziges Mal gespeichert werden, sodass es nicht zu Mehrdeutigkeiten kommen kann.
Technisch gesehen basieren relationale Datenbanken auf der relationalen Algebra. Danach wird eine einzelne Tabelle als Relation bezeichnet. Jeder Datensatz ist ein Tupel (geordnete Sammlung einer festgelegten Anzahl von Werten), in dem die Tabellenspalten die Attribute A1 bis An bilden. Das Relationenschema R = (A1, ..., An) legt Anzahl und Datentyp der Attribute fest. Eine Relation r(R) ist formal eine Relation mit dem Relationenschema R, besteht also aus Tupeln, für die gilt:
r(R) = r(A1, ..., An)
Die Verknüpfungen zwischen den Spalten einer Tabelle und zwischen den einzelnen Tabellen werden als Beziehungen oder Verknüpfungen (englisch: relationships) bezeichnet. Auch der Begriff Relationen kommt dafür häufig zum Einsatz, wenngleich er hier nichts mit Relationen im Sinne der relationalen Algebra zu tun hat. Eine Beziehung entsteht durch die Verwendung von Schlüsseln: Der Primärschlüssel des Datensatzes einer Tabelle wird als Wert in ein Feld einer anderen Tabelle eingetragen. Der Primärschlüssel ist ein spezielles Datenfeld oder eine Kombination der Werte mehrerer Felder, die innerhalb der Tabelle einen einmaligen Wert besitzen und den Datensatz somit eindeutig kennzeichnen. Der Primärschlüssel einer Tabelle, auf den in einer anderen Tabelle verwiesen wird, heißt dort Fremdschlüssel.
Der Primärschlüssel ist übrigens ein Sonderfall eines sogenannten Indexes. Indizes ermöglichen den schnellen Zugriff auf bestimmte Tabelleninhalte, indem sie die Informationen einer Datenbankspalte separat in geordneter Form abspeichern. Um einen Datensatz anhand eines indizierten Felds zu finden, muss nicht die gesamte Datenbanktabelle sequenziell durchsucht werden.
Es gibt drei Arten von Beziehungen, die je nach Art der gespeicherten Information nützlich sind:
- Eine 1:1-Beziehung (oft, erneut abweichend von der relationalen Algebra, auch 1:1-Relation genannt) verknüpft einen Datensatz einer Tabelle mit genau einem Datensatz einer anderen Tabelle. Dies ist immer dann nützlich, wenn bestimmte Informationsaspekte über ein Entity nicht so oft benötigt werden wie andere Aspekte. Die seltener oder in einem anderen Zusammenhang verwendeten Informationen lassen sich auf diese Weise einfach ausblenden. Beispielsweise könnte eine Tabelle Informationen über angebotene Artikel wie Bezeichnung, Preis und Mehrwertsteuersatz enthalten, eine andere dagegen den Lagerbestand.
- Eine 1:n-Beziehung oder Eins-zu-viele-Beziehung verbindet einen Datensatz einer Tabelle mit beliebig vielen Datensätzen einer anderen Tabelle. Dies ist der häufigste und nützlichste Verknüpfungstyp, weil er den größten Beitrag zur Vermeidung von Inkonsistenzen leistet: Detailinformationen über Werte, die in einer Spalte einer Tabelle beliebig oft vorkommen können, werden in einer separaten Tabelle erfasst. Die erste Tabelle enthält in dem entsprechenden Feld nur noch einen Verweis auf einen bestimmten Datensatz der zweiten Tabelle.
- Eine m:n-Beziehung, auch Viele-zu-viele-Beziehung genannt, kombiniert beliebig viele Vorkommen eines bestimmten Wertes mit beliebig vielen Vorkommen eines anderen. Stellen Sie sich beispielsweise eine Tabelle vor, die eine Liste lieferbarer Waren enthält, und eine weitere Tabelle, in der die Adressen von Kunden erfasst werden. Jeder Artikel kann von beliebig vielen Kunden gekauft werden, und jeder Kunde kann beliebig viele unterschiedliche Artikel kaufen. Das relationale Datenbankmodell verlangt allerdings, dass diese Art von Beziehung indirekt dargestellt wird: Eine dritte Tabelle listet die einzelnen Kaufaktionen auf; jeder Datensatz enthält dabei eine Verknüpfung zu einem bestimmten Kunden und eine weitere zu einem einzelnen Artikel. Jeder dieser beiden Fremdschlüssel für sich bildet eine 1:n-Beziehung; die m:n-Beziehung zwischen Kunden und Artikeln besteht nicht direkt.
Ein einfaches Beispiel
Das unter den m:n-Beziehungen angedeutete Beispiel soll im Folgenden konkret ausgeführt werden: Eine Tabelle enthält Daten über Käufer, die zweite Informationen über die Artikel, und die dritte Tabelle listet jeden einzelnen Kauf auf. Die Beziehung zwischen den drei Tabellen ADRESSEN, KAEUFE und ARTIKEL wird in Abbildung 12.1 dargestellt.
Abbildung 12.1 Relationen zwischen den Tabellen einer einfachen relationalen Datenbank
Das oberste, fett gesetzte Feld jeder Tabelle ist der Primärschlüssel. Die Tabelle ADRESSEN enthält die Kundendaten mit dem Primärschlüssel NR. ARTIKEL hat den Primärschlüssel ARTNR (Artikelnummer). Die Tabelle KAEUFE schließlich verwendet einen Primärschlüssel namens KAUFNR. Da keine andere Tabelle auf einzelne Käufe zugreift, benötigt die Tabelle momentan eigentlich keinen Primärschlüssel.
Die Beschriftungen an den kleinen Rauten, von denen die Beziehungen ausgehen, zeigen den Beziehungstyp an. Beide Beziehungen in der Datenbank sind 1:n-Beziehungen. Die m:n-Beziehungen zwischen den Tabellen ADRESSEN und ARTIKEL kann natürlich nicht eingezeichnet werden, weil sie nur indirekt besteht.
Konkret kann die Tabelle ADRESSEN zum Beispiel mit den Werten aus Tabelle 12.2 gefüllt werden.
NR | NAME | STRASSE | HAUSNR | PLZ | ORT |
1 |
Schmidt |
Kleiner Weg |
1 |
50678 |
Köln |
2 |
Müller |
Alte Str. |
78 |
80543 |
München |
3 |
Becker |
Störtebekerweg |
45 |
20567 |
Hamburg |
4 |
Heinze |
Grüne Allee |
36 |
10345 |
Berlin |
Natürlich müssen Sie die Kunden nicht durchnummerieren, sondern können sich Ihr eigenes individuelles Schema für Kundennummern ausdenken. Wichtig ist lediglich, dass jede dieser Nummern nur ein einziges Mal in der Tabelle vorkommt und dass jeder Kunde eine (eindeutige) Nummer bekommt.
Die Tabelle ARTIKEL enthält Informationen über die angebotenen Artikel (siehe Tabelle 12.3). Beachten Sie, dass das Feld MWST nicht etwa einen konkreten Wert enthält, sondern den Mehrwertsteuersatz, also den Wert 7 oder den Wert 19. Noch praktischer wären allerdings 1:1-Relationen zu einer weiteren Tabelle, die die konkreten Mehrwertsteuersätze enthält; schließlich können sich diese ändern. Die Preise werden aus im weiteren Verlauf näher erläuterten Gründen in Cent angegeben.
ARTNR | ARTNAME | PREIS | MWST |
1 |
Cola |
119 |
19 |
2 |
Vollmilch |
79 |
7 |
3 |
Toastbrot |
149 |
7 |
4 |
Zahnpasta |
179 |
19 |
Nachdem diese beiden Tabellen eingerichtet sind, können nun Käufe getätigt werden. In der Tabelle KAEUFE könnten etwa die folgenden Geschäftsvorfälle erfasst werden (siehe Tabelle 12.4):
KAUFNR | NR | ARTNR | STUECK | DATUM |
1 |
3 |
3 |
2 |
2009-04-15 |
2 |
2 |
1 |
4 |
2009-04-16 |
3 |
2 |
2 |
1 |
2009-04-16 |
4 |
1 |
4 |
1 |
2009-04-18 |
5 |
1 |
3 |
1 |
2009-04-18 |
Die Einträge in der Tabelle KAEUFE sind in dieser Form für Menschen so gut wie unlesbar. Es geht auch gar nicht darum, sie in einer Form zu verwahren, in der sie sofort lesbar sind, sondern darum, die Daten redundanzfrei und kompakt zu speichern. Für die lesbare Ausgabe beherrscht jedes relationale Datenbankverwaltungssystem (RDBMS, Relational Database Management System) sogenannte Auswahlabfragen, mit deren Hilfe Sie anhand der Relationen Daten aus verschiedenen Tabellen zusammenstellen können.
Tabelle 12.5 zeigt das Ergebnis einer solchen Auswahlabfrage. Hier werden die Käufe mit den eigentlichen Kunden- und Artikelnamen aufgeführt, alphabetisch nach Kunden und anschließend alphabetisch nach Artikelbezeichnungen sortiert. Damit Sie das Ergebnis nachvollziehen können, wird die Kaufnummer aus der Tabelle KAEUFE übernommen. Die letzte Spalte enthält den errechneten Gesamtpreis für jeden einzelnen Kauf (das Produkt aus Stückzahl und Einzelpreis).
Beachten Sie, dass die Ergebnisse von Auswahlabfragen normalerweise nicht abgespeichert werden. Schließlich basieren sie auf Daten, die sich durch die nachträgliche Änderung oder Ergänzung von Datensätzen in den zugrunde liegenden Tabellen jederzeit ändern können.
Die meisten relationalen Datenbanksysteme verwenden für Abfragen eine standardisierte Sprache namens SQL (Structured Query Language). Diese Abfragesprache wird in Abschnitt 12.3, » SQL-Abfragen«, vorgestellt.
Normalisierung
Das wichtigste Ziel beim Erstellen relationaler Datenbanken ist – wie bereits erwähnt – die Beseitigung von Redundanzen zur Vermeidung von Inkonsistenzen. Dieser Vorgang wird als Normalisierung der Datenbank bezeichnet. Insgesamt sind fünf, eigentlich sogar sechs sogenannte Normalformen definiert, die aufeinander aufbauen und schrittweise den Weg zu einem fertigen relationalen Datenbankmodell weisen:
- Die erste Normalform (1NF) verlangt, dass die Information in jedem Feld einer Datenbank atomar ist, das heißt eine nicht weiter zerlegbare Einzelinformation. »Einzelinformation« hängt allerdings vom Anwendungszweck ab: Ein Zustelldienst müsste Anschriften beispielsweise in all ihre Einzelteile zerlegen, während eine Anschrift als reine Endkundeninformation durchaus als Gesamtwert in einem einzelnen Feld stehen könnte. Verboten sind gemäß der 1NF insbesondere auch listenartige Wiederholungen gleichartiger Informationen – etwa mehrere Telefonnummern einer Person.
- Die zweite Normalform (2NF) fordert zusätzlich, dass Datensätze nur direkte Informationen über ein und denselben Sachverhalt enthalten. Formal gesagt dürfen alle Felder in einer Tabelle, die die zweite Normalform erfüllt, nur vom Primärschlüssel dieser Tabelle abhängen. Beispielsweise dürfte eine Person mit zwei Wohnsitzen nicht zweimal in eine Kundentabelle aufgenommen werden. In diesem Fall müssten die Wohnorte in eine separate Tabelle geschrieben werden; der Bezug auf die Kunden müsste in dieser Tabelle als Fremdschlüssel eingetragen werden.
- Die dritte Normalform (3NF) ist erfüllt, wenn alle Felder funktional unabhängig voneinander sind. Der Unterschied zur zweiten Normalform erscheint geringfügig. Eine Tabelle, die zwar die zweite, aber nicht die dritte Normalform erfüllt, belässt eine eindeutig zu einem bestimmten Feld gehörende Zusatzinformation innerhalb einer Tabelle, in der dieses Feld keinen Schlüssel bildet. Beispielsweise hat in der Personaltabelle einer Unternehmensdatenbank, in der in einem Feld die Abteilung eines Mitarbeiters steht, der Name des Abteilungsleiters nichts zu suchen, weil er nur von der Abteilung, aber nicht vom Mitarbeiter abhängt.
- Die Boyce-Codd-Normalform (BCNF), benannt nach Pionieren des relationalen Datenbankmodells, ist eine strengere Variante der dritten Normalform. Eine Tabelle, die sich in der dritten Normalform befindet, kann die BCNF verletzen, wenn der Primärschlüssel aus mehreren Feldern zusammengesetzt ist und der Wert irgendeines Felds nicht vom gesamten Primärschlüssel, sondern nur von einem seiner Felder abhängt. Um die Boyce-Codd-Normalform zu erreichen, muss eine solche Tabelle in zwei Einzeltabellen aufgeteilt werden, die jeweils eines dieser Felder als Primärschlüssel aufweisen.
- Die vierte Normalform (4NF) betrifft sogenannte mehrwertige Abhängigkeiten (multi-valued dependencies). Eine mehrwertige Abhängigkeit liegt vor, wenn eine Beziehung
zwischen verschiedenen Informationen nicht so in zwei Tabellen unterteilt werden kann,
dass eine 1:n- oder die umgekehrte n:1-Relation entsteht.
Angenommen, in einer zweispaltigen Tabelle werden durch einen Fremdschlüssel Personen referenziert und in der zweiten Spalte durch einen weiteren Fremdschlüssel die von diesen Personen verwendeten Betriebssysteme. Da eine Person mehrere Betriebssysteme einsetzen kann, kann sowohl jede Person als auch jedes Betriebssystem mehrmals vorkommen.
Die vierte Normalform wird verletzt, sobald eine weitere Spalte hinzukommt, die beispielsweise die von diesen Personen beherrschten Programmiersprachen auflistet: In diesem Fall entstehen Redundanzen durch die mehrfache Nennung der Betriebssysteme und Programmiersprachen für denselben Benutzer. Eine andere Ausprägung wären beliebige, nicht zusammenhängende Paare von Betriebssystem und Programmiersprache. Wenn sich die Anzahl der von einer Person verwendeten Betriebssysteme und der Programmiersprachen unterscheidet, bleiben sogar Felder leer.
Tabelle 12.6 zeigt schematisch, wie dies aussieht. Die Lösung besteht natürlich darin, eine solche Tabelle in zwei Einzeltabellen zu unterteilen, deren Primärschlüssel jeweils die Person ist.
- Die fünfte Normalform (5NF) erfordert schließlich, dass innerhalb einer Tabelle nur
triviale Join-Abhängigkeiten existieren dürfen. Eine Join-Abhängigkeit besteht in
jeder Tabelle, die sich in mehrere Einzeltabellen aufteilen ließe, indem derselbe
Schlüssel jeweils auf einzelne Spalten der Tabelle angewandt wird. Trivial ist eine
Join-Abhängigkeit dann, wenn durch eine Verknüpfung zweier solcher Einzeltabellen
keine Redundanz durch einen verdoppelten Datensatz vorkäme.
Wenn Sie beispielsweise zwei Tabellen vereinigen, von denen die eine einzelne Personen und deren Wohnort und die andere dieselben Personen und deren Bundesland auflistet, würde auch die entstehende Join-Tabelle die fünfte Normalform erfüllen, da jede Person in genau einem Ort und genau einem Bundesland wohnt.
Ein Join der Wohnorte-Tabelle und einer Tabelle, in der jede Zeile eine Person und eine ihrer Telefonnummern enthält, verletzt die fünfte Normalform dagegen: Da eine Person mehrere Telefonnummern besitzen kann, würde ihr Wohnort mehrfach genannt. Diese Informationen müssen also getrennt voneinander gespeichert bleiben.
Die Bezeichnung Normalisierung könnte als kontinuierlicher Prozess missverstanden werden, der auf eine bereits bestehende Datenbank angewendet wird. In Wirklichkeit müssen Sie sich bereits bei der Datenbankmodellierung Gedanken darüber machen, also bevor Sie eine Datenbank in der Praxis einrichten.
Transaktionen
Ein fortgeschrittenes Feature relationaler Datenbanksysteme ist die Unterstützung von Transaktionen. Es handelt sich um die Möglichkeit, ein »Paket« aus beliebig vielen Änderungen in der Datenbank insgesamt zu bestätigen (Commit) oder rückgängig zu machen (Rollback).
Stellen Sie sich zur Verdeutlichung ein Online-Einkaufssystem vor: Ein Kunde kann beliebig viele Artikel zum Warenkorb hinzufügen und wieder daraus entfernen. Zum Schluss kann er die ausgewählten Waren bestellen oder den gesamten Vorgang abbrechen. Transaktionen sind die ideale Lösung für solche Aufgaben: Sobald der Kunde auf das System zugreift, wird eine neue Transaktion gestartet. Daraufhin merkt sich das Datenbanksystem alle Bewegungen im Warenkorb und alle sonstigen Einstellungen. Kommt es zu einer Bestellung, wird der Commit der Transaktion durchgeführt; bei einem Abbruch erfolgt dagegen der Rollback.
Da die Transaktionsfähigkeit die Performance eines RDBMS beeinträchtigt, handhabt der in Abschnitt 12.2 behandelte MySQL-Server sie auf pragmatische Weise: Er bietet unterschiedliche Tabellentypen an; die neueren InnoDB-Tabellen unterstützen Transaktionen, während die klassischen MyISAM-Tabellen schneller verarbeitet werden.
RDBMS-Arten
Da relationale Datenbankverwaltungssysteme das verbreitetste Datenbankmodell sind, gibt es eine riesige Menge von Produkten, die diesem Standard entsprechen. Man kann sie grob in folgende Gruppen unterteilen:
- Desktopdatenbanken sind Datenbankanwendungen, die für die Datenverwaltung am Einzelplatz oder in kleinen Arbeitsgruppen geeignet sind. Sie bieten in der Regel eine grafische Benutzeroberfläche, die die Tabellen und Abfragen übersichtlich und einfach darstellt, und ermöglichen das einfache Erzeugen von Eingabemasken und ausdruckbaren Berichten. Bekannte Beispiele für Desktop-Datenbanksysteme sind das in der Microsoft-Office-Familie integrierte Programm Access, OpenOffice.org Base oder die aus dem Mac-Bereich stammende und inzwischen auch für Windows verfügbare Datenbank FileMaker.
- Kommerzielle Datenbankserver werden insbesondere für verteilte Unternehmensanwendungen eingesetzt. Es handelt sich um komplexe und sehr teure modular erweiterbare Systeme. Bekannte Beispiele sind Oracle, Microsoft SQL Server oder IBM DB2. Im erweiterten Sinn gehören auch Branchenlösungen oder Warenwirtschaftssysteme wie SAP ERP dazu, weil sie alle auf speziell angepassten Datenbanken basieren.
- Freie Datenbankserver sind eine günstige Alternative zu den kommerziellen Produkten. Die bekanntesten Open-Source-Datenbanksysteme sind das in Abschnitt 12.2 vorgestellte MySQL sowie PostgreSQL.
12.1.3 Objektorientierte Datenbanken
Trotz der soeben besprochenen Normalisierung lassen sich gewisse komplexe Datenstrukturen nur unzureichend mithilfe einer relationalen Datenbank modellieren. Aus diesem Grund wurde das objektorientierte Datenbankmodell eingeführt, das eine völlig freie und beliebige Strukturierung der Daten ermöglicht. Eine objektorientierte Datenbank besteht aus Klassen und Objekten und ähnelt damit der objektorientierten Programmierung, die in Kapitel 9, »Grundlagen der Programmierung«, erläutert wird.
Ein gutes Beispiel für ein Gefüge, das sich durch relationale Modellierung nicht vernünftig darstellen lässt, wären Verbindungen und Entfernungen zwischen verschiedenen Orten, wie sie beispielsweise für ein Speditionsunternehmen benötigt werden. Tabelle 12.7 unternimmt dennoch den Versuch, diese Informationen nach relationalem Muster darzustellen.
Diese Tabelle ist aus verschiedenen Gründen ungeeignet. Erstens enthalten zwei Spalten Informationen der gleichen Art; es gibt kein Kriterium, das bestimmt, welche Stadt unter VON_ORT aufgeführt wird und welche unter NACH_ORT. Die Darstellung der Entfernung in beide Richtungen ist auch keine Alternative, weil es dadurch zu Redundanzen käme. Durch die Normalisierungsregeln für relationale Datenbanken lässt sich dieses Modell nicht weiter verbessern.
Übrigens ist es auch keine Lösung, die durchaus relational darstellbaren Entfernungen von einer bestimmten Stadt zu allen anderen zu verwenden. Dies verhindert nämlich die Aufnahme günstigerer Verbindungen in die Datenbank. Angenommen, eine Tabelle listet die Entfernungen von Köln zu den anderen Städten auf. Sicherlich würde niemand, der von Hamburg nach Berlin muss, den Umweg über Köln wählen.[Anm.: Obwohl ich allen Hamburgern versichern kann, dass es sich lohnen würde ;-).]
Mithilfe der objektorientierten Modellierung ist die Darstellung dieser Entfernungen dagegen ein Leichtes. Hier lässt sich eine Klasse namens Ort einrichten, die einfach ein Array von Zielen enthält, zu denen Verbindungen bestehen.
Es gibt verschiedene Sprachen, in denen sich objektorientierte Datenbanken formulieren lassen. Einige Lösungen verwenden die Syntax objektorientierter Programmiersprachen wie C++, während andere Systeme ihre eigenen Sprachen benutzen. Einen allgemeinen Standard für objektorientierte Datenbankverwaltungssysteme (OODBMS), wie ihn SQL für relationale Datenbanken bildet, gibt es noch nicht. Dennoch arbeitet ein Gremium namens Object Database Management Group (ODMG) an einer solchen Standardisierung. Eine einigermaßen verbreitete Objektmodellierungssprache ist die von dieser Gruppe definierte Object Definition Language (ODL).
Eine übergeordnete Datenstruktur, am ehesten vergleichbar mit einer Tabelle in einer relationalen Datenbank, wird durch eine Klasse gebildet, deren Definition das Schlüsselwort class einleitet. Eine Informationskategorie, die in etwa einer Spalte in einer relationalen Datenbanktabelle entspricht, wird durch das Schlüsselwort attribute, die Angabe eines Datentyps und eine Bezeichnung eingerichtet. Das folgende Beispiel entspricht der zuvor dargestellten relationalen Tabelle ADRESSEN:
class Adressen {
attribute long Nr;
attribute string Name.;
attribute string Strasse;
attribute short Hausnr;
attribute short Plz;
attribute string Ort;
}
Die atomaren Datentypen string, long und short sollten sich von selbst erklären. Es existieren keine separaten Typen für ganzzahlige und für Fließkommazahlen. Eine objektorientierte Umsetzung der Tabelle ARTIKEL sieht folgendermaßen aus:
class Artikel {
attribute long ArtNr;
attribute string ArtName;
attribute long Preis;
attribute short MWSt;
}
Eine Beziehung wird in der ODL durch das Schlüsselwort relationship dargestellt. Da jeder Datensatz eine Instanz einer Klasse ist, müssen Sie nicht mit Schlüsseln arbeiten, sondern können ein Objekt dieser Klasse direkt referenzieren. Die Darstellung der Tabelle in einer OO-Datenbank lautet demnach:
class Kaeufe {
attribute long KaufNr;
relationship Adressen Kunde;
relationship Artikel Ware;
attribute short Stueck;
attribute struct Datum {
short Tag;
short Monat;
short Jahr;
} KaufDatum;
}
Der Datentyp struct bietet die Möglichkeit, eine nichtatomare Information als verschachtelte Gruppe einzufügen. Dies garantiert im vorliegenden Fall die leicht handhabbare Darstellung eines Datums. Die Syntax für struct entspricht dabei dem in der Programmiersprache C üblichen Standard: Vor der öffnenden geschweiften Klammer steht der Datentypname der Struktur, hinter der schließenden wird ein konkretes Element dieses Typs deklariert.
Die ursprüngliche Aufgabe, die Entfernungstabelle darzustellen, lässt sich nun mithilfe der ODL-Syntax recht einfach lösen:
class Ort {
attribute string Name.;
struct Entfernung {
relationship Ort Zielort;
attribute short Kilometer;
};
array (struct Entfernung) Entfernungen;
}
Ein array ist – wie in Programmiersprachen – eine Liste beliebig vieler Elemente eines bestimmten Datentyps. In diesem Fall wird eine Entfernung als Struktur aus einer Verknüpfung mit einem Ort und der Kilometeranzahl gebildet. Die entsprechenden Entfernungen werden in einem Array dargestellt.
Um objektorientierte Datenstrukturen mit Werten zu füllen und um diese Werte später nach verschiedenen Kriterien zu lesen und auszuwerten, wird eine zweite Sprache benötigt. Die von der ODMG vorgeschlagene Version einer solchen objektorientierten Abfragesprache heißt OQL (Object Query Language). Sie verwendet weitgehend dieselben Befehle und die gleiche Syntax wie die in Abschnitt 12.3 vorgestellte relationale Abfragesprache SQL.
Ihr Kommentar
Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.