Freitag, 6. März 2015

Datenbanken entwickeln lernen


Datenbanken entwickeln
Die Entwicklung einer DB vollzieht sich in mehreren Schritten.
Zunächst ist festzustellen, welche Informationen die Anwender vom DBS erwarten. Aufgrund dieser Erhebung kann man sich dann überlegen, welche Tabellen benötigt werden.
Ferner muß festgelegt werden, welche Datentypen für die einzelnen Tabellenspalten benötigt werden. Diesen Prozeß bezeichnet man als Datenmodellierung. Erst wenn die Datenmodellierung abgeschlossen ist, können die Tabellen angelegt werden. Man sollte sich für diesen Schritt ruhig ein wenig Zeit nehmen, weil es nachher häufig unmöglich ist, ohne großen Aufwand Fehler zu beheben.
Um sich einigen Ärger zu ersparen, empfiehlt es sich, ein paar Grundsätze bei der Datenmodellierung zu beachten:
Keine Redundanz Unter Redundanz versteht man das doppelte Vorhandensein einzelner Daten.
Beispiel: Vor-/Nachname Vorname Straße
Hans Maier Hans Musterstr. 5
Michael Meier Michel Michelweg99
Wie man leicht erkennen kann, kommt der jeweilige Vorname in zwei Spalten vor.
Dies bringt zwei Nachteile mit sich: Zum einen kostet es mehr Speicherplatz, was bei einigen 1000 Datensätzen schon etwas ausmacht; zum anderen werden Änderungen schwieriger, anfälliger für Fehler und auch aufwendiger, da ja zwei Attribute geändert werden müssen. Wenn dies nicht erfolgt, treten Inkonsistenzen auf.

