Datenbanken automatisch komprimieren

In vielen Datenbankanwendungen fallen temporäre Daten an, also Daten, die in Tabellen geschrieben und in der gleichen Session wieder gelöscht werden. Das kann sowohl in nicht aufgeteilten Datenbanken als auch in aufgeteilten Datenbanken mit Frontend und Backend geschehen. Man könnte denken, die Größe der Datenbankdatei würde nach dem Anfügen und Löschen von Daten einigermaßen konstant sein. Das ist jedoch nicht der Fall: Gelöschte Daten sind zwar nicht mehr in den Tabellen zu finden, allerdings benötigt die Datenbank anschließend ungefähr genauso viel Speicherplatz wie vor dem Löschen. Wie das zu erklären ist und wie wir durch die Komprimierung einer Datenbank dennoch dafür sorgen können, dass eine Datenbank sich durch die Verwendung temporärer Daten nicht übermäßig aufbläht, beschreiben wir in diesem Beitrag.

Beispieldatenbank erzeugen

Wenn wir das Verhalten von Access-Datenbanken beim Anlegen und Löschen von Daten und beim Komprimieren der Datenbank untersuchen wollen, brauchen wir die Möglichkeit, schnell Daten hinzuzufügen und zu entfernen – und natürlich eine Tabelle, in der wir die Daten speichern.

Die Tabelle soll tblTexte heißen und neben dem Primärschlüsselfeld ID ein Textfeld namens Beispieltext mit einer Feldgröße von 255 Zeichen enthalten (siehe Bild 1).

Tabelle für Beispieldaten

Bild 1: Tabelle für Beispieldaten

Zum Anlegen einer relevanten Menge von Daten verwenden wir die folgende Prozedur:

Public Sub TabelleFuellen()
     Dim db As DAO.Database
     Dim i As Long
     Set db = CurrentDb
     For i = 1 To 10000
         db.Execute "INSERT INTO tblTexte(Beispieltext)  VALUES(''1234567890...12345'')", dbFailOnError
     Next i
End Sub

Diese legt 10.000 Datensätze mit jeweils 255 Zeichen an. Um die Datensätze schnell wieder zu löschen, verwenden wir die folgende Prozedur:

Public Sub TabelleLeeren()
     Dim db As DAO.Database
     Set db = CurrentDb
     db.Execute "DELETE FROM tblTexte",  dbFailOnError
End Sub

Führen wir die erste Prozedur für eine bis dahin leere Datenbank aus, erhalten wir eine Datenbankgröße von ungefähr 3.264 KB.

Untersuchen der Datenbankgröße nach dem Löschen der Daten

Anschließend führen wir die zweite Prozedur aus und löschen damit alle Datensätze der Tabelle tblTexte. Schließen wir danach die Datenbank, bleibt die Dateigröße erhalten – obwohl die Tabelle keine Daten mehr enthält.

Platz für gelöschte Daten wird erst beim Komprimieren freigegeben

Der Grund für dieses Verhalten ist, dass der Speicherplatz erst nach dem Komprimieren einer Datenbank freigegeben wird. Also öffnen wir die Datenbank mit der leeren Tabelle erneut und rufen für diese den Befehl Datenbank komprimieren und reparieren auf (unter Access 365 beispielsweise unter Datei|Informationen zu finden).

Betrachten wir anschließend erneut die Dateigröße, weist diese wieder um die 400 KB aus. Daraus können wir ableiten: Der Speicherplatz für gelöschte Datensätze wird erst nach dem Komprimieren der Datenbank freigegeben.

Automatische Komprimierung aktivieren

Für monolithische Access-Anwendungen, also solche, die nur aus einer einzigen Datenbankdatei und nicht aus Frontend und Backend bestehen, können wir in den Access-Optionen die Option Beim Schließen komprimieren aktivieren (siehe Bild 2).

Aktivieren der automatischen Komprimierung

Bild 2: Aktivieren der automatischen Komprimierung

Füllen wir die Tabelle wieder mit Daten und löschen diese erneut, finden wir gleich nach dem nächsten Schließen wieder die geringe Dateigröße von rund 400 KB vor.

Komprimierung bei aufgeteilten Datenbanken

Nun teilen wir die Beispieldatenbank in Frontend und Backend auf, was am schnellsten mit dem Menübefehl Datenbanktools|Daten verschieben|Access-Datenbank gelingt. Hier brauchen wir nur den Pfad zur neuen Backenddatenbank anzugeben. Das Ergebnis ist eine neue Backenddatenbank, in welche die einzige Tabelle der bisher verwendeten Datenbank verschoben wurde, sowie eine Verknüpfung zu dieser Tabelle in der aktuellen Datenbankdatei.

