Die SQL-IDE verwaltet derzeit (Stand Dezember 2025) ca. 33500 Datenbanken von ca. 10000 Usern. Zu Spitzenzeiten (d.h. wochentags am Vormittag) gibt es ca. 150 User, die gleichzeitig online sind. Bei der Speicherung der Datenbanken kommt Deduplizierung zum Einsatz, daher ist die serverseitig notwendige Speicherkapazität relativ gering (derzeit ca. 500 MB).
Da die Entwicklung der SQL-IDE erst zwei Jahre nach dem Start der Online-IDE begann, war die Größenordnung der zu erwartenden Zahl an Usern (und damit auch Datenbanken) schon abschätzbar.
Es läge nahe, serverseitig eine Instanz von MariaDB oder Postgres zu installieren und in dieser - je nach Bedarf - die Datenbanken der User anzulegen. Alle an den Clients eingegebenen SQL-Statements der User werden per http-Request zum Server übermittelt, dort in der entsprechenden User-Datenbank ausgeführt, die Ergebnistabelle wird zurückgeliefert und am Client angezeigt.
Diese Architektur erschien aus folgenden Gründen problematisch:
Grobe Abschätzungen und kurze Testläufe ergaben, dass die Miete eines deutlich stärkeren Servers notwendig gewesen wäre, um mit dem aufgrund von b) zu erwartenden Traffic umzugehen. Damit wäre d) nicht machbar gewesen. Zudem stellte sich heraus, dass c) schwer umsetzbar war und die Unsicherheit a) konnte nicht abschließend beseitigt werden.
Der Ansatz wurde daher verworfen.
Auf der Suche nach einem Datenbanksystem, das sich innerhalb der Client-Browser ausführen ließ, stieß ich auf SQL.js, eine Implementierung von SQLite, die im Browser läuft und sich per Javascript-API steuern lässt. Der Grundgedanke war, die User-Datenbanken serverseitig als Binärdatei im SQLite-Format zu speichern, beim Selektieren der Datenbank an die Clients auszuliefern, alle SQL-Statements dort auszuführen und - im Falle datenverändernder SQL-Statements - die veränderte Datenbankdatei als Ganzes wieder zurück zum Server zu senden und dort zu speichern. Dem standen folgende Schwierigkeiten im Weg:
Der Server speichert User-Datenbanken immer in zwei Teilen:
Wählt ein User die Datenbank in der SQL-IDE aus, so passiert folgendes:
Die getrennte Speicherung der "Grunddatenbank" und aller durch den User ausgeführten datenverändernden Statements ermöglicht es u.a., ausgeführte Statements auch nach Tagen wieder rückgängig zu machen (Rollback). Erreicht wird das dadurch, dass
Sowohl die Selektion einer Datenbank als auch das Rollback erfolgen selbst bei hunderten von SQL-Statements so schnell, dass sie von den Usern i.d.R. nicht als langsam empfunden werden.
Gibt ein User eine SQL-Anweisung ein und klickt auf den Ausführen-Button, so passiert folgendes:
Als Editor wird der Monaco Editor von Microsoft verwendet, der auch in Visual Studio Code zum Einsatz kommt. Die semantischen Informationen, die nötig sind, um bspw. kontextsensitive Codevervollständigung anzubieten oder Fehler schon bei der Texteingabe zu unterringeln, erhält der Editor von einem eigens für die SQL-IDE implementiertn SQL-Compiler. Im Gegensatz zu SQLite arbeitet dieser typisiert und nah am SQL-Standard, sodass beim User der Eindruck entsteht, Statements für einen voll SQL-konforme Datenbank zu schreiben. Der Compiler nutzt als Eingabe nicht nur das aktuell vom User bearbeitete SQL-Statement, sondern auch die Strukturdaten der aktuell selektierten Datenbank.
Klickt der user auf den Button "Statement ausführen", wird das gerade im Cursorbereich befindliche Statement mithilfe des vom Compiler generierten Abstract Syntax Tree aus der Menge der im Editor befindlichen Statements herausgeschält und - im Falle datenverändernder Statements - so verändert, dass es der Syntax von SQLite entspricht. Zudem werden CREATE TABLE-Statements um SQLite-spezifische check-Anweisungen erweitert, die sicherstellen, dass die gespeicherten Datensätze den definierten Spaltentypen entsprechen.