Relationale Datenbanken und SQL

Dieser Vortrag soll all denen, die noch nicht viel von Datenbanken und SQL gehört haben, einen Einstieg in das Thema geben. Für alle gelernten Mathematiker bzw. Informatiker ist das sicher ein alter Hut.

Datenbanken und Datenbankanwendungen sind heute sicher die Hauptanwendung von Computern überhaupt. Daten sind ein wichtiger Aktivposten von Unternehmen. Es gibt Unternehmen (z.B. Banken), für die der Ausfall der zentralen Datenbank über ein bis zwei Tage den sofortigen Konkurs bedeuten würde.

Datenbanksysteme ermöglichen die Anwendungsübergreifende Nutzung von Daten und isolieren Anwendungsprogramme von Hardware und Betriebssystem.

Inhalt

1. Definition einiger Begriffe

1.1 Datenbank

Eine Datenbank ist eine einheitlich beschriebene Darstellung eines Ausschnitts der Realität mittels diskreter Daten auf externen und persistenten Speichermedien (typischerweise Festplatten).

Die Daten können nur über das Datenbank-Management-System (DBMS) eingefügt, gelesen, geändert oder gelöscht werden.

Struktur, Operationen und Konsistenzregeln werden durch ein Datenmodell beschrieben.

1.2 Datenbank-Management-System (DBMS)

Softwaresystem, das die einheitliche Beschreibung und sichere Bearbeitung einer Datenbank ermöglicht. Das DBMS garantiert Korrektheit der Daten (Einhaltung von Konsistenzregeln), Korrektheit im Mehrbenutzerbetrieb (concurrency control) und Datensicherheit (Korrektheit der Daten auch bei Programm- und Systemabstürzen).

Ein DBMS bietet in aller Regel eine feinkörnige Berechtigungssteuerung

2. Eigenschaften eines DBMS

Physische Datenunabhängigkeit
Änderungen an den Speicherstrukturen und Zugriffspfaden sind für Anwenderprogramme und ad-hoc Abfragen unsichtbar.
Logische Datenunabhängigkeit
Änderungen an der logischen Sicht ist für Anwendungen und Abfragen unsichtbar.
Sichten (Views)
Jede Anwendung kann eine eigene Sicht der Daten erhalten. Das können Ausschnitte aus Tabellen oder Verknüpfungen mehrerer Tabellen sein.
Datenschutz
Das DBMS regelt den Zugriff auf die Daten und deren Sichtbarkeit.
Datensicherheit
Das DBMS garantiert, daß die Datenbank immer in einem konsistenten Zustand ist. Das heißt, Transaktionen sind entweder dauerhaft (COMMIT), oder sie werden vollständig rückgesetzt (ROLLBACK).
Concurrency Control
Das DBMS stellt sicher, daß mehrere parallel ablaufende Transaktionen isoliert voneinander und konsistent ablaufen.
Integritätskontrolle
Das DBMS garantiert, daß ihm bekannte Konsistenzregeln eingehalten werden.
Ad-hoc Abfragen
Ein DBMS unterstützt spontane Anfragestellungen. Diese werden vom DBMS optimiert (soweit möglich).

3. Verteilte Datenbanksysteme

3.1 Client-Server-Architektur

Hier gibt es typischerweise einen zentralen Datenbank-Server und eine größere Anzahl vernetzter Arbeitsplatzrechner, die keine relevanten Daten speichern. Der Benutzer am Arbeitsplatzrechner sieht die volle Funktionalität des DBMS. Das System verhält sich wie ein zentrales Datenbanksystem, die Kommunikation ist für den Benutzer transparent

3.2 Verteilte Datenbanksysteme

Hier gibt es mehrere Datenbankserver, wobei bestimmte Daten auf nur einem Rechner oder auch auf mehreren (replizit) gespeichert sein können.

Transaktionen können in diesem Fall über mehrere DBMS laufen, deshalb ist hier ein zweistufiges Schema erforderlich (Two-Phase-COMMIT).

4. Klassifizierung/Historie der Datenhaltung

1950-1960 "Vorgeschichte"

Da es noch keine Magnetplatten gab, wurden große Datenmengen ausschließlich sequentiell auf Magnetband gespeichert. Brauchte man einen bestimmten Datensatz, so mußte man das ganze Band durchnudeln.

Im Prinzip entspricht das heute einem Suchen mit grep nach einem Wort in einer Datei.

