Hendrik Baumann baut in Erfurt die Mitglieder- und Beitragsverwaltung für einen Sportverein mit 1.400 Mitgliedern. Im Mai trat jemand aus und verlangte die Löschung seiner Daten, was sein gutes Recht ist. Hendrik hat DELETE FROM mitglieder WHERE id = 812 ausgeführt, und die Anwendung hat nicht widersprochen.
Im März darauf stand die Kassenprüfung. Drei Beitragsbuchungen und eine Zuwendungsbestätigung zeigten auf ein Mitglied, das es nicht mehr gab, und die Belege waren damit nicht mehr zuzuordnen.
Eine Datenbank ist kein Ort, an dem Dinge liegen. Sie ist eine Menge von Zusagen darüber, was nach einem Absturz noch stimmt, und eine Menge von Abwägungen darüber, was schnell sein wird. In Deutschland kommt eine dritte Menge dazu, und die steht nicht in der Datenbank, sondern im Gesetz.
Löschen, und trotzdem aufbewahren
Zwei Pflichten liegen hier auf derselben Zeile. Artikel 17 der Datenschutz-Grundverordnung gibt ein Recht auf Löschung. §147 der Abgabenordnung verlangt, dass steuerlich erhebliche Unterlagen über Jahre aufbewahrt werden. Aufgelöst wird das in Artikel 17 Absatz 3 Buchstabe b, der den Anspruch dort ausnimmt, wo eine rechtliche Verpflichtung die Verarbeitung verlangt. Welche Frist für welchen Beleg gilt, sagt die Steuerberatung. Dass beide Pflichten auf einer Zeile liegen, entscheidet den Entwurf, und das ist die Arbeit hier.
Der Entwurf ist nicht, weniger zu löschen. Er ist, die Daten so zu trennen, dass Löschen und Aufbewahren verschiedene Zeilen treffen. Ein Beleg speichert Name und Anschrift als Kopie, nicht als Fremdschlüssel. Sie bescheinigt, was an einem Tag gegolten hat, und darf sich nicht mitändern, wenn jemand umzieht oder austritt.
CREATE TABLE spenden (id INTEGER PRIMARY KEY,mitglied_id INTEGER REFERENCES mitglieder(id) ON DELETE SET NULL,name TEXT NOT NULL, -- Stand am Tag der Spende, absichtlich doppeltanschrift TEXT NOT NULL,betrag_cent INTEGER NOT NULL,gezahlt_am DATE NOT NULL)
ON DELETE SET NULL lässt den Beleg stehen und trennt nur die Verbindung, während ON DELETE CASCADE ihn mitgenommen hätte und ON DELETE RESTRICT das Löschen ganz verweigert. Genau diese drei Wörter hat Hendrik nicht geschrieben, und die Voreinstellung hat entschieden.
In der Prüfung heißt die Doppelung name und anschrift ein Verstoß gegen die dritte Normalform. Auf einem Beleg ist sie die richtige Antwort, weil ein Beleg keine Sicht auf lebende Daten ist, sondern ein eingefrorener Zustand. Wer das benennen kann, hat die Normalformen verstanden; wer sie nur aufsagt, löscht im Mai und sucht im März.
Die Zeile, die vier Sekunden gespart hat
Der zweite Teil dieses Themas ist billiger zu lernen und wird trotzdem später gelernt. Hendriks Beitragsübersicht liest die Buchungen der letzten zwölf Jahre, 214.000 Zeilen, und fragt nach denen eines Mitglieds. Ohne Hilfe hat die Datenbank einen Weg: alle 214.000 Zeilen lesen und jede prüfen. Das dauerte 4,1 Sekunden.
Ein Index ist eine zweite, sortierte Kopie der Spalte. Mit ihr springt die Datenbank an die Stelle und liest die 96 Zeilen, die das Mitglied betreffen. Aus 4,1 Sekunden wurden 11 Millisekunden, und an der Abfrage hat sich kein Zeichen geändert: CREATE INDEX ON buchungen (mitglied_id).
Umsonst ist das nicht, und deshalb legt keine Datenbank von sich aus Indizes an. Die Kopie muss wahr gehalten werden, also schreibt jeder neue Beitrag zweimal, einmal in die Zeile und einmal in die Kopie. Bei einer Tabelle, die ständig gelesen und selten geschrieben wird, ist das ein guter Handel. Beim Beitragslauf im Januar, der an einem Abend 1.400 Buchungen anlegt, ist es eine Abgabe.
Beendet wird die Diskussion mit EXPLAIN, das die Datenbank vorher fragt, was sie zu tun gedenkt. Sie antwortet mit dem Plan, und das Lesen dieses Plans ist die übertragbarste Fähigkeit dieses Themas. Wofür die Sprache sonst noch da ist, steht unter SQL.
Drei Sätze, die falsche Antworten erzeugen
Der erste liefert still gar nichts. NULL ist nicht gleich NULL, deshalb hilft nur IS NULL. NULL bedeutet nicht null und nicht leer, sondern unbekannt, und zwei Unbekannte lassen sich nicht für gleich erklären. WHERE austritt = NULL ist kein Fehler und trifft keine Zeile. Hendriks erste Fassung hatte genau das und meldete, kein Mitglied sei ausgetreten.
Der zweite legt die Maschine lahm. Ein Join ohne ON verbindet jede Zeile mit jeder Zeile. 1.400 Mitglieder mit 214.000 Buchungen ohne Bedingung verbunden sind 299.600.000 Zeilen, und die Datenbank tut es, weil die Anfrage erlaubt ist. Es kommt keine Fehlermeldung, sondern nichts.
Der dritte zählt, wenn etwas auf halbem Weg abbricht. Eine Transaktion ist ganz oder gar nicht. Ein Mitglied in eine andere Abteilung umzumelden sind zwei Schreibvorgänge, und ein Absturz dazwischen lässt es in zweien oder in keiner stehen. Zwischen BEGIN und COMMIT landen entweder beide oder keiner, und einen Zustand dazwischen kann niemand beobachten. Darauf zeigt das Wort Datenbank eigentlich, und deshalb kommt Datenbankentwurf vor jedem Werkzeug.
Die Reihenfolge
Vier Sprossen, und jede ist unsichtbar, wenn man darüber angefangen hat
Angefangen wird fast immer auf der dritten, weil sie in der Stellenanzeige steht und in der Ausschreibung des Betriebs schon entschieden ist.
- 04Die andere FormDokumente und Schlüssel, wenn eine feste Zeile wirklich der falsche Behälter ist.Ohne die ersten drei ist das geraten
- 03Das SystemWelches Produkt, welcher Dialekt, was es bei einem Absturz tut und wo es stehen darf.Meistens vor Ihrer Ankunft ausgesucht
- 02Die FormWas die Tabellen sind, was eindeutig ist, was nicht fehlen darf, und welcher Beleg eingefroren gehört.Übersprungen, und kein Index rettet etwas
- 01Die SpracheDirekt fragen, und den Plan lesen, mit dem die Datenbank antwortet.Übersprungen, und der Abbilder ist undurchsichtig
Die Sprossen sind keine Schwierigkeitsstufen. Die erste ist die am leichtesten zu lernende und die am häufigsten aufgeschobene, weil ein Objektabbilder für Anfänger brauchbare Abfragen schreibt und genau dann damit aufhört, wenn es darauf ankommt.
Die Reihenfolge, und was ihr Überspringen kostet
Die Reihenfolge, die trägt, ist Sprache, dann Form, dann System. Fast niemand geht sie so, weil das System in der Stellenanzeige steht und die Form nirgends.
Rückwärts genommen hat der Fehler eine Signatur. Jemand lernt einen Objektabbilder vor SQL, bekommt eine laufende Anwendung und trifft dann auf eine langsame Seite, über die sich nicht nachdenken lässt, weil die Schicht, die die Abfragen schreibt, jetzt die Schicht ist, die verbirgt, was langsam ist. Der Abbilder ist nicht das Problem, und Datenzugriff ist ein echtes Fach. Undurchsichtig ist ein Objektabbilder nur für jemanden, der nie das SQL gelesen hat, das er erzeugt.
Der Stillstand: drei Normalformen, aufgesagt
Hier bleiben deutsche Lernende stehen, und es sieht nicht nach Stillstand aus, weil die Prüfungsfrage richtig beantwortet wird. Der Punkt ist der, an dem jemand die drei Normalformen aufsagen kann und nicht sagen kann, welche Tabelle im Betrieb sie brechen muss und warum. Im Lernfeld ist Redundanz ein Fehler mit Punktabzug. Auf einem Beleg ist sie eine Pflicht.
Dazu kommt ein zweiter, kleinerer Stillstand: Die Datenbank gilt als die Abteilung von jemand anderem, bis zu dem Tag, an dem eine Seite langsam ist und die Reparatur eine Zeile lang in einer Datei steht, die im Team niemand geöffnet hat. Ob Zeilen und Spalten überhaupt die richtige Form sind, ist eine eigene Frage und steht unter NoSQL; für einen Verein, in dem Mitglieder zu Abteilungen und Buchungen zu beiden gehören, lautet die Antwort ja.
Werkzeuge, und wo sie stehen dürfen
SQLite ist der richtige Ort zum Lernen und zunehmend auch der richtige Ort zum Ausliefern. Es ist eine einzige Datei, es braucht keinen Server, es ist gemeinfrei, und es hat die Gewohnheit abgelöst, ein eigenes Dateiformat zu erfinden und einen Leser dafür zu schreiben. Ein Verein in Hendriks Größe könnte dauerhaft darauf laufen.
PostgreSQL ist die Voreinstellung, sobald ein Server gerechtfertigt ist, es ist frei und quelloffen, und es hat diese Stellung im Lauf des letzten Jahrzehnts von MySQL übernommen. Beide verstehen EXPLAIN, beide setzen Transaktionen richtig durch, und das SQL dieses Themas wandert mit kleinen Unterschieden im Dialekt zwischen ihnen. Welches System auf einem Projekt ankommt, ist meistens entschieden, bevor jemand eingestellt wird, und darum geht es unter Die Datenbanksysteme.
Eine Frage stellt sich in Deutschland zusätzlich, und sie ist keine technische: wo die Datei liegt. Mitgliederdaten eines Vereins auf einem gemieteten Server in Nürnberg oder Falkenstein sind eine Auftragsverarbeitung mit einem Vertrag und einem Standort in der Europäischen Union, und das ist der Grund, warum deutsche kleine Betriebe und Vereine seltener bei den großen Anbietern liegen, als englische Anleitungen vermuten lassen. Wie so ein Server überhaupt bespielt wird, steht unter Softwareauslieferung.
Was hier nicht beantwortet ist: was passiert, wenn eine Maschine die Sache nicht mehr hält. Das ist ein anderes Fach mit anderen Zusagen, und dort werden genau die Garantien oben absichtlich wegverhandelt. Näher liegt für die meisten die andere Richtung, nämlich wie diese Tabellen in einen Browser kommen, und das ist Webentwicklung.