Wo das Datenbankschema tatsächlich liegt
Über die Inhalte und ihre Prüfung
In diesem Artikel
Alles, was dieser Dienst tut, steht in der Versionsverwaltung. Der Code jedenfalls. Die Datenbank, auf der er läuft, sind 32 Tabellen, und 15 davon haben nirgends im Repo eine Definition — kein CREATE TABLE, keine Schemadatei, nichts. Eine Sicherung stellt alle 32 samt Form wieder her; was im Repo fehlt, ist eine zweite, unabhängige Fassung dieser Form.
Diese Zahlen stammen aus einem Vergleich der laufenden Datenbank mit 736 Dateien und 5.671.710 Zeichen Repo. Sie sind nicht geschätzt.
Wie ein halbes Schema abhandenkommt
Es ist keine Schlamperei, und genau das macht es aufschreibenswert. Jeder einzelne Schritt war vernünftig.
Tabellen, die vor dem heutigen Code entstanden, wurden nie aufgeschrieben, weil sie damals einfach da waren. Tabellen, die seither hinzukamen, kamen über Migrationsskripte, und die stehen schon im Repo — daher stammen die 17 Definitionen. Spalten, die später dazukamen, kamen mit einem einzeiligen ALTER TABLE an der Eingabezeile, weil Tippen schneller war als ein Skript für eine Änderung, die eine Sekunde dauert.
Am schlimmsten sind die Indizes. Ein Index wird angelegt, wenn etwas langsam ist, in dem Moment, in dem es langsam ist, und er behebt das sofort. Es bleibt kein Erzeugnis zurück, nichts zum Durchsehen, nichts, was fehlschlägt, wenn es vergessen wird. Elf der zweiunddreißig Sekundärindizes hier gibt es aus genau diesem Grund, und aufgezeichnet sind sie nirgends.
Die Tabelle, in der die Zähler selbst stehen, 166.438 Zeilen davon, gehört zu den fünfzehn ohne Definition im Repo.
Was tatsächlich kaputtgeht
Wenig, bis zu einem bestimmten Augenblick: wenn die Datenbank aus einem Abzug zurückgespielt wird.
Ein Abzug trägt die Struktur mit, ein glattes Zurückspielen ist also in Ordnung. Gefährlich ist jeder Weg, der eine Tabelle neu aufbaut statt sie zurückzuspielen — ein Umzug auf eine andere Maschine, das Einspielen einzelner Tabellen, das Neuanlegen aus einem Skript. Die Daten kommen zurück, die Indizes still nicht. Nichts schlägt fehl. Die Abfragen liefern die richtigen Antworten. Sie brauchen nur länger, und die Ursache ist unsichtbar, weil die einzige Aufzeichnung dessen, was der Index war, auf der Maschine liegt, die ihn nicht mehr hat.
Das ist der Fehler, der benannt gehört: ein fehlender Index erzeugt keinen Fehler, er erzeugt eine langsamere richtige Antwort. Dafür gibt es keinen Test, denn die Tests laufen durch.
Was wir bis dahin tun
Das Schema steht heute nicht im Repo, und das ist die genaue Beschreibung der Lage. Was vorhanden ist, ist enger als eine vollständige Behebung und deckt den Fall ab, der wirklich etwas kostet:
Ein Abzug vor allem Zerstörerischen, aufbewahrt außerhalb des Web-Verzeichnisses. Ein Zurückspielen, das wirklich einmal durchgeführt wurde statt angenommen. Und eine kurze Liste, nach jedem Zurückspielen geprüft, der Indizes, die bekanntermaßen nur in der laufenden Datenbank existieren — denn die Maschine lässt sich fragen, welche Indizes sie hat, und die Antwort lässt sich mit der vom letzten Mal vergleichen.
Die allgemeine Fassung gilt für mehr als Datenbanken. Wenn ein Teil des Systems nur im laufenden System steht, gibt es keine zweite Fassung davon. Die Frage, die sich für jedes Stück Technik lohnt, ist nicht, ob es gesichert ist, sondern was sich nicht aus dem Repo wiederherstellen ließe, wenn diese Maschine verschwände. Hier lautet die Antwort fünfzehn Tabellen und elf Indizes, sie kostete einen Nachmittag, und sie ist eine Liste statt einer Unbekannten.
Aktualisierung: September 2026
Fünf Tage nach diesem Beitrag wurde der Arbeitsbaum committet: 26 Dateien und 4.058 Zeilen, darunter elf Migrationsskripte vom 28. August bis 1. September, die bis dahin nur auf der laufenden Maschine lagen. Das war die leichte Hälfte — Code, der geschrieben, aber nie festgehalten worden war.
Am 1. September 2026 wurde auf demselben Weg nachgemessen: die laufende Datenbank gegen alles, was git kennt.
| Tabellen | 46 | 30 mit CREATE TABLE im Repo, 16 ohne |
| Sekundärindizes | 43 | 32 von Code im Repo angelegt, 11 nur in der laufenden Datenbank |
| Migrationsskripte | 109 | in der Versionierung |
Die Zahl, auf die es ankommt, hat sich nicht bewegt. Am 27. August gab es elf Sekundärindizes, die nirgends außer in der laufenden Datenbank standen. Am 1. September sind es weiterhin elf. Dazwischen kamen elf weitere Indizes hinzu, und jeder einzelne kam mit einem Migrationsskript: die Gewohnheit hat sich geändert, die Altlast nicht.
Die elf sitzen auf fünf Tabellen — den Zählern, den Sprachen, den Verweisen, der Ausschlussliste und dem Ereignisprotokoll. Alle fünf sind älter als der heutige Code, und genau deshalb wurde für sie nie etwas aufgeschrieben. Jetzt eine Datei dafür anzulegen hieße, aus einem laufenden Server zu rekonstruieren, was vor Jahren an einer Eingabeaufforderung getippt wurde.
Die Lage vom August gilt also unverändert. Das Schema steht weiterhin nicht im Repo, und eine Wiederherstellung, die eine Tabelle neu baut statt sie zurückzuspielen, verlöre nach wie vor elf Indizes ohne ein Wort. Geändert hat sich das Kleinere: Alles, was seither dazukam, hat eine Datei hinterlassen.