1960-1970 "Steinzeit"

Es gibt erste Magnetplatten und -trommeln, also relativ schnelle Medien mit wahlfreiem Zugriff. Jetzt kann man auf einen speziellen Datensatz zugreifen, ohne alle davorliegenden abzugrasen. Durch geeignete Inhaltsverzeichnisse (Index-Dateien oder Hashtabellen) kann man die Adresse des Datensatzes ermitteln.

Die Daten wurden anwendungsspezifisch gespeichert (nur die Anwendung und deren Programmierer kennt den Aufbau der Datensätze). Im Prinzip wurden die programminternen Strukturen (records in Pascal, structs in C) direkt in die Datei geschrieben.

Man hatte jetzt Datensätze fester und variabler Länge, sowie die Möglichkeit, sequentiell, direkt oder indexsequentiell darauf zuzugreifen.

1970-1980 "Mittelalter"

Man geht dazu über, die Beschreibung der Datensätze in einem "Data Dictionary" abzulegen. Damit werden Datensätze in Felder eingeteilt. Damit sind auch erste Konsistenzprüfungen und Berechtigungssteuerung möglich.

Der PC erlebt diese Phase erst später, hier kann man dBase und dessen Ableger bzw. Konkurenzprodukte einordnen (Clipper, FoxPro, Paradox ...)

In diese Zeit fallen auch erste Implementierungen von Datenbanksystemen, die mehrere Dateien miteinander verknüpfen konnten. Das betrifft die DBMS mit hierarchischem oder Netzwerk-Modell. Motiviert wurde diese (Sackgassen-)Entwicklung durch den Ansatz, Abfragen vor der Ausführung zu compilieren (geschuldet der mangelnden Rechenleistung).

1980-Heute "Moderne"

Relationale DBMS setzen sich mehr und mehr durch. Die gängigen heutigen RDBMS erfüllen weitgehend die oben aufgezählten Eigenschaften eines DBMS. Die RDBMS beruhen auf einem einfachen konzeptionellen Modell und sind hochgradig datenunabhängig. Das relationale Modell ist auch umfassend theoretisch durchdrungen worden, es gibt eine ganze "Theorie relationaler Datenbanken" mit zahlreichen Spezialgebieten.

In einem RDBMS sieht der Benutzer die Daten in Form von Tabellen. Der Zugriff erfolgt jetzt inhalts- bzw. mengenorientiert mit Abfragesprachen (DML - Data Manipulation Language). Als Standard hat sich hier SQL (Structured Query Language), im übrigen eine der besseren Erfindungen von IBM, durchgesetzt. Man muß dem DBMS nicht sagen, wie es den einzelnen Satz findet, sondern gibt nur Selektionskriterien vor. Dazu ein Beispiel in SQL:

SELECT KUNDENNUMMER, NAME, PLZ, ORT FROM KUNDENSTAMM
WHERE ORT='Chemnitz' ORDER BY NAME

Die RDBMS können Daten verschiedener Tabellen (Dateien) miteinander verknüpfen. Hierzu wieder ein Beispiel in SQL:

SELECT K.KUNDENNUMMER, K.NAME, L.PLZ, L.ORT FROM KUNDENSTAMM K,
LIEFERANSCHRIFTEN L WHERE K.NAME='Test und Probe KG' AND L.KUNDENNUMMER=K.KUNDENNUMMER ORDER BY L.ORT

Ein wichtiges Merkmal der RDBMS ist, daß Daten zur Speicherung einer Normierung unterzogen werden. Im obigen Beispiel sieht man bereits, daß die Lieferanschrift nicht im Kundenstamm steht. Man vermeidet dadurch, denselben Kunden mehrfach zu speichern, nur weil er mehrere Lieferanschriften (Filialen) hat.

Es würde hier zu weit führen, auf die verschiedenen Phasen der Normierung und deren praktische Realisierung einzugehen, als gutes und tiefschürfendes Buch sei hier
"Datenmodelle, Datenbanksprachen und Datenbank-Management-Systeme" von Gottfried Vossen empfohlen.

1985-??? Objektorientierte DBMS

Je komplizierter die abzuspeichernden Gebilde werden, desto ungeeigneter sind relationale DBMS. Betrachtet man z.B. eine CAD-Anwendung, so leuchtet das sofort ein. Wie soll man auch die Konstruktion eines Autos in tabellarischer Form erfassen? Traditionell werden solche Objekte in Dateiform gespeichert.