Ein DBMS verfügt nicht über einen definierten Zugriffsweg auf einen bestimmten Datensatz. Deshalb muß in jeder Zeile einer Tabelle ein Wert enthalten sein, der diesen Eintrag eindeutig kennzeichnet bzw. identifiziert. Um die Eindeutigkeit der Tabellenzeilen zu gewährleisten, erweitert man den Datensatz um ein Identifikationsmerkmal, z.B. wird einem Artikeldatensatz eine Artikelnummer zugeordnet.
Dieses Merkmal nennt man Schlüssel. Beim Festlegen des Schlüssels kann man einen Schlüssel selbst definieren oder einen fremddefinierten übernehmen. Bei einem Buch würde sich da die ISBN-Nummer anbieten. Um nicht Gefahr zu laufen, daß durch eine Änderung solcher fremddefinierten Schlüssel im DBS Inkonsistenzen auftreten, zum Beispiel, weil der Schlüssel nicht mehr eindeutig ist, empfiehlt es sich häufig, einen eigenen zu nehmen.
Prozeßdaten sind Daten, die durch einen Rechenprozeß aus gespeicherten Attributen gewonnen werden.
Beispiel: Neben dem Geburtsdatum wird auch noch das Alter gespeichert. Spätestens nach einem Jahr ist dieser Eintrag falsch
Deshalb sollten diese Daten bei jeder Abfrage neu errechnet werden.
Eine Möglichkeit ist, erst einmal darüber nachzudenken, was man eigentlich machen will, dann die entsprechenden Prozeduren entwickeln und dabei sehen, welche Art von Daten man braucht. Diese Vorgehensweise kennen diejenigen, die schon einmal programmiert haben.
Andererseits kann man sich auch zuerst überlegen, welche Daten überhaupt anfallen und wie diese am besten organisiert werden. Anschließend kann man sich dazu die entsprechenden Funktionen ausdenken. Da Datenbanken in der Regel zum Speichern von Daten gedacht sind, empfiehlt sich letztere Vorgehensweise; man sollte aber trotzdem die benötigten Funktionen nicht aus dem Auge verlieren.
Als erstes muß man feststellen, welche Daten gebraucht werden bzw. anfallen und wie diese organisiert werden sollen. Im nächsten Schritt ist zu überlegen, ob alle Anforderungen realisierbar sind.
Um die benötigten Tabellen zu entwickeln, gibt es für einfache DBs im Prinzip zwei Möglichkeiten: Entweder stur nach Schema-F über die fünf Normalformen oder etwas intuitiver über das ER-Modell
Erst wenn man größere DBs entwickelt, muß man mit beiden Möglichkeiten gleichzeitig arbeiten. Das heißt, erst mit dem ER-Modell eine Grundstruktur festlegen und diese dann mit den fünf Normalformen überprüfen. .
Komponenten eines Datenbanksystems Eine Datenbank (DB, engl. Database) ist eine systematische Sammlung von Daten. Zur Nutzung und Verwaltung der in der DB gespeicherten Daten benötigt der Anwender ein Datenbank-Verwaltungssystem (DBMS, engl. Database Management System).Die Kombination aus DB und DBMS ist das Datenbanksystem (DBS, engl.: Database System), das jedoch häufig fälschlicherweise als Datenbank bezeichnet wird.
Ebenen eines Datenbanksystems sind Betriebssystem/Hardware als die unterste Ebene, auf der jede Computeranwendung basiert. Neben dem DBS bauen auch alle anderen Programme auf dieser Ebene auf.
Auf der internen Ebene erfolgt die physische Speicherung der Daten. Die Speicherlogik, die dabei verwendet wird, hängt vom DBMS ab und kann dem Entwickler ziemlich egal sein, da er lediglich über die konzeptionelle Ebene auf die DB zugreift.Den Anwender braucht weder die interne noch die konzeptionelle Ebene zu kümmern, da er erst über die oberste, nämlich die externe Ebene auf die DB zugreift.
Auf der dritten, der konzeptionellen Ebene, wird das Datenmodell beschrieben.Unter einem Datenmodell versteht man die datenmäßige Abbildung eines bestimmten Ausschnitts der realen Umwelt. Im Datenmodell sind die Strukturen der Daten und ihre Beziehung zueinander festgelegt. Nach der Art, wie die Beziehungen in dem Datenmodell geregelt werden, unterscheidet man zwischen hierarchischen, vernetzten und relationalen Datenmodellen.
Beim relationalen Datenmodell werden die Daten in zweidimensionalen Tabellen angeordnet.Jede Tabelle hat einen eindeutigen Relationsnamen. Alle Zeilen der Tabelle werden als Relation, jede einzelne Zeile davon als Datensatz, die Spaltenüberschriften als Attributnamen oder Attribute und alle Attributnamen zusammen werden als Relationsschema bezeichnet.
Beispiel:
MNr AbtNr Name GebDat Telefon
Damit man jede Zeile gezielt ansprechen kann, wird ein Schlüsselattribut eingeführt. Der Schlüssel muß immer eindeutig sein und wird auch als Primärschlüssel bezeichnet. Der Primärschlüssel muß nicht immer aus nur einem Attribut bestehen. Es ist auch möglich, mehrere Attribute zusammen als (zusammengesetzten) Primärschlüssel zu verwenden. Teilweise hat man in einer Relation mehrere Attribute, die eindeutig sind, d.h. Schlüssel sein könnten; in diesem Fall werden die anderen Attribute als Schlüsselkandidaten bezeichnet. Oder anders herum: Jeder Schlüsselkanditat kann jederzeit als Primärschlüssel benutzt werden. Es kann aber für eine Tabelle immer nur einen Primärschlüssel gleichzeitig geben.
Die fünf Normalformen
Ein Relationstyp ist in der 1. Normalform, wenn alle Attribute maximal einen Wert haben. Am Kreuzungspunkt einer Spalte mit einer Reihe darf also maximal ein Datenwert stehen. Das Nichtvorhandensein von Daten ist zulässig.
Ein Beispiel:
Es sollen alle Bestellformulare eines Versandhandels in einer Datenbank gespeichert werden. Eine einzelne Bestellung enthält die Kundennummer, das Datum, die Auftragsnummer und natürlich die bestellten Artikel sowie deren Anzahl. Um die Wiederholungsgruppen zu vermeiden, werden zwei gesonderte Tabellen erstellt.Jetzt ist aber die Zuordnung verloren gegangen. Wer hat welche(n) Artikel bestellt? Dieses Problem ist einfach zu lösen. müssen wir nur festhalten, welche Artikel zu welcher Bestellung gehören. Da die AuftragNr eindeutig ist, nehmen wir diese als Primärschlüssel für `Auftrag`. Nun fügen wir noch diese Spalte entsprechend ihrer Werte der Relation `best. Artikel` hinzu, und schon haben wir wieder unsere Zuordnung.
In dieser Konstellation wird die Spalte `AuftragNr` in `best. Artikel` als Fremdschlüssel bezeichnet. Jede Zeile muss eindeutig ansprechbar sein. Wie aber ist das in unserem Fall der bestellten Artikel zu erreichen?
Nun, die AuftragNr und die ArtikelNr kommen zwar mehrfach vor, trotzdem ist die Lösung aber ganz einfach: Die Kombination aus AuftragNr und ArtikelNr muß eindeutig sein. Wenn wir also diese Kombination wählen, ist die o.g. Forderung erfüllt. Diese Kombination wird als ,zusammengesetzter Primärschlüssel` bezeichnet.
Die 2. Normalform Ein Relationstyp ist in der 2. Normalform, wenn er in der 1. Normalform ist und jedes Attribut vom gesamten Primärschlüssel abhängt. Relationstypen, die in der 1. Normalform sind, sind automatisch in der 2. Normalform, wenn ihr Primärschlüssel nicht zusammengesetzt ist.
Ein kleines Beispiel:
Neben der AuftragNr, der ArtikelNr und der Menge soll auch der Hersteller des Artikels gespeichert werden.In diesem Beispiel ist das Attribut `Hersteller` nur vom Teilschlüssel `ArtikelNr` und nicht auch von `AuftragNr` abghängig. Damit die Relation der 2. NF genügt, muß das Attribut `Hersteller` aus der Relation herausgenommen und der (neuen) Relation Artikel zugeordnet werden.
Die 3. Normalform ist erfüllt, wenn die 2. Normalform erfüllt ist und die Nicht-Schlüssel- Attribute funktional unabhängig voneinander sind. Sind A und B Attribute eines Relationstyps, so ist B funktional abhängig von A, wenn für jedes Vorkommen ein und desselben Wertes von A immer derselbe Wert von B auftreten muß.
Eine funktionale Abhängigkeit kann auch von einer Gruppe von Attributen bestehen. [3]
Ein Beispiel:
Zu den einzelnen Artikeln sollen die ArtikelNr, die Bezeichnung, der Hersteller und die HerstellerNr gespeichert werden. Als Primärschlüssel wird die ArtikelNr verwendet.
Die Tabelle `Artikel` wird in die beiden Tabellen `Artikel` und `Hersteller` aufgespalten.
Die 4. Normalform ist erfüllt, wenn die 3. Normalform erfüllt ist und wenn keine paarweise auftretenden mehrwertigen Abhängigkeiten vorhanden sind. Sind A, B und C Attribute eines Relationstypes, so ist C mehrwertig abhängig von A, falls für jeden Wert von A für alle Werte von B, die zusammen mit diesem Wert von A auftreten, jeweils die gleiche Wertemenge von C auftreten muß. Für verschiedene Werte von A können unterschiedliche Wertemengen von C auftreten. Bei Verstoß gegen die 4. Normalform können ,,Gruppeninkonsistenzen`` auftreten.
In der Relation Disposition sind folgende Informationen festgehalten: der Lagerort für jeden Artikel Aufträge, in denen ein Artikel vorkommt.Es soll nicht ausgesagt werden, aus welchem Lager der Artikel für einen Auftrag kommt. text=Folgende mehrwertige Abhängigkeiten liegen vor: `Lager` ist mehrwertig abhängig von `ArtikelNr : Für jeden Artikel muß für alle Aufträge, für die der Artikel bestellt ist, jeweils die gleiche Gruppe von Lagern auftreten. `AuftragNr` ist mehrwertig von `ArtikelNr` : Für jeden Artikel muß für alle Lager, in denen der Artikel aufbewahrt wird, jeweils die gleiche Gruppe von Aufträgen auftreten.
Damit die Relation der 4. NF genügt, muß sie in zwei neue Relationen (Artikel-Lager und Artikel- Auftrag) aufgespalten werden. Die erste Relation beschreibt, in welchem Zusammenhang Artikel und Lager stehen; die zweite den Zusammenhang zwischen Artikel und Auftrag.
Ein Relationstyp ist in der 5. Normalform, wenn er in der 4. Normalform ist und er sich unter keinen Umständen durch Kombination einfacherer Relationstypen mit unterschiedlichen Schlüsseln bilden läßt. Denormalisierung der Tabellen Im Prinzip kann man die Tabellen, die man nach den fünf Normalisierungen erhalten hat, 1:1 in der DB verwenden. Es ist jedoch zu prüfen, ob man in der Normalisierungswut die Tabellen nicht zu sehr auseinandergerissen hat. Tabellen, die denselben Primärschlüssel haben, können ohne weiteres zusammengelegt werden, ohne gegen eine Normalisierungsform zu verstoßen. Bei umfangreichen Datenbeständen mit hohen Zugriffszahlen empfiehlt sich jedoch, aus Performancegründen wieder eine gewisse Denormalisierung herzustellen.

