ADMIN

2020

12

2020-11-29T12:00:00

Applikationsmanagement

PRAXIS

036

Datenbank

Datenhaltung

Lokale, dateibasierte Datenbanken mit SQLite und Firebird

Datenhaltung vor Ort

von Evgenij Smirnov

Veröffentlicht in Ausgabe 12/2020 - PRAXIS

Kennen Sie das? Sie installieren schnell mal eben lokal eine Anwendung und plötzlich bringt diese eine SQL-Express-Instanz mit oder erwartet gar, dass Sie eine solche selbst installieren und konfigurieren. Wir zeigen, wie Sie es zumindest für Ihre eigenen Hilfsprogramme besser machen können. Dabei greifen wir auf eine dateibasierte Datenhaltung zurück und behelfen uns der Tools SQLite und Firebird.

Eine relationale Datenbank ist auch für kleine Datenmengen eine feine Sache. Sie können schnell und komfortabel suchen, sortieren und gruppieren, mehrere Tabellen miteinander korrelieren und müssen sich keine Gedanken um die Konsistenz der tatsächlich auf der Festplatte gespeicherten Daten machen. Daher gehen zunehmend auch Admins, die kleine Anwendungen mit C# oder VB.NET beziehungsweise PowerShell-Skripte entwickeln, zur Nutzung von relationalen Techniken in ihrer Datenhaltung über.
Microsoft stellt mit SQL Express und der Windows Internal Database kostenlose und dennoch leistungsfähige Datenbank-Engines zur Verfügung. Auch in Visual Studio sind sie gut integriert, was die Entwicklung, gerade für .NET-Anfänger, einfacher macht. Doch die Auswirkungen auf die Infrastruktur, ihren Betrieb und die Sicherheit beim späteren Einsatz solcher Lösungen sollten jeden IT-Verantwortlichen dazu veranlassen, sich nach Alternativen umzuschauen.
Die Schattenseiten von SQL
Für die meisten lokalen Einsatzszenarien ist Microsoft SQL leistungstechnisch ein Overkill. Es bläht das System unnötig auf und eröffnet neue Herausforderungen in Bezug auf die Serverhärtung und das Patchmanagement. Es ist immer wieder faszinierend, wie IT-Teams, die lange und ausführlich über den Einsatz von Server Core diskutieren, oft kein Problem damit haben, dass eine Anwendung auf jedem Rechner eine SQL-Express-Instanz voraussetzt.
Eine relationale Datenbank ist auch für kleine Datenmengen eine feine Sache. Sie können schnell und komfortabel suchen, sortieren und gruppieren, mehrere Tabellen miteinander korrelieren und müssen sich keine Gedanken um die Konsistenz der tatsächlich auf der Festplatte gespeicherten Daten machen. Daher gehen zunehmend auch Admins, die kleine Anwendungen mit C# oder VB.NET beziehungsweise PowerShell-Skripte entwickeln, zur Nutzung von relationalen Techniken in ihrer Datenhaltung über.
Microsoft stellt mit SQL Express und der Windows Internal Database kostenlose und dennoch leistungsfähige Datenbank-Engines zur Verfügung. Auch in Visual Studio sind sie gut integriert, was die Entwicklung, gerade für .NET-Anfänger, einfacher macht. Doch die Auswirkungen auf die Infrastruktur, ihren Betrieb und die Sicherheit beim späteren Einsatz solcher Lösungen sollten jeden IT-Verantwortlichen dazu veranlassen, sich nach Alternativen umzuschauen.
Die Schattenseiten von SQL
Für die meisten lokalen Einsatzszenarien ist Microsoft SQL leistungstechnisch ein Overkill. Es bläht das System unnötig auf und eröffnet neue Herausforderungen in Bezug auf die Serverhärtung und das Patchmanagement. Es ist immer wieder faszinierend, wie IT-Teams, die lange und ausführlich über den Einsatz von Server Core diskutieren, oft kein Problem damit haben, dass eine Anwendung auf jedem Rechner eine SQL-Express-Instanz voraussetzt.
Dabei werden mehrere Hundert MByte an ausführbaren Inhalten installiert, einige dauerhaft laufende Dienste eingerichtet und – je nach Konfiguration – sogar Netzwerkports geöffnet, was für den lokalen Einsatz gar nicht nötig wäre. Es existiert eine Vielzahl von Szenarien, die eine SQL-Server-Instanz als initialen Angriffsvektor einsetzen. Damit muss auch die Security-Überwachung einer mitgebrachten SQL-Instanz den gleichen Prinzipien unterworfen sein wie die eines echten SQL-Servers.
Wenn die Applikation nicht ihre eigenen Werkzeuge zur Datenbankpflege mitbringt, müssen Sie solch eine lokale SQL-Instanz nach den gleichen Prinzipien betreiben wie einen produktiven SQL-Server. Datensicherung, Ausschlüsse aus dem Antimalware-Scan, kumulative Patches, die nicht per WSUS bereitgestellt werden – all das ist der Preis für die Einfachheit der Entwicklung.
Last but not least: Die weit verbreitete Fehlkonfiguration, bei der eine Datenbank im Wiederherstellungsmodus "vollständig" erzeugt wird, deren Transaktionsprotokolle jedoch nie abgeschnitten werden, kann Sie mit einer SQL-Express-Instanz genauso erwischen wie bei größeren Editionen. Die Größe einer Datenbank ist zwar in Express auf 10 GByte begrenzt, in diese Zahl fließen jedoch nur die MDF- und NDF-Dateien hinein – nicht aber die Logdateien mit der Endung LDF. Diese können ohne regelmäßigen Beschnitt beliebig anwachsen und die jeweilige Festplatte volllaufen lassen.
Das muss eine lokale Datenbank leisten
Strikt lokale Datenbanken haben in Microsoft-Produkten seit Windows NT einen festen Platz. Die Basis dafür bildet die "Joint Engine Technology", kurz JET. Aus der ursprünglichen Access- beziehungsweise FoxPro-Datenbanktechnologie entwickelt, reifte JET mit den Jahren zu einer robusten und performanten Speichertechnik heran. Von ihr stammt auch die "Extensible Storage Engine" (ESE) ab, die Microsoft Exchange zugrunde liegt. Dieser Umstand hat böse Zungen früher dazu veranlasst zu behaupten, Exchange würde seine Daten in Access-Datenbanken speichern.
Viele Windows-Features benutzen JET für ihre interne Datenhaltung: Active Directory, DHCP, WINS, RDS-Lizenzserver, Zertifikatsdienste und einige mehr. Für Datenhaltung von Eigenentwicklungen ist JET in Reinform aber nur bedingt geeignet, denn dafür existiert kein standardisierter Provider für .NET-basierte Programmiersprachen.
Außerdem ist das Speicher- und Zugriffsmodell von JET nicht strikt relational. JET können Sie jedoch auf zwei Weisen indirekt einsetzen: im Client-Server-Szenario mit AD LDS (Zugriff über LDAP), und filebasiert mit Access-Datenbanken (klassischerweise sind es MDB-Dateien).
Was sollte ein Entwickler oder ein skriptender Admin von einer lokalen Datenbank erwarten? Die typischen Anforderungen sind schnell zusammengefasst:
- Ein robustes, selbsterklärendes und gut dokumentiertes Programmiermodell. Ein Entwickler sollte sich nicht damit befassen müssen, wie genau die Daten seiner Datenbank in den physischen Dateien abgelegt werden.
- Portabilität der Datenbank.
- Möglichst kleiner Footprint an binären Dateien, die erforderlich sind.
- Zugriff und Betrieb auch ohne Administratorrechte.
- Datensicherung als Teil der Maschinensicherung.
- Resilienz gegenüber dem Abbruch der Applikation/des Skriptes.
Andere Anforderungen hingegen, die im klassischen Datenbankbetrieb essenziell sind, stehen beim lokalen Einsatz im Hintergrund oder sind gar nicht relevant:
- HA und Ausfallsicherheit.
- Verschlüsselung im Transit.
- Rechte- sowie Rollenmodelle für den Zugriff.
- Sauberes Locking bei Multiuser-Zugriff.
- Online-Datensicherung im laufenden Betrieb.
- Resilienz gegenüber Schwankungen oder Unterbrechungen im Netzwerk.
Sehen Sie sich diese Listen einmal genau an, wird noch einmal deutlich, dass Microsoft SQL – selbst als Express oder WID – zwar vieles mitbringt, was die zweite Kategorie ausmacht, jedoch viele Merkmale der ersten Kategorie vermissen lässt. In einem Punkt ist SQL jedoch unschlagbar: Jede .NET-Installation enthält von Hause aus den Namespace für den Zugriff auf SQL-Daten: System.Data.SQLClient. Zu diesem existieren eine sehr gut gepflegte und umfangreiche Dokumentation [1] und Unmengen von Beispielcode in allen auf .NET basierenden Sprachen.
XML und JSON für die Konfiguration
Wer Daten programmatisch in Dateien abspeichern und wieder auslesen muss, dürfte schnell auf die universell verfügbaren strukturierten Formate XML (eXtensible Markup Language) und JSON (JavaScript Object Notation) stoßen. Beide eignen sich vorzüglich dafür, Konfigurationen oder Stammdaten zu speichern, die zu Beginn der Ausführung komplett in den Speicher eingelesen und – falls sie verändert wurden – in einem Stück wieder in die jeweilige Datei ausgegeben werden.
Beide Formate sind so weit "menschenlesbar", dass sich kleine Anpassungen auch per Hand mittels eines Texteditors vornehmen lassen. XML punktet mit der Möglichkeit, die Daten mit Eigenschaften wie Datentypen oder Zeitstempeln anzureichern. JSON hingegen bietet eine potenziell höhere Kompatibilität und Portierbarkeit – gerade dadurch, dass die Daten selbst das Datenschema definieren.
Es gehört zum guten Programmierstil, die für die Verbindung zur herkömmlichen Datenbank erforderlichen Daten nicht im Quell- oder Skriptcode, sondern in einer JSON- oder XML-Datei zu hinterlegen. Bei C#-Anwendungen ist dafür die Datei "<Anwendungsname>.config vorgesehen, die im gleichen Pfad wie das Kompilat erzeugt wird und dem XML-Format folgt.
Für die klassischen Aufgaben einer Datenbank wie das Sortieren, Gruppieren, Suchen und so weiter eignen sich beide Formate nur bedingt – diese Vorgänge müssen Sie mit den in den Arbeitsspeicher eingelesenen Daten durchführen. Haben sich die Daten in der Datei seit dem Einlesen durch einen anderen Programmzweig oder einen anderen Prozess verändert, stehen diese Änderungen erst ab dem nächsten vollständigen Einlesen zur Verfügung.
Über einen Adapter lässt sich XML in ADO.NET integrieren [2]. Die Programmierlogik ist hier jedoch anders als bei SQL-Aufrufen und lässt sich auch nicht 1:1 von oder nach SQL übersetzen. Zudem lässt die Performance solcher Abfragen oft zu wünschen übrig, vor allem bei größeren Datenmengen.
Ergänzend sei erwähnt, dass es durchaus ausgewachsene Produkte wie BaseX oder Sedna (XML) beziehungsweise CouchBase oder MariaDB (JSON) auf dem Markt gibt, die strukturierten Plain-Text als Grundlage für die Datenspeicherung verwenden. Dies sind jedoch in der Regel vollwertige Client-Server-Datenbanksysteme, die nicht für die rein lokale Verwendung optimiert sind.
SQLite: Beim Browser abgeschaut
Bei der Suche nach einer geeigneten Datenbank für die lokale Speicherung von Bewegungsdaten lohnt sich der Blick unter die Motorhaube bei einer Gattung von Anwendungen, die diese Anforderung bereits seit Jahrzehnten erfüllen müssen: Webbrowser. Neben persistenten, vom Nutzer explizit erzeugten Daten wie den Favoriten (Lesezeichen) gilt es, weitere Datenarten zwischenzuspeichern, die beim Browsen entstehen:
- Cookies
- Formulardaten (Autovervollständigung)
- heruntergeladene Inhalte (Cache)
- Zuordnungen von Webseiten zu Sicherheitszonen
- Zertifikate
Haben die frühen Browsergenerationen dafür auf einzelne kleine Dateien (Internet Explorer) oder proprietäre und notorisch unzuverlässige Formate wie MORK (Mozilla-Produkte) gesetzt, so konvergiert inzwischen die Datenspeicherung in fast allen Browsern zu einer Kombination aus JSON (wenig bewegliche Stammdaten in geringen Mengen) und SQLite (bewegliche Bewegungsdaten in größeren Mengen) – ein Grund, sich SQLite auch für die eigene Verwendung genauer anzuschauen. In den folgenden Abschnitten werden wir die Einbindung am Beispiel der PowerShell demonstrieren. Das lässt sich problemlos auf alle anderen auf .NET beruhenden Sprachen übertragen.
SQLite [3] ist ein aktiv gepflegtes Open-Source-Produkt, das eine hohe Kompatibilität zu SQL-Standards bei komplett lokaler Ausführung mit wenig Ressourcenbedarf verspricht. Es steht in der Public Domain bereit, sie dürfen es also frei in Ihren Entwicklungen einsetzen.
Die Einbindung von SQLite in Ihren Quellcode ist schnell erledigt. Laden Sie von [4] die "Precompiled Binaries" für die gewünschte .NET- und Bit-Version herunter und entpacken Sie das ZIP-Archiv in einen Pfad Ihrer Wahl. Je nach Version benötigen Sie Visual-Studio-Redistribu-tables, die Sie auf Ihrem System installieren müssen, falls dies nicht bereits andere Anwendungen vorgenommen haben. Das Paket enthält eine Menge Dateien; für die Integration in PowerShell-Skripte brauchen Sie jedoch lediglich "System.Data.SQLite.dll", jeweils in 32 oder 64 Bit. Für ein Visual-Studio-Projekt sollten Sie einfach das aktuelle NuGet-Paket aus dem offiziellen Repository importieren.
Ist die DLL am richtigen Ort vorhanden, fügen Sie Ihrem Skript einfach den Befehl
Add-Type -Path <Pfad>\System.Data.SQLite.dll
hinzu. Danach steht Ihnen der Namespace "System.Data.SQLite" in Ihrer Umgebung zur Verfügung, dessen Objektschema Ihnen sehr bekannt vorkommen dürfte, wenn Sie bereits ADO.NET mit Microsoft SQL verwendet haben.
Der für die Verbindung zu einer SQLite-Datenbank erforderliche Connection String ist einfach und beläuft sich auf die Pfadangabe:
Data Source=<Pfad>;Version=3;
wobei Sie die Versionsangabe auch weglassen können, da die DLL nur die Version 3 unterstützt. Wollen Sie die SQLite-Datenbank nur für temporäre, dafür aber superschnelle Verarbeitung von Umlaufdaten einsetzen, können Sie diese im Arbeitsspeicher ansiedeln:
Data Source=:memory:
Weitere nützliche Parameter, die Sie für die Verbindung zu einer SQLite-Datenbank verwenden können, liefert [5].
Das Arbeiten mit SQLite verläuft ähnlich wie mit SQL Server. Mit dem Code aus Listing 1 erzeugen Sie eine Datenbank mit zwei Tabellen.
Listing 1: SQLite-Datenbank anlegen
Add-Type -Path "System.Data.SQLite.dll" $conn = New-Object System.Data.SQLite.SQLiteConnection $conn.ConnectionString = "Data Source=C:\TEMP\MyFirstDB.sqlite" $conn.Open() $cmd = $conn.CreateCommand() $cmd.CommandText = "CREATE TABLE Tabelle1 (id INTEGER PRIMARY KEY AUTOINCREMENT, textzeile VARCHAR(255))" $cmd.ExecuteNonQuery() $cmd.CommandText = "CREATE TABLE Tabelle2 (id INTEGER PRIMARY KEY AUTOINCREMENT, langezahl BIGINT, kurzertext VARCHAR(10))" $cmd.ExecuteNonQuery() $cmd.Dispose() $conn.Close()
Die entstandene Datei hat den Umfang von wenigen KByte – kein Wunder, sie enthält ja noch keine Nutzdaten. Diese fügen Sie wie im Listing 2 ersichtlich auf die gleiche Art und Weise in die Tabellen ein, wie die Tabellenstruktur erzeugt worden ist. Der Beginn und das Ende sind analog zum ersten Skript.
Listing 2: SQLite-Datenbank befüllen
$cmd.CommandText = "INSERT INTO Tabelle1 (textzeile) VALUES ('erste zeile')" $cmd.ExecuteNonQuery() $cmd.CommandText = "INSERT INTO Tabelle1 (textzeile) VALUES ('zweite zeile')" $cmd.ExecuteNonQuery() $cmd.CommandText = "INSERT INTO Tabelle2 (langezahl,kurzertext) VALUES (42,'zweiund40')" $cmd.ExecuteNonQuery()
Für das Auslesen der Daten verwenden Sie wie im Listing 3 dargestellt das übliche DataReader-Objekt. Auch hier sind der Beginn und das Ende wieder analog zum ersten Skript.
Listing 3: SQLite-Datenbank auslesen
$cmd.CommandText = "SELECT * FROM Tabelle1" $rdr = $cmd.ExecuteReader() if ($rdr.HasRows) {     while ($rdr.Read()) {                  $rdr['id']                  $rdr['textzeile']     } } $rdr.Close() $rdr.Dispose()
Achten Sie darauf, dass Sie die Datenbankobjekte korrekt schließen (.Close()) und entsorgen (.Dispose()) – sonst kann es passieren, dass die SQLite-Datei auch nach Beendigung des Skriptes gesperrt bleibt.
Falls Sie die Daten in Ihrer SQLite-Datenbank einmal grafisch untersuchen oder bearbeiten möchten, steht Ihnen der kostenlose DB Browser [6] zur Verfügung. Das Programm für Windows hat eine installierbare und eine portable Variante. Zudem existiert eine Version für macOS.
Lightweight-Klassiker Firebird
Ein absoluter Klassiker für kleine, leichtgewichtige Datenbanken ist das im Jahr 2000 aus Borlands InterBase-Projekt hervorgegangene Firebird. Von einigen belächelt, von vielen geliebt, hat es sich in den 20 Jahren seiner Geschichte zu einem absolut Enterprise-fähigen System mit einer stabilen Fan- und Entwicklergemeinde gemausert, das auf vielen Plattformen verfügbar ist, darunter die meisten UNIX-Derivate.
Mit DB Browser können Sie SQLite-Daten visuell bearbeiten.
Für unsere Zwecke ist die Deployment-Variante "Embedded" von Interesse. Dabei handelt es sich um eine DLL, die Client- und Serverfunktionalität in sich vereint. Sie müssen hier nichts installieren, sondern nur die Datei "fbembed.dll" nebst einigen Begleitdateien in einen bekannten Pfad auf dem System kopieren. Firebird erhalten Sie unter [7]. Beachten Sie, dass die Embedded-Variante derzeit noch nicht in der aktuellen Version 3.0, sondern nur in der letzten unterstützten Vorgängerversion 2.5.9 zur Verfügung steht.
Auch für Firebird existiert ein ADO.NET-Provider, den Sie sowohl als NuGet-Paket für Ihr Visual-Studio-Projekt als auch in Form eines direkten Downloads von der offiziellen Webseite beziehen können. Die Dokumentation dieser Bibliothek ist bei weitem nicht so ausgereift wie bei Microsoft SQL oder SQLite. Das ist umso bedauerlicher, weil es im Umgang mit Firebird diverse Eigenarten gibt. Allein schon der standardmäßige Connection String [8] spricht eine klare Sprache: Firebird ist etwas für Menschen, die wissen, was sie tun.
Für die Einbindung von Firebird in Ihre Skripte kopieren Sie das entpackte Paket mit "fbembed.dll" und ADO.NET-Provider "FirebirdSql.Data.FirebirdClient.dll" in dasselbe Verzeichnis auf Ihrer Maschine. Danach können Sie mit
Add-Type -Path <Pfad>\FirebirdSql.Data.FirebirdClient.dll
den entsprechenden Namespace zu Ihrer PowerShell-Umgebung hinzufügen.
An erster Stelle steht die Erzeugung einer Datenbank. Dafür nutzen Sie die in Listing 4 dargestellte Methode. Dabei verbleiben keine zu schließenden Datenbankobjekte. Wie Sie deutlich sehen, müssen Sie auch im lokalen Betrieb Name und Kennwort angeben. Somit ist es später möglich, Zugriffe einzelner Skript- oder Programmteile durch Vergabe von Benutzerrechten zu beschränken.
Listing 4: Erzeugen einer Firebird-Datenbank
Add-Type -Path "<Path>\FirebirdSql.Data.FirebirdClient.dll" $connstr = New-Object FirebirdSql.Data.FirebirdClient.FbConnectionStringBuilder $connstr.ServerType = [FirebirdSql.Data.FirebirdClient.FbServerType]::Embedded $connstr.Database = "c:\temp\MyFirstFirebird.fdb" $connstr.DataSource = "localhost" $connstr.UserID = "SYSDBA" $connstr.Password = "masterkey" [FirebirdSql.Data.FirebirdClient.FbConnection]::CreateDatabase($connstr.ConnectionString,8192,$true,$true)
Aber Achtung: Eine Firebird-Datenbank muss zwingend auf einem lokalen Laufwerk liegen. Netzwerkpfade jeglicher Couleur finden keine Unterstützung. Das müssen Sie bedenken, wenn Sie die betroffene Datenbank pro Benutzer speichern und Ordnerumleitung aktiv ist.
Möchten Sie nun in der neu erzeugten Datenbank (die im leeren Zustand bereits 1,3 MByte misst) Tabellenstruk­turen und Daten anlegen, gilt es, eine weitere Besonderheit von Firebird zu beachten: Alle Operationen, lesend wie schreibend, müssen als Teil einer Transaktion erfolgen. Bei schreibenden Operationen werden die Daten erst in der Datenbank persistiert, wenn die Transaktion durchgeführt wird (Commit). Es besteht aber zudem die Möglichkeit, sie unerledigt zu verwerfen (Rollback).
 Die Anlage und Erstbestückung einer Tabelle sieht aus wie im Listing 5 beschrieben. Der Beginn entspricht dem ersten Skript.