Um auch hier die Vorteile eines DBMS nutzen zu können (Mehrfachzugriff, Datenunabhängigkeit, Redundanzfreiheit, Navigation mit Abfragesprache) wurden objektorientierte Datenbanken entworfen und auch realisiert. Man findet auch unter Linux einige Vertreter dieser Kategorie (Links, Poet).

Es gibt außerdem Ansätze, kompliziert strukturierte Objekte durch Erweiterungen des relationalen Modells in RDBMS unterzubringen. Ein Vorreiter in dieser Richtung war Postgres. Auch dieses Object-Relationale DBMS ist für Linux verfügbar.

5. SQL - Structured Query Language

SQL ist der Standard unter den Abfragesprachen relationaler Datenbanken. Es gibt nur noch ganz wenige DBMS, die eine andere Sprache sprechen, darunter db++ und das freie Ingres.

SQL ist ein typischer Fall von zu spät gekommener Standardisierung, jeder große DB-Hersteller hat eigene (mehr oder weniger sinnvolle) Erweiterungen oder gar Abweichungen eingebaut. SQL wurde zuletzt 1992 vom ANSI-Gremium standardisiert. Dabei wurden drei Stufen der Konformität festgelegt:

  1. Basic SQL-92
  2. Intermediate SQL-92
  3. Full SQL-92
Ein Full SQL-92 stellt dabei doch sehr hohe Anforderungen, die von keinem freien oder Low-Cost-System erfüllt werden. Selbst Intermediate SQL-92 ist für diese Systeme im Moment noch nicht erreichbar, wobei die Entwicklung von PostgreSQL und mysql in diese Richtung geht. Wer SQL lernen möchte wird in der Dokumentation zu verschiedenen DBMS (z.B. Informix, aber auch mSQL) fündig. Unter http://w3.one.net/~jhoffman/sqltut.html findet man außerdem ein sorgfältig gestaltetes Tutorial, welches alle herstellerspezifischen Erweiterungen außen vor läßt. Eine gute Quelle ist auch die Dokumentation zur Testversion von YARD-SQL, die auf den SuSE-CD's enthalten ist.

Eigentlich enthält SQL zwei Teilbereiche, eine DML (Data Manipulation Language) und eine DDL (Data Definition Language). Mit letzterer definiert man die Strukturen, die man dann mit der DML beackert.

5.1 SQL-Befehle

Die folgende Liste enthält nur die wichtigsten SQL-Befehle und deren Kurzbeschreibung. Vieleicht ist das für jemanden ganz nützlich, der anfängt, sich mit SQL zu befassen:

BefehlVerwendung
COMMITSchließt eine Transaktion ab und macht alle Änderungen permanent
CREATE INDEXErstellt einen Index
CREATE TABLEErstellt eine Tabelle
CREATE VIEWErstellt eine logische Sicht anhand eines SELECT-Statements
DELETELöscht Tabellenzeilen
DROPLöscht Strukturelemente, z.B. DROP TABLE
GRANTErteilt Berechtigungen
INSERTFügt einen oder mehrere Datensätze ein. Die Daten werden dem INSERT entweder in einer VALUES-Klausel mitgegeben oder stammen aus einem SELECT
REVOKEEntzieht Berechtigungen
ROLLBACKMacht eine Transaktion komplett rückgängig und verwirft alle Änderungen
SELECTLiest Daten aus der Datenbank. Kann mehrere Tabellen verknüpfen, die Ausgabe sortieren, Daten gruppieren und aggregieren (Summe, Maximum, Minimum, Durchschnitt, Anzahl)
UPDATEÄndert Daten. Die betroffenen Sätze werden durch eine WHERE-Klausel angegeben.

5.2 Statisches und dynamisches SQL

Es gibt verschiedene Möglichkeiten, wie man der Datenbank seine SQL-Befehle übergibt. Statisches SQL bietet eine wesentlich bessere Performance auf Kosten mangelnder Flexibilität. Statisches SQL wird in der Regel als Embedded SQL zur Verfügung gestellt. Dabei werden in eine Wirtssprache (C, COBOL oder andere) SQL-Statements eingefügt. Man muß diese vom übrigen Quelltext durch Anweisungen EXEC SQL bzw. END-EXEC abtrennen. Ein Präcompiler des Datenbankherstellers verarbeitet dann den Quelltext, indem er die SQL-Befehle durch entsprechende Funktionsaufrufe ersetzt. Nach dem Compilieren hat man ein Objekt, das man noch gegen die entsprechende SQL-Bibliothek des DB-Herstellers linken muß und erhält ein fertiges Programm mit sehr guter Performance. Die SQL-Statements werden also bereits beim Compilieren verarbeitet.