SQL
CREATE TABLE
Als erstes müssen wir natürlich die Tabellen erstellen. Dazu dient der Befehl CREATE TABLE.
Die Syntax lautet: CREATE TABLE table_name (create_definition,...) Für table_name ist selbstverständlich der Name der zu erstellenden Tabelle einzusetzen. Die drei Punkte hinter `create_definition` bedeuten, daß mehrere `create_definition`s durch Kommas getrennt hintereinander stehen können.
• Die `create_definition`s müssen innerhalb der runden Klammern stehen! Für `create_definition` kann man folgendes einsetzen:
• Feld-Name Typ [NOT NULL]
• [AUTO_INCREMENT]
• [UNIQUE]
• [PRIMARY KEY] oder PRIMARY KEY (Feldname,...) oder UNIQUE (Feldname,...) oder FOREIGN KEY (Feldname,...)
• Mit NOT NULL wird festgelegt, daß ein Wert (das kann auch ein leerer sein) eingetragen werden muß. NULL ist nicht mit der Zahl 0 zu verwechseln; NULL bedeutet einfach ,,kein Wert``.

• Wenn bei INSERT kein Wert für dieses Feld angegeben wurde, wird der Standardwert genommen. Es gibt keine Fehlermeldung (nur mySQL)! Wenn ein Zahlenfeld mit dem Schlüsselwort AUTO_INCREMENT angelegt wurde, wird, solange kein Wert für dieses Feld angeben wurde, der höchste Wert +1 genommen.