Listing 5: Anlegen einer Firebird-Tabelle
$conn = New-Object FirebirdSql.Data.FirebirdClient.FbConnection($connstr.ConnectionString) $conn.Open() $tropt = New-Object FirebirdSql.Data.FirebirdClient.FbTransactionOptions $trans = $conn.BeginTransaction($tropt) $cmd = New-Object FirebirdSql.Data.FirebirdClient.FbTransactionOptions $cmd.Connection = $conn $cmd.Transaction = $trans $cmd.CommandType = [System.Data.CommandType]::Text $cmd.CommandText = "CREATE TABLE TEST01 (id BIGINT, text VARCHAR(255));" $cmd.ExecuteNonQuery() $trans.Commit() $trans.Dispose() $cmd.Dispose() $trans = $conn.BeginTransaction($tropt) $cmd = New-Object FirebirdSql.Data.FirebirdClient.FbCommand $cmd.Connection = $conn $cmd.Transaction = $trans $cmd.CommandType = [System.Data.CommandType]::Text $cmd.CommandText = "INSERT INTO TEST01 (id, text) VALUES (1, 'Zeile 1');" $cmd.ExecuteNonQuery() $cmd.CommandText = "INSERT INTO TEST01 (id, text) VALUES (2, 'Zeile 2 Zeile 2')" $cmd.ExecuteNonQuery() $cmd.CommandText = "CREATE TABLE Tabelle2 (id INTEGER PRIMARY KEY AUTOINCREMENT, langezahl BIGINT, kurzertext VARCHAR(10))" $cmd.ExecuteNonQuery() $trans.Commit() $trans.Dispose() $cmd.Dispose() $conn.Close() $conn.Dispose()
Das Semikolon am Ende jeder SQL-Anweisung ist eine der Eigenarten der SQL-Implementierung in Firebird. Es ist nicht per se falsch, Sie können es jedoch bei den meisten anderen Dialekten weglassen. Das Lesen aus der Datenbank geschieht analog, bedarf jedoch ebenfalls der Einbettung in eine Transaktion, die Sie am Ende natürlich nicht abschließen müssen.
Firebird ist eine gute Wahl, wenn Sie sich vorstellen können, die Datenbank irgendwann zu skalieren und mittels des Firebird-Super-Server hochperformant und ausfallsicher zentral zur Verfügung zu stellen. FDB-Dateien lassen sich dafür einfach kopieren und in den Bestand des Super-Servers einbinden.
Link-Codes
[3] Homepage SQLite: https://sqlite.org/index.html
[5] SQLite – Connection Strings: https://www.connectionstrings.com/sqlite/
[6] DB Browser für SQLite: https://sqlitebrowser.org/
[7] Firebird – Downloads: https://firebirdsql.org/en/firebird-2-5-9/
Wenn es doch einmal SQL sein muss
Trotz allem bisher Gesagten überwiegen manchmal Gründe für den Einsatz von Microsofts SQL-Technologie. Typische Szenarien sind:
- Es ist geplant, die Anwendung oder das Skript mit gemeinsamer Datenhaltung in die Breite zu skalieren.
- Es existiert schon eine große Vielzahl an Eigenentwicklungen und Third-Party-Anwendungen, die SQL lokal einsetzen, und das IT-Team hat bereits Erfahrung im Betrieb derart verteilter SQL-Instanzen.
- Es herrschen strenge Regeln für den Einsatz neuer, bisher in der Umgebung noch nicht verwendeter Produkte. Spätestens mit dem Upgrade auf Edge Chromium kann allerdings niemand mehr behaupten, dass SQLite nicht zum Einsatz kommt.
In diesem Fall sollten Sie versuchen, die lokalen SQL-Instanzen sowohl bei Ihren eigenen Entwicklungen als auch bei Third-Party-Applikationen auf einem zentralen SQL-Cluster zu konsolidieren. Dort können Sie von allen Vorteilen wie zentraler Sicherung, Hochverfügbarkeit, Zugriffsbeschränkungen und so weiter profitieren und müssen sich beim Patchen keine Gedanken um lokale SQL-Instanzen auf Dutzenden von Anwendungsservern machen.
Da Microsoft SQL ohnehin keinen "lokalen Modus" kennt, sollte die notwendige Anpassung an den Applikationen und Skripten kein Problem darstellen, sofern Sie an die Konfigurationsdateien oder Registry-Einträge herankommen, die den Connection String beinhalten. Die Datenbanken verschieben Sie am besten über Backup und Restore.
Aber aufgepasst: In Microsoft SQL können Sie keine Datenbank von einer neueren in eine ältere Version verschieben. Denken Sie daran, falls Sie sich den Weg zurück in die lokalen Instanzen nicht verbauen wollen.
Fazit
Wenn Sie bei Ihren Eigenentwicklungen auf relationale Datenbanken für lokale Datenhaltung setzen möchten, sollten Sie sich gut überlegen, ob Microsoft SQL wirklich die beste Wahl ist. Je nach Anforderungen an Portabilität und Integration mit anderen Verfahren eignen sich dateibasierte Datenbanken wie SQLite und Firebird Embedded unter Umständen deutlich besser.
ADO.NET bietet dem Entwickler eine gute Plattform, um den Datenbankzugriff mit ähnlichen Methoden abzu­bilden. Dennoch hat jede Datenbank-Engine ihre Eigenarten.
Für Konfigurationen, die fast immer nur gelesen werden und einfache Datenstrukturen abbilden, eignen sich die klassischen Textformate wie XML und JSON. Zumindest die Verbindung zum Datenbankspeicher Ihrer Wahl sollte in solch einer Konfigurationsdatei und nicht im Quellcode Ihrer Anwendung stehen. Denken Sie bei allen Datenbank-Techniken daran, die verwendeten Ressourcen aufzuräumen, um offene Handles, Memory Leaks und gesperrte Dateien zu vermeiden.
Wenn der Einsatz von Microsoft SQL tatsächlich geboten ist, sollten statt lokaler Instanzen lieber Datenbanken auf zentralen Servern Ihrer Organisation zum Einsatz kommen.
(ln)