Anders verhält es sich bei dynamischem SQL. Hier werden die SQL-Statements direkt zur Laufzeit als String dem DBMS übergeben. Dieses muß zur Laufzeit die Befehle parsen, compilieren, einen geeigneten Zugriffsplan erstellen und dann ausführen. Das ist, je nach Komplexität der Statements recht aufwendig.

Um für viele gleichartige SQL-Befehle diesen ganzen Prozeß nicht dauernd wiederholen zu müssen (Man stelle sich eine Anwendung mit 100.000 INSERT-Statements vor), kann man einen Befehl mit Parametermarkern versehen. Dieser wird dann einmal aufbereitet und anschließend für jeden Aufruf nur noch mit den entsprechenden Parametern versorgt. Das Konzept nennt sich Prepared Statements.

Programme, die dem Benutzer die Eingabe von SQL-Anweisungen erlauben, arbeiten stets mit dynamischem SQL. Da dynamisches SQL besser von der Datenbank isoliert, wird dieses auch für sogenannte Middleware eingesetzt. Das sind Programme, die Anwendungen und Anwendungsprogrammierern eine einheitliche Schnittstelle für verschiedene DBMS bieten. Prominentester Vertreter ist dabei ODBC, es gibt aber auch auf UNIX entsprechende Lösungen. Eigentlich gibt es sogar einen X/OPEN-Standard dafür (CLI = Call Level Interface). Ich habe aber keine entsprechende Implementation für Linux gefunden.

6. Datenbanken unter Linux

Kommen wir auf unser Lieblings-Betriebssystem zurück. Linux ist durchaus als Grundlage für größere Datenbankanwendungen geeignet. Es gibt von Seite des Betriebssystems eigentlich kaum Einschränkungen in dieser Hinsicht, Linux ist hier eher besser als andere PC-Unixe oder gar NT geeignet, da es durch sein hervorragendes Speichermanagement eine hohe Performance bietet.

Das oft gegen Linux gebrauchte Argument der komplizierten Wartung und Einarbeitung zieht bei einem Datenbankserver kaum, hier braucht man sowieso einen gut ausgebildeten Administrator. Linux' einziger Nachteil in Richtung DB-Server ist, daß es selbst alle Platten (auch die character-devices) casht und damit bestimmte Transaktionsmechanismen der großen DBMS (Optimierung auf raw-devices) ausschließt. Ich zähle im folgenden nur mal alle mir bekannten Linux-Datenbanken auf, mit einer Kurzcharakteristik aber ohne Anspruch auf Vollständigkeit.

6.1 Freie und Low-Cost-Datenbanken

mSQL
Mini-SQL, mehr dazu von Jens Pönisch
PostgreSQL
weiterentwickeltes Postgres mit SQL als Abfragesprache. Unterstützt Transaktionen. Hat objektorientierte Erweiterungen. Wichtige SQL-Elemente fehlen aber (Subselects, Outer Joins, exakter numerischer Datentyp).
mysql
Dazu mehr im entsprechenden Vortrag
phsql
Absolute Minimallösung, benutzt sed, bash und awk, um SQL auszuführen. Natürlich sehr langsam. Nur für den geeignet, der etwas in SQL reinschnuppern möchte. Aber ein extremes Beispiel, was mit 30 kByte Standard-Scriptsprachen alles machbar ist.
mdbms
Ebenfalls ein absolutes minimal-Datenbänkchen. Unterstützt aber eine recht große Untermenge von Standard-SQL. Zum Lernen brauchbar.
Ingres
Hierbei handelt es sich um das sogenannte university-Ingres, das seit 1987 nicht mehr weiterentwickelt wurde. Das System verwendet eine eigene Abfragesprache. Sollte man sich nicht antun.

6.2 Kommerzielle Systeme

Hier verweise ich auf die Zeitschrift iX, Ausgabe 05/97, in der ein recht umfangreicher Test von SQL-fähigen RDBMS für Linux enthalten ist.