von
Michael Albrecht - Ausbilder FIAN
team neusta GmbH
Motivation & Historie
Relationen & Entitäten
Datenbankdesign
Normalisierung
Structured Query Language
Sonstiges
Wie heiße ich und was ist meine Motivation FIAN zu werden?
Was bringe ich zum Thema Datenbanksysteme bereits für Vorkenntnisse mit?
Was erwarte ich am Ende des Kurses?
Möglichst zu jeder Frage 1-2 Sätze und insgesamt nicht länger als 2 Minuten
Natürlich brauchen wir Daten vor allem, um sie in Programmen verarbeiten, verwenden und neue Daten erzeugen können.
Nur der reinen Datenhaltung halber ist seltener der Fall.
Entitäten (lat.: entitas - Ding) sind Objekte unseres Denkens und Handelns.
Für ein Datenbanksystem also die Artefakte, die es zu speichern gilt.
Attribute (lat.: attributere - zuordnen) sind Eigenschaften, die den Entitäten zugeordnet werden, um sie zu beschreiben oder auch voneinander zu unterscheiden.
Eine Relation (lat.: relatio - das Zurücktragen) ist eine Beziehung zwischen Entitäten.
Dabei nehmen die Entitäten evtl. unterschiedliche Rollen ein bzw. können mehrere Beziehungen zueinander haben.
Sammle alle Entitäten, die Du im Rahmen dieser Schulungsmassnahme siehst!
Finde alle Relationen zwischen den Entitäten, die im Rahmen dieser Schulung von Bedeutung sind!
Sammle anschließend alle Attribute der Entitäten, die Du in Aufgabe 1 gefunden hast!
Manche Attribute reichen hin, um einzelne Entitäten des gleichen Typs zu unterscheiden.
Diese nennt man Schlüssel.
Alle Attribute, die nicht Teil eines Schlüssel sind, nennt man Nicht-Schlüsselattribute.
Schlüssel, die explizit als Schlüssel eingeführt werden, nennt man technische Schlüssel - Bsp.: ID
Schlüssel, die aufgrund der Natur der Daten als Schlüssel dienen, nennt man fachliche Schlüssel.
Bsp.: Personalnummer
Es kann innerhalb einer Entität viele Attribut(kombinationen) geben, die als Schlüssel dienen.
Einer sollte davon ausgezeichnet werden, indem man ihn Primärschlüssel nennt.
Entitäten sind Rechtecke.
Relationen sind Diamanten, die mit den Entitäten, die Teil der Relation sind, verknüpft werden.
Attribute werden als Kreise an die Rechtecke oder Diamanten gehängt.
Es gibt folgende 3 Relationstypen:
Die Kardinalitäten lassen sich mit 0...n bzw. 1...n feiner granulieren.
Entitäten werden natürlich 1:1 in Tabellen umgesetzt.
Dabei sollte der Name der Entität zum Tabellennamen werden.
Die Attribute werden zu Spalten(überschriften).
Der Wertebereich der Attribute bestimmt dabei den Typ der Spalten.
EAN (PK) | Name | Beschreibung | Farbe | Größe | Preis |
---|---|---|---|---|---|
... | ... | ... | ... | ... | ... |
Der Tabelle der Children-Entitäten wird der Primärschlüssel der Parent-Entität als Fremdschlüssel hinzugefügt.
EAN (PK) | ProduktTypID (FK) | Name | ... |
---|---|---|---|
... | ... | ... | ... |
Analog zu 1:n Relationen, wobei die Entscheidung, welche Seite Parent und welche Child ist, frei bleibt.
ID | Ehefrau (FK) | Name | ... |
---|---|---|---|
... | ... | ... | ... |
ID | Name | ... |
---|---|---|
... | ... | ... |
Frau
Mann
m:n - Relationen werden über eine Mapping Tabelle abgebildet.
EAN (PK) | Name | ... |
---|---|---|
2000891 | Heimtrikot | ... |
ID (PK) | Name | ... |
---|---|---|
10 | Trikots | ... |
20 | Herren | ... |
Produktkategorie
Produkt
EAN (PK, FK) | ID (PK, FK) |
---|---|
2000891 | 10 |
2000891 | 20 |
Produkt2Produktkategorie
Im Falle der 1:n bzw. 1:1 Relationen werden die Attribute der Relation neben den Fremdschlüssel gestellt.
Im Falle der m:n - Relationen werden die Attribute zu Spalten der Mapping-Tabelle.
Die Spezialisierung in weitere Entitäten, die eigene Attribute besitzen, wird behandelt wie eine 1:1 - Relation, wobei die allgemeine Entität der Parent ist.
Die Spezialisierung in weitere Entitäten, die keine eigenen Attribute besitzen, wird
Email (PK) | Name | ... |
---|---|---|
... | ... | ... |
Person
Email (PK, FK) | Jahrgang | ... |
---|---|---|
... | ... | ... |
Praktikant
Email (PK) | Name | Funktion |
---|---|---|
... | ... | Trainer/Verwaltungsmitarbeiter/... |
Person
Email (PK) | Name | .. |
---|---|---|
... | ... | ... |
Praktikant
Email (PK) | Name | ... |
---|---|---|
... | ... | ... |
Trainer
Email (PK) | Name | ... |
---|---|---|
... | ... | ... |
Verwaltungsmitarbeiter
Anomalien sind Unregelmäßigkeiten in den Datensätzen, die aufgrund der Pflege durch einzelne Benutzer oder im Mehrbenutzerbetrieb auftauchen können.
Eine Relation ist in 1.Normalform, wenn alle ihre Attribute atomar sind.
Regisseur hat Vor- und Nachname
Dauer gibts 2mal.
Titel besteht aus Titel und Teil.
Aufspaltung in mehrere Attribute oder in mehrere Relationen.
Eine Relation ist in 2.Normalform, wenn sie
Ein Attribut A hängt von {B1, B2, B3} funktional ab, wenn bei Gleichheit in den Werten {B1, B2, B3} die Gleichheit in A folgt.
A hängt voll von {B1, B2, B3} funktional ab, wenn die Menge {B1, B2, B3} nicht verkleinert werden kann, ohne die funktionale Abhängigkeit zu verlieren.
Eine Relation ist in 2.Normalform, wenn sie
Aufspaltung in mehrere Tabellen, so dass jedes Nicht-Schlüsselattribut voll funktional vom Schlüssel abhängt..
Eine Relation ist in 3.Normalform, wenn sie
Voneinander abhängige Attribute in
eigene Tabelle ausgelagern
CREATE DATABASE datenbankSchemaName;
DROP DATABASE datenbankSchemaName;
Mit diesen Befehlen erzeugt und löscht man ein neues Datenbankschema.
CREATE TABLE tableName (
spaltenname1 sql_data_types [constraints],
spaltenname2 sql_data_types [constraints],
spaltenname3 sql_data_types [constraints],
...
);
DROP TABLE tableName;
Mit diesen Befehlen erzeugt und löscht man eine Tabelle.
ALTER TABLE tableName
ADD new_spaltenname sql_data_types [constraints];
ALTER TABLE tableName
DROP COLUMN spaltenname1;
ALTER TABLE tableName
MODIFY COLUMN spaltenname1 sql_data_types [constraints];
Mit diesen Befehlen ändert man eine bestehende Tabelle.
Lege eine Datenbank Filme an!
Befülle alle Tabellen mit den gleichen Werten aus dem Skript!
Erstelle alle normalisierten Tabellen lt. Skript, also:
Wenn im ersten CREATE Schritt etwas schiefgeht, versuche es mit ALTER Befehlen zu korrigieren.
SELECT [DISTINCT][Aggregatfunktionen] ...
FROM ...
[ JOIN ... ON ... ]
[ WHERE ... ]
[ GROUP BY ... HAVING ... ]
[ ORDER BY ... [ASC/DESC]]
SELECT titel FROM Filme;
SELECT DISTINCT titel FROM Filme;
SELECT * FROM Filme;
Das Sternchen * heißt hier Asterisk und wird als Platzhalter für alle Attribute verwendet.
SELECT titel, episode, id FROM Filme;
SELECT titel, 12*3, ln(1), 'Hallo' FROM Filme;
SELECT titel AS Filmtitel FROM Filme;
SELECT COUNT(*) AS Anzahl FROM Dauer;
SELECT MAX(dauer) AS Maximallänge FROM Dauer;
SELECT MIN(dauer) AS Minimallänge FROM Dauer;
SELECT AVG(dauer) AS Durchschnitt FROM Dauer;
SELECT SUM(dauer) AS Gesamt FROM Dauer;
SELECT * FROM Dauer WHERE dauer > 150;
SELECT * FROM Dauer WHERE dauer = 100;
SELECT * FROM Dauer WHERE dauer IN (131,132,133);
SELECT * FROM Dauer WHERE dauer BETWEEN 100 AND 120;
SELECT * FROM Dauer WHERE dauer >= 155;
SELECT * FROM Dauer WHERE dauer > 150;
SELECT * FROM Dauer WHERE dauer != 100; -- Manchmal auch <>
SELECT * FROM Dauer WHERE dauer = 100 OR dauer > 150 AND ueberlaenge = 1;
Es gilt die Punkt-vor-Strich - Regel:
AND geht vor OR
Andernfalls müssen wir Klammern setzen.
SELECT * FROM Filme WHERE titel LIKE 'From Dusk till Dawn';
SELECT * FROM Filme WHERE titel LIKE 'From Dusk _ill Dawn';
SELECT * FROM Filme WHERE titel LIKE 'From%';
_ repräsentiert genau 1 Zeichen.
% repräsentiert 0, ein oder beliebig viele Zeichen
Finde alle IDs der Filme von Sergio Leone heraus!
Finde alle Regisseure heraus, die Filme ohne Überlänge produzierten!
Finde alle Sergio Leone - Filme, die länger als 3h gehen!
Finde alle Regisseure, deren Filme einen (bestimmten/unbestimmten) Artikel enthalten!
SELECT [DISTINCT][Aggregatfunktionen] ...
FROM ...
[ JOIN ... ON ... ]
[ WHERE ... ]
[ GROUP BY ... HAVING ... ]
[ ORDER BY ... [ASC/DESC]]
SELECT * FROM Filme, Regisseure;
SELECT COUNT(*) FROM Filme, FilmRegisseure, Regisseure;
Wir haben 12 Filme in der Datenbank.
Wir haben 4 Regisseure.
Es gibt 13 Zuordnungen von Regisseuren zu Filmen.
12 * 4 * 13 = 624.
SELECT Filme.titel, Regisseure.vorname, Regisseure.nachname
FROM Filme, FilmRegisseure, Regisseure
WHERE Filme.id = FilmRegisseure.filmId
AND FilmRegisseure.regisseurId = Regisseure.regisseurId;
SELECT f.titel, r.vorname, r.nachname
FROM Filme AS f, FilmRegisseure AS f2r, Regisseure AS r
WHERE f.id = f2r.filmId
AND f2r.regisseurId = r.regisseurId;
SELECT f.titel, r.vorname, r.nachname
FROM Filme AS f
JOIN FilmRegisseure AS f2r ON f.id = f2r.filmId
JOIN Regisseure AS r ON f2r.regisseurId = r.regisseurId
SELECT f.titel, r.vorname, r.nachname
FROM Filme AS f
JOIN FilmRegisseure AS f2r ON f.id = f2r.filmId
NATURAL JOIN Regisseure AS r
SELECT *
FROM Regisseure AS r
LEFT OUTER JOIN FilmRegisseure AS f2r
ON r.regisseurId = f2r.regisseurId;
SELECT * FROM Regisseure AS r FULL OUTER JOIN FilmRegisseure AS f2r;
Leider wird der FULL JOIN in MySQL NICHT unterstützt, weshalb wir eine Alternative benötigen...
SELECT * FROM ...
UNION ALL
SELECT * FROM ...
SELECT value1 FROM table1
UNION
SELECT value2 FROM table2;
UNION führt zwei Abfrageresultate zusammen und streicht gleiche Datensätze.
SELECT value1 FROM table1
UNION ALL
SELECT value2 FROM table2;
UNION ALL führt zwei Abfrageresultate zusammen und streicht gleiche Datensätze NICHT.
SELECT [DISTINCT][Aggregatfunktionen] ...
FROM ...
[ JOIN ... ON ... ]
[ WHERE ... ]
[ GROUP BY ... HAVING ... ]
[ ORDER BY ... [ASC/DESC]]
SELECT r.vorname, r.nachname, COUNT(f2r.regisseurId)
FROM Regisseure AS r
LEFT JOIN FilmRegisseure AS f2r ON r.regisseurId = f2r.regisseurId
GROUP BY r.regisseurId
SELECT r.vorname, r.nachname, COUNT(f2r.regisseurId)
FROM Regisseure AS r
LEFT JOIN FilmRegisseure AS f2r ON r.regisseurId = f2r.regisseurId
GROUP BY r.regisseurId
HAVING COUNT(f2r.regisseurId) > 3
SELECT vorname, nachname
FROM Regisseure
ORDER BY nachname DESC
SELECT vorname, nachname FROM Regisseure
UNION
SELECT vorname, nachname FROM Schauspieler
SELECT r.vorname, r.nachname FROM Regisseure AS r
WHERE
EXISTS(
SELECT *
FROM Schauspieler AS s
WHERE s.vorname = r.vorname AND s.nachname = r.nachname
)
SELECT r.vorname, r.nachname
FROM Regisseure AS r
WHERE r.regisseurId =
ALL (
SELECT r.regisseurId
FROM Filme AS f
JOIN FilmRegisseure AS f2r ON f.id=f2r.filmId
JOIN Regisseure AS r on f2r.regisseurId = r.regisseurId
JOIN Dauer AS d ON d.id = f.id
)
ANY und ALL Subselects müssen mit einem Vergleichsoperator verknüpft werden,
also =, != bzw. <>, <,>,<=,>=
CASE
WHEN bedingung1 THEN ergebnis1
WHEN bedingung2 THEN ergebnis2
WHEN bedingung3 THEN ergebnis3
ELSE standardergebnis
END
INSERT INTO Tabellenname [(spaltenname1, spaltenname2, ...)]
VALUES (spaltenwert1, spaltenwert2, ...)
INSERT INTO Tabellenname [(spaltenname1, spaltenname2, ...)]
SELECT ...
Alternativ kann auch ein Abfrageergebnis eingefügt werden:
DELETE FROM Tabelle
[WHERE ...]
Ohne WHERE - Bedingung werden ALLE Datensätze der Tabelle gelöscht.
UPDATE Tabelle
SET spalte1=wert1, spalte2=wert2, ...
[WHERE ...]
Ohne WHERE - Bedingung werden ALLE Datensätze der Tabelle aktualisiert.
Es können 1 bis n Spalten aktualisiert werden.
GRANT {ALL|EXECUTE|SELECT|andere Privilegien}
ON Tabellenname
TO {Benutzername|PUBLIC|Rollenname}
[WITH GRANT OPTION]
REVOKE {ALL|EXECUTE|SELECT|andere Privilegien}
ON Tabellenname
FROM {Benutzername|PUBLIC|Rollenname}
Eine Datenbanktransaktion besteht aus einer Gruppe von Teilaktionen, die in einer oder mehreren Datenbanktabellen erfolgreich ausgeführt werden müssen, bevor sie endgültig festgeschrieben (Commit) werden können.
try {
...
conn.setAutoCommit(false);
// INSERT, UPDATE, DELETE
// passieren hier
// und werfen ggf. SQL-Exceptions
// Wenn alles ok ist, ...
conn.commit();
} catch(SQLException e) {
// ...andernfalls
conn.rollback();
}
Schlägt eine der Teiltransaktionen in der Gruppe fehl, werden alle anderen Teilaktionen ebenfalls rückgängig gemacht (Rollback).
Ein Datenbank Index beschleunigt die Suche nach Werten in den indizierten Feldern
CREATE [UNIQUE] INDEX <index name>
ON <table name> (<column(s)>);
Nachteil:
Beim Einfügen neuer Datensätze verschlechtert die Indizierung die Performanz.
No Index:
Nach dem (wahllosen) Einfügen neuer Datensätze braucht es für die Suche eines bestimmten Elements meist:
n / 2 - viele Zugriffe
,wobei n die Anzahl aller Elemente ist.
Wir nennen dies: O(n) "Landau Notation"
Die Dauer wächst linear mit der Anzahl der eingefügten Elemente.
Ein Binärbaum ist so aufgebaut, dass nach einer festzulegenden Regel, manche Elemente links und manche rechts einsortiert werden.
Hier:
kleinere Elemente -> links
größere Elemente -> rechts
With Index:
Hier braucht es für die Suche eines bestimmten Elements meist:
log(n) - viele Zugriffe
,wobei n die Anzahl aller Elemente ist und log der Logarithmus zur Basis 2.
Wir nennen dies: O(log(n))
n | O(n) | O(log(n)) |
---|---|---|
100 | 100 | 6 |
10000 | 10000 | 14 |
1.000.000 | 1.000.000 | 20 |
1.000.000.000 | 1.000.000.000 | 30 |