• AUTO_INCREMENT kann nur einmal pro Tabelle in einem Primärschlüsselfeld verwendet werden. AUTO_INCREMENT gibt es nur in mySQL. Wenn UNIQUE bei einem Feld angegeben wurde, darf ein Wert in maximal einem Tupel vorkommen, d.h. jeder Wert muß eindeutig sein. Bei Primärschlüsseln wird automatisch UNIQUE angenommen.

• Mit PRIMARY KEY wird der Primärschlüssel festgelegt. Bei zusammengesetzten Primärschlüsseln sind alle Felder, die Teil des Schlüssels sind, anzugeben. Primärschlüssel müssen eindeutig sein und es muß NOT NULL angegeben werden.

• UNIQUE und PRIMARY KEY können entweder direkt hinter einer Spaltendefinition angegeben werden oder getrennt davon. Sobald erst eine Kombination mehrerer Spalten den Primärschlüssel bildet, d.h. eindeutig ist, muß der Primärschlüssel getrennt angegeben werden. Mit FOREIGN KEY wird die Fremdschlüsselbeziehung angegeben. mySQL unterstützt bis jetzt noch keine Fremdschlüssel und ignoriert folglich die Angaben.

Funktionen
• Bei select_expression und where_expression können neben Konstanten und Spaltenwerten auch Funktionen verwendet werden.
• Mathematische Funktionen Es können nicht nur Spaltennamen angegeben werden, sondern auch mathematische Rechenoperation mit Spalten und/oder Konstanten.
• + - * / % addieren/subtrahieren/multiplizieren/dividieren

• (ganzzahliger Rest) ABS() Betrag von COS() Cosinus in rad DEGREES() Umrechnung von rad in deg (Grad) MOD() Modulo (ganzzahliger Rest) PI() die Zahl Pi POW(X,Y) rechnet X hoch Y aus RAND() liefert eine Zufallszahl zwischen 0 und 1 ROUND() rundet Wert ROUND(x,n) rundet Wert von x auf n Stellen SQRT() Wurzel (2. Grades) TRUNCATE(x,n) schneidet nach n Kommastellen von x ab
• Logische Operatoren und Logische Funktionen
• NOT ! logisches NOT. Gibt 1 zurück, wenn das Argument 0 ist, sonst 0. Ausnahme:
• NOT NULL gibt NULL zurück.
• AND && logisches UND. Gibt 0 zurück, wenn eines der Argumente 0 oder NULL ist, sonst 1.
• OR || logisches ODER. Gibt 1 zurück, wenn eines der Argumente nicht 0 und nicht NULL ist, sonst 1.
• PASSWORD(str) verschlüsselt den Klartext
DROP TABLE Da wir jetzt wissen, wie wir Tabellen erstellen, ist es auch wichtig zu wissen, wie wir sie wieder loswerden. Dies geschieht mit dem Befehl DROP TABLE. Die Syntax lautet: DROP TABLE table_name