Erstere nennen wir nun BackendKomprimieren_FE.accdb, letztere BackendKomprimieren_BE.accdb.

Anlegen und Löschen in Frontend und Backend

Die Frontenddatenbank mit der Tabellenverknüpfung und das Backend mit der leeren Tabelle haben wir nun zunächst komprimiert. Die Größen lauteten danach:

  • Frontend: 432 KB
  • Backend: 348 KB

Anschließend rufen wir die Prozedur zum Anlegen der 10.000 Datensätze in der Tabelle tblTexte auf. Dabei fällt zuerst auf, dass der Vorgang viel länger dauert als in der monolithischen .accdb-Datei. Noch viel interessanter ist die Beobachtung des benötigten Speicherplatzes für die beiden Dateien:

  • Frontend: 40.412 KB
  • Backend: 3.208 KB

Der Teil mit der Tabelle ist also ähnlich gewachsen wie zuvor, aber das Frontend ist massiv größer geworden – es wächst um mehr als den zehnfachen Speicherplatz der eigentlich erzeugten Daten. Obwohl es noch nicht einmal eine von uns angelegte Tabelle mit Daten enthält. Die Größe ändert sich auch nach dem Schließen nicht.

Anschließend haben wir die Prozedur zum Schreiben der Daten erneut aufgerufen, um zu prüfen, ob wir das Frontend so bis zur Grenze von 2 GB aufblähen können. Das ist jedoch nicht der Fall: Beim zweiten Durchlauf wird die Frontenddatenbank nur noch unwesentlich vergrößert, während das Backend seine Größe wie erwartet um ca. 2.800 KB ändert.

Wachstum des Frontends

Zum Wachstum der Größe des Frontends noch folgende Anmerkung: Dies geschieht nur, wenn wir die Daten per VBA in die Tabelle tblTexte des Backends einfügen. Wir haben in einem zweiten Versuch manuell mehrere tausend Datensätze dort eingefügt und in diesem Fall wurde zwar das Backend vergrößert, nicht jedoch das Frontend.

Komprimieren des Frontends

Komprimieren wir nun das Frontend, wird dieses wieder auf die ursprüngliche Größe geschrumpft. An der Größe des Backends ändert sich zunächst nichts, was auch nicht zu erwarten war, da wir die enthaltenen Daten nicht gelöscht haben. Also öffnen wir das Frontend erneut und löschen die Daten im Backend mit der Prozedur TabelleLeeren.

Die Größe des Backends bleibt erhalten. Nun rufen wir in der Frontenddatenbank den Befehl Komprimieren und Reparieren auf. Obwohl wir die Daten im Backend gelöscht haben, ändert sich dessen Speicherbedarf nicht.

Wenn wir das Frontend einer Kombination aus Frontend und Backend komprimieren, wird also nur der Speicherplatz im Frontend freigegeben, der für das Schreiben von Datensätzen im Backend angefallene Daten verwendet wurde.

Backend komprimieren

Wie also können wir nun dafür sorgen, dass der Speicherplatz für im laufenden Betrieb angelegte und wieder gelöschte Daten im Backend wieder freigegeben wird? Immerhin darf das Backend nicht größer als 2 GB werden, was bei solchen Operationen schnell geschehen kann.

Öffnen wir das Backend ohne das Frontend und komprimieren es nach dem Löschen der Daten mit dem dafür vorgesehen Befehl Komprimieren und Reparieren, erhält es wieder seine ursprüngliche Dateigröße.

Backend beim Schließen komprimieren

Die Vermutung liegt nahe, dass wir nur für das Backend die Option Beim Schließen komprimieren einstellen müssen, damit dieses beim Schließen des Frontends automatisch komprimiert wird.

Dies führt allerdings nicht zum Erfolg. Nach dem Einstellen dieser Option und dem Schreiben und Löschen der Daten über das Frontend erhält das Backend nicht wieder die Größe der Datenbank mit der geleerten Tabelle.

Woran liegt das? Offensichtlich findet beim Zugriff auf das Backend über die Tabellenverknüpfungen kein Öffnen und Schließen der Backenddatenbank in dem Sinne statt, dass dabei die für das Schließen aktivierte Komprimierung ausgelöst wird.

Wir müssen also einen anderen Weg finden, um das Backend zu komprimieren.

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

den kompletten Artikel im PDF-Format mit Beispieldatenbank

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar