Die Standard Query Language, kurz SQL, wird verwendet, um relationale Datenbanken anzusprechen. SQL ist dabei sehr umfangreich und umfasst nicht nur Anweisungen und Befehle zum Abfragen der Daten - wie man aus dem Namen schließen könnte - sondern auch die Möglichkeit Daten zu ändern und die Datenbank selbst zu beschreiben. Somit kann man mit SQL so ziemlich alle Aufgaben erledigen, die zur Administration und Benutzung von Datenbanken anfallen.
Hier sei noch erwähnt, dass es einen SQL-Standard gibt, an dem sich die Datenbankhersteller leider nur orientieren und nicht halten. Dies hat zur Folge, dass eine datenunabhängige Softare-Entwicklung mit Perl - auf Basis des abstrakten Datenbank-Layers DBI - möglich ist, die Datenbank aber aufgrund der unterschiedlichen SQL-Implementierungen nicht einfach gewechselt werden kann. Für eine solche Abstraktion gibt es ergänzend zu DBI andere Module, sogenannte ORMs. Ein sehr populäres wäre DBIx::Class.
SQl ist relativ leicht erlernbar und man kann schnell schnell Fortschritte machen. Dies ist allerdings nur eine kleine Einführung, die sich auf das Wesentliche beschränkt, aber von einen Einstieg erstmal völlig ausreichend ist. Also, viel Spass und viel Erfolg!
In einer relationalen Datenbank werden Informationen in Tabellen gespeichert. Jede Tabelle speichert zu unterschiedlichen Datensätzen (horizontal) diverse Informationen (vertikal).
Eine Beispiel für eine Datentabelle:
MitarbeiterTabelle | ||||
---|---|---|---|---|
MID | Nachname | Vorname | Standort | Gehalt |
123 | Wolf | Markus | Böblingen | 30000 |
456 | Simpson | Homer | Springfield | 120000 |
789 | Wurst | Hans | Deppendorf | 75000 |
Um Daten in diese Tabelle einzugeben, ändern, löschen und diese abfragen zu können, verwendet man die Structured Query Language, kurz SQL.
Unser Streifzug durch SQL beginnt bei einfachen Abfragen über eine Tabelle, Abfragen mit Kriterien und schliesslich Abfragen über mehrere Tabellen, sogenannte Joins. Abschliessend werden die Daten eine Tabelle manipuiliert, d.h. Daten werden
Eine Abfrage dient dem Suchen und Anzeigen von vorhandenen Daten.
Dies geschieht in SQL immer mit dem SELECT
-Befehl.
Wir wollen aus der Beispieltabelle Mitarbeiter den Namen und Standort aller Mitarbeiter erfahren:
SELECT Nachname, Vorname, Standort
FROM MitarbeiterTabelle;
So sieht das Ergebnis aus:
Nachname | Vorname | Standort |
---|---|---|
Wolf | Markus | Böblingen |
Simpson | Homer | Springfield |
Wurst | Hans | Deppendorf |
Was genau haben wir getan: Wir haben uns alle Mitarbeiter aus der Mitarbeiter-Tabelle zur Ansicht ausgewählt, und zwar deren Namen und Standort. Die Mitarbeiter-Nummer (MID) haben wir dabei ausser Acht gelassen.
Eine Abfrage generell funnktioniert also so:
SELECT SpaltenName,SpaltenName, ...
FROM TabellenName;
Will man alle Informationen, die in einer Tabelle gespeichert sind sehen:
SELECT * FROM TabellenName;
Um Abfragen durchzuführen, die nicht alle Datensätze in der Tabelle zurückliefert, benötigen wir Abfragekriterien. Anhand dieser Kriterien werden die Datensätze gefiltert. Die allgemeine Form einer Abfrage mit Kriterien:
SELECT SpaltenName,SpaltenName,....
FROM TabellenName WHERE Kriterium
Der Aufbau des Kriterienausdrucks leitet sich von der relationalen Algebra ab. Folgende Operatoren gibt es in SQL, um vergleichende Ausdrücke zu bilden:
Operator | Bedeutung |
---|---|
= | gleich |
<> oder != | nicht gleich |
< | kleiner als |
> | größer als |
<= | kleiner als oder gleich |
>= | größer als oder gleich |
Aus der Mitarbeiter-Tabelle werden mit der Abfrage
SELECT Nachname FROM MitarbeiterTabelle
WHERE Gehalt >= 50000;
die folgenden Datensätze zurückgeliefert:
Nachname |
---|
Simpson |
Wurst |
Es wurden also alle Mitarbeiter, deren Gehalt gleich ist oder über 50.000,- liegt, ausgewählt. Ein anderes Beispiel:
SELECT Gehalt FROM MitarbeiterTabelle
WHERE Nachname = 'Simpson';
Das Resultat:
Gehalt |
---|
120000 |
Man kann Kriterien endlos miteinander verknüpfen, und damit sehr detaillierte und aussagekräftige Abfragen durchführen.
SELECT Nachname, Vorname FROM MitarbeiterTabelle
WHERE Gehalt > 50000 AND Standort != 'Springfield';
Wie man im Resultat sieht, wäre Homer Simpson aufgrund seines Gehaltes, das größer als 50000 ist, im Resultat enthalten, allerdings ist sein Standort 'Springfield', und der wurde als "nicht"-Kriterium angegeben:
Nachname | Vorname |
---|---|
Wurst | Hans |
Die beiden Kriterien wurden mit AND
verknüpft, das entspricht dem logischen UND.
Dann gibt es natürlich auch das logische ODER: OR
.
Eine andere Möglichkeit, Aussagen miteinander zu verknüpfen,
bieten die Schlüsselwörter IN
& BETWEEN
.
Ersteres wird verwendet, um in Spalten, die Zeichenketten
beinhalten, eine Menge von möglichen Kriterien anzugeben.
Ist eine der in der Klammer angegebenen Zeichenketten in einer
Spalte vorhanden, werden dessen Nachname und Vorname zurückgeliefert.
SELECT Nachname, Vorname FROM MitarbeiterTabelle
WHERE Standort IN ('Böblingen', 'Deppendorf');
Für Zahlenwerte gibt man ein Zahlenintervall mit BETWEEN an:
SELECT Nachname, Vorname FROM MitarbeiterTabelle
WHERE Gehalt BETWEEN 20000 AND 50000;
Man kann den ganzen Ausdruck mit NOT negieren, es werden also die Datensätze abgefragt, die NICHT diesen Kriterien entsprechen:
SELECT Nachname, Vorname FROM MitarbeiterTabelle
WHERE Standort NOT IN ('Böblingen', 'Deppendorf');
Und damit bekommen wir bei dieser Abfrage (endlich) wieder Homer Simpson ;-)
Um das zu feiern, benützen wir noch das Schlüsselwort LIKE:
SELECT Nachname FROM MitarbeiterTabelle
WHERE Vorname LIKE 'H%';
Das Prozentzeichen ist dabei als "Wildcard" zu sehen, repräsentiert
also alle möglichen Zeichen. Im folgenden noch ein paar Beispiele
für den Einsatz: 'Home%'
, '%ome%'
, '%omer'
.
Damit man dieselben Daten nicht mehrmals in unterschiedlichen Tabellen speichern muss, werden sie indiziert. Dazu bekommt ein Datensatz in einer Tabelle einen Primärschlüssel (primary key). Dieser besteht aus einer oder mehrerer Spalten. Auf jeden Fall muss der Primärschlüssel eines Datensatzes in dieser Tabelle eindeutig sein, es darf keinen anderen Datensatz mit demselben Schlüssel geben.
Man spricht von einem Fremdschlüssel (foreign key) bei einer Spalte in einer Tabelle, die in einer anderen Tabelle ein Primärschlüssel ist. Das heisst, die beiden Tabellen haben miteinander zu tun, ihre Datensätze sind untereinander verknüpft. Für die Join-Beispiele gelten folgende Beispieltabellen:
Artikel | ||
---|---|---|
ArtikelNr | Bezeichnung | Preis |
0010 | Kaffeebecher | 5 |
0020 | T-Shirt | 20 |
0030 | Mütze | 10 |
0040 | Sweatshirt | 45 |
Kunden | ||||
---|---|---|---|---|
KundenNr | Nachname | Vorname | Strasse | Stadt |
99100 | Meier | Richard | Hauptstr. 1 | 70000 Stuttgart |
43689 | Banner | Werner | Moosweg 5 | 12334 Hobbitdorf |
32074 | Zeller | Stefanie | Zollstr. 41 | 09137 Grenzdorf |
77077 | Geizig | Sparviel | Diskontstr. 1 | 83990 Irgendwo |
Bestellung | |||
---|---|---|---|
Best_Nr | KundenNr | ArtikelNr | Menge |
1234 | 99100 | 0020 | 5 |
3645 | 43689 | 0010 | 16 |
1234 | 99100 | 0040 | 2 |
9834 | 32074 | 0030 | 9 |
Eine Bestellung hat zwei Fremdschlüssel: zum einen einen Käufer über die KundenNr, und zu einem Artikel über die ArtikelNr. Wichtig ist, dass in dieser Tabelle kein Primärschlüssel vorhanden ist. Die Bestellnummer kommt doppelt vor, wie man sieht. Mit diesen Tabellen werden wir nun kompliziertere Abfragen durchführen: joins
Es gibt zwei Voraussetzungen, um miteinander in Verbindung stehende Tabellen optimal einzusetzen:
Und damit ins Geschehen: wir wollen alle Bestellungen sehen, die Herr Meier aufgegeben hat:
SELECT Best_Nr, ArtikelNr, Menge
FROM Bestellung, Kunden
WHERE Bestellung.KundenNr = Kunden.KundenNr AND Nachname = 'Meier';
Zu beachten ist in der WHERE
-Klausel die Notation TabellenName.Spaltenname. Dadurch werden die Spalten aus den beiden Tabellen nicht verwechselt.
Das Ergebnis sieht so aus:
Best_Nr | ArtikelNr | Menge |
---|---|---|
1234 | 0020 | 5 |
1234 | 0040 | 2 |
Es gibt Kunden, die noch keine Bestellung aufgegeben haben. Die aber, die schon einmal etwas bestellt haben, sollen einen Bonus bekommen. Dazu wollen wir herausfinden, wer das ist:
SELECT DISTINCT Kunden.KundenNr, Nachname, Vorname
FROM Bestellung, Kunden
WHERE Bestellung.KundenNr = Kunden.KundenNr ORDER BY Nachname, Vorname;
Normalerweise würde Herr Meier im Ergebnis zweimal auftauchen, da er ja zwei Bestellungen aufgegeben hat. Mit dem Schlüsselwort DISTINCT
wird das aber vermieden, er
taucht nur einmal auf.DISTINCT filtert also Duplikate unter den angeforderten Datensätzen heraus. Um noch eins draufzusetzen, haben wir das Ergebnis nach Nachnamen und Vornamen sortieren lassen, und zwar durch ORDER BY.
Dies also eine kleine Einführung in die Joins, damit kommt man schon mal ein Stück weit. Natürlich geht's aber noch weitaus komplexer... Wer sich dafür interessiert, bzw. tiefer einsteigen will, sollte die Fachliteratur dazu lesen, z.B. das Buch SQL lernen von Michael Ebner, erschienen bei Addison-Wesley.
Ich will 5 wichtige Funktionen, die in SQL "eingebaut" sind, erläutern:
Ein paar Beispiele:
SELECT SUM(Menge), AVG(Menge)
FROM Bestellung
Berechnet die Anzahl der Artikel, die bestellt wurden, sowie die durchnittliche Anzahl, die von einem Artikel bestellt wurde.
SELECT MAX(Menge), MIN(Menge)
FROM Bestellung
Liefert die Bestellung mit der größten Menge von Artikeln und mit der kleinsten Menge.
SELECT COUNT(*)
FROM Bestellung WHERE Menge > 10
Zählt alle Bestell-Positionen, bei denen mehr als 10 Stück von einem Artikel bestellt wurden.
Mit Abfragen lassen sich die Informationen in einer Datenbank nach Gusto sortieren und anzeigen. Wie kommen die Daten aber in die Datenbank? Wie werden sie geändert und gelöscht? Mit SQL jedenfalls relativ einfach. Als Beispiel gilt die Artikel Tabelle mit den Spalten ArtikelNr, Bezeichnung und Preis.
Zuerst fügen wir einen Datensatz in die Tabelle 'Artikel hinzu':
INSERT INTO Artikel VALUES ('0090', 'duschvorhang', 44.95);
In diesem Fall wird ein neuer Datensatz in die Tabelle eingefügt. Man kann die Reihenfolge der Werte auch verändern, dann muss aber auch angegeben werden, welche Spalten man meint. Dabei lassen wir dieses Mal den Preis mal aus, weil er noch nicht feststeht. Das geht aber nicht bei Primärschlüsseln, in diesem Fall die ArtikelNr, die muss vohanden sein:
INSERT INTO Artikel (Bezeichnung, ArtikelNr)
VALUES ('duschvorhang', '0090');
Da wir den Preis leergelassen haben, können wir ihn natürlich nchträglich einfügen, indem man einen bestehenden Datensatz ändert:
UPDATE Artikel
SET Preis = 44.95
WHERE ArtikelNr = '0090';
Dies ist natürlich auch möglich, wenn die zu ändernden Daten bereits bestehen, und auch, wenn es mehrere sind:
UPDATE Artikel
SET Preis = 44.95
WHERE Preis = 49.95
Dadurch werden alle Artikel, die bisher 49,95 gekostet haben, nun billiger.
Zu guterletzt wollen wir die Daten wieder löschen:
DELETE FROM Artikel
WHERE ArtikelNr = '0090';
Damit wird genau ein Datensatz gelöscht, der Duschvorhang, den wir vorhin eingefügt haben. Um alle Duschvorhänge, die in der Artikel Tabelle gespeichert sind, zu löschen, gehen wir wie folgt vor:
DELETE FROM Artikel
WHERE Bezeichnung = 'duschvorhang';
Das war's auch schon mit der kleinen Einführung! Viel Erfolg beim Arbeiten mit Datenbanken ↦ Datenbankprogrammierung mit Perl