INSERT INTO Tabellen ohne Daten haben eigentlich keinen Sinn. Deshalb wollen wir mit dem Befehl INSERT INTO ein paar Daten einfügen. Die Syntax lautet: INSERT INTO table_name [ (feld_name,...) ] VALUES (werte,...) Die Feldnamen können weggelassen werden, wenn in alle Felder etwas eingefügt werden soll. In diesem Fall muß man aber die Werte in genau der Reihenfolge eingeben, wie die Felder in der CREATE TABLE Anweisung definiert wurden.

In der Regel, vor allem aber in Programmen, empfiehlt es sich, die Feldnamen anzugeben, weil man sich nie darauf verlassen sollte, daß sich die Reihenfolge der Spalten nicht ändert.

Bei den Werten müssen Zeichenketten und Datum in Hochkommata (Anführungszeichen) stehen, nur für Zahlen gilt das nicht

Um die Datenbasis für unser Beispiel in die DB einzutragen, wird der Befehl noch ein paarmal benutzt.

SELECT
Der Befehl SELECT ist der mächtigste Befehl in SQL.
Die Grund-Syntax lautet: SELECT [DISTINCT | ALL] select_expression,... FROM tables ... [WHERE where_definition] [GROUP BY feld,...] [ORDER BY feld [ASC | DESC] ,...] [LIMIT [offset,] rows]
Die kürzestmögliche SELECT-Anweisung lautet: SELECT * FROM table

DISTINCT und ALL sind exklusive, optionale Parameter; soll heißen, es kann immer nur einer, muß aber keiner benutzt werden.
DISTINCT sorgt dafür, daß jede identische Zeile nur einmal ausgegeben wird.
Mit ALL werden die sich wiederholenden Werte auch mehrmals ausgegeben.
Ohne Parameter verhält sich das DBMS normalerweise, als ob man ALL angeben würde.
Für select_expression muß eingesetzt werden, was angezeigt werden soll. Im einfachsten Fall ist das ein `*`.
Damit wird einfach alles angezeigt. Im Normalfall werden die benötigten Spalten durch Kommas getrennt angegeben. Sobald die Spaltennamen nicht mehr eindeutig sind, weil mehrere Tabellen angegeben wurden, muß der Tabellenname, gefolgt von einem Punkt, vorangestellt werden; es können dabei auch sog. Aliases verwendet werden.
Neben den reinen Spaltenwerten können auch Werte, die aus den Spaltenwerten berechnet oder durch sonstige Funktionen erstellt wurden, ausgegeben werden.
Alias bedeutet so viel wie ein ,,anderer Name``. Man kann sowohl für Spalten als auch für Tabellen Aliase definieren. Tabellen-Alias Tabellen-Aliase können sowohl bei der select_expression als auch bei der `where_definition` zur eindeutigen Spaltenbeschreibung anstelle des Tabellennamens verwendet werden. Aliases werden verwendet, weil sie in der Regel kürzer sind als der Spaltenname. Aliases werden bei tables mit einer Leerstelle getrennt hinter dem Tabellennamen eingegeben.
LIKE
wird verwendet bei Jokerzeichen
> SELECT Name -> FROM Firmen -> WHERE Telefon LIKE '%96/%';
Es existieren zwei Jokerzeichen: % und * steht für eine beliebige (auch 0) Anzahl beliebiger Zeichen
? steht für genau ein beliebiges Zeichen
BETWEEN
Er tut das, was man von ihm erwartet: er wählt alle Spalten aus, die zwischen dem oberen und unteren Wert liegen.
> SELECT * FROM Firmen-> WHERE StrNr BETWEEN 2 AND 5;
BETWEEN kann bei Textspalten, Datumsspalten und numerischen Spalten verwendet werden.
where_definition
Da es nicht immer sinnvoll ist, alle Zeilen auszugeben, kann man über die `where_definition` angeben, welche Bedingungen erfüllt sein müssen, damit die Zeile ausgeben wird. Die `where_definition` wird auch beim Löschen (DELETE) und Ändern (UPDATE) gebraucht. Eine Bedingung kann aus mehreren Teilbedingungen, die mit AND und OR verknüpft werden müssen, bestehen. Eine Teilbedingung besteht aus einem Spaltennamen, einem Operator sowie entweder einer Konstanten, einer weiteren Spalte oder einer Funktion. Die Teilbedingungen können auch mit NOT verneint werden.
Als Operatoren stehen die Vergleichsoperatoren sowie die Operatoren `LIKE`, `BETWEEN` zur Auswahl.
Bei Vergleichen mit Strings (=VARCHAR) wird im Normalfall nicht auf die Groß-/Kleinschreibung geachtet. Wenn man jedoch unterscheiden will, so muß beim Anlegen der Tabelle bei VARCHAR die Option BINARY angegeben werden.