Jeder kennt diese Kompressionsprogramme wie gzip, arj, (win)zip, 7z und noch mehr. Sie sind praktisch, um Daten platzsparend aufzubewahren, bandbreitensparend zu übermitteln oder auch einfach nur um Daten zu einer Datei zusammenzupacken. Dabei hat die letzte Aufgabe eigentlich gar nicht viel mit Kompression zu tun, wird aber von manchen Werkzeugen zusätzlich zur Kompression auch noch unterstützt. Ein weniger bekannter Grund für Kompression, der aber recht wichtig ist, ist im Bereich der Kryptographie. Wenn man Daten vor der Verschlüsselung komprimiert, ist es schwieriger, den Schlüssel zu erraten.
Witzigerweise hat sich in der Linux-Welt als Archivformat das .tar.gz-Format weit verbreitet, während in der MS-Windows-Welt eher die zip-Dateien üblich sind, obwohl beide Formate auf beiden Plattformen relativ gut unterstützt werden:
Unter Linux kann man zwei Programme, zip und unzip finden oder einfach installieren, die ZIP-Dateien erzeugen und auspacken. Unter MS-Windows kann man z.B. cygwin installieren und hat dann auch tar und gzip dabei, oder man kann mit Winzip auch tar.gz-Dateien zumindest auspacken.
Hinter diesen beiden Formaten und den zugehörigen Werkzeugen stehen zwei verschiedene Ansätze. In der Linux-Welt und früher noch mehr in der Unix-Welt war es üblich, Werkzeuge zu haben, die eine Aufgabe sehr gut erfüllen und die sich mit anderen Werkzeugen kombinieren lassen. Herausgekommen ist gzip, das nur eine einzelne Datei oder einen Datenstrom komprimiert, nicht aber mehrere Dateien in ein Archiv zusammenführt, wofür andere Werkzeuge, z.B. tar herangezogen werden können. Man kann das aber mit einem Aufruf erledigen, indem man tar mit einer Option mitgibt, das das Archiv nach der Erstellung noch durch gzip geschickt werden soll oder vor dem Lesen durch gunzip. Dagegen mach zip alles in einem Werkzeug.
Bei genauerem Hinsehen gibt es aber noch eine subtilen, aber doch manchmal wichtigen Unterschied, der eigentlich wenig mit der Frage zu tun hat, ob man ein Werkzeug hat, das beide Aufgaben verbindet.
Im ZIP-Format werden die Dateien einzeln komprimiert und dann die komprimierten Dateien zu einem Archiv zusammengefügt. Bei .tar.gz ist es umgekehrt. Oft ist die Wahl durch Gewohnheiten oder durch Kommunikationspartner ein Stück weit eingeschränkt, aber es lohnt sich doch, diesen Unterschied zu kennen: Beide Ansätze haben ihre Vorteile in verschiedenen Situationen und deshalb ist es eigentlich gut, dass man auf beiden Plattformen auch beide verwenden kann.
Der Vorteil, erst zu archivieren und das Archiv zu komprimieren ist einfach, dass man dabei eine bessere Kompression erzielen kann. Da die Kompression ja darauf basiert, irgendwelche Gemeinsamkeiten, Regelmäßigkeiten oder allgemein Redundanzen von verschiedenen Sequenzen innerhalb der komprimierten Datei zu finden, ist es plausibel anzunehmen, dass man die Kompression manchmal verbessern kann, wenn dies über alle archivierten Dateien gemacht werden kann und nicht nur über die einzelnen archivierten Dateien. Als Beispiel habe ich einmal das /bin-Verzeichnis komprimiert:
$ ls -l bin.tar.gz bin.zip
-rw-r--r-- 1 bk1 brodowsky 3909375 2013-06-20 22:23 bin.tar.gz
-rw-r--r-- 1 bk1 brodowsky 7568659 2013-06-20 22:24 bin.zip
Man sieht also, dass die Wiederholungen und Ähnlichkeiten zwischen den Dateien dazu führen, dass trotz gleichem Kompressionsalgorithmus die tar.gz-Datei nur etwa halb so groß wie die zip-Datei ist.
Der Vorteil, erst zu komprimieren und dann die einzelnen komprimierten Dateien zu archivieren besteht darin, dass man leichter auf einzelne Dateien aus dem Archiv zugreifen kann. Bei tar.gz muss man alles vom Anfang bis zu der gesuchten Datei dekomprimieren, im Durchschnitt also etwas mehr als die Hälfte des Archivs, bei zip nur die eine Datei, die man wirklich will. Aus diesem Grunde wurde das zip-Format auch für die Programmiersprache java verwendet, um die Bibliotheken (jar-Dateien) zu speichern. Das sind ZIP-Dateien mit einem zusätzlichen Verzeichnis META-INF, das Metainformationen enthalten kann. Man kann jar-Dateien mit unzip auspacken und zip-Dateien mit jar xfvv.
Wenn man nun aber eine Datenbankspalte oder -tabelle komprimieren will, sind diese beiden Ansätze nicht so attraktiv. Im einen Fall werden die Zugriffe unakzeptabel langsam, im anderen Fall hat man mit einem einzelnen Datenbankattribut in einer einzelnen Zeile selten genug Masse, um von der Kompression profitieren zu können. Wie könnte man das trotzdem lösen? Vielleicht wäre eine Möglichkeit, dass man ab einer gewissen Datenmenge in der Spalte, also wenn es genug Zeilen gibt, bei denen dieses Attribut nicht null ist, die Daten analysiert und in einem mit der Tabelle assoziierten Bereich Metadaten zur Kompression ablegt, die etwa aus mehrfach vorkommenden Bit- oder Byte-Sequenzen bestehen und diese auf andere Bit- oder Byte-Sequenzen abbilden, so dass die häufigeren kürzer sind als die selteneren gleicher Originallänge. Solange die neu hinzukommenden Daten etwa den schon vorhandenen entsprechen, kann man sie damit auch komprimieren und tatsächlich die Datenbank kleiner machen, aber vor allem in manchen Fällen schneller und in Kombination mit Verschlüsselung vielleicht sogar sicherer.
Nebenbei bemerkt, dass es viele Werkzeuge gibt, die ähnlich wie die hier erwähnten Vertreter funktionieren:
- lha, zoo und 7z funktionieren z.B. ähnlich wie zip.
- compress, bzip2 und xz funktionieren ähnlich wie gzip
- cpio funktioniert ähnlich wie tar
Weil compress in den 90er-Jahren auf patentierten Algorithmen basierte, hat man es praktisch vollständig durch gzip ersetzt, was auch die bessere Kompressionsraten auf Kosten des Zeitaufwands zum Komprimieren erzielt hat. Dann kam bzip2, das noch besser und noch langsamer komprimiert und xz, noch besser und noch langsamer.
tar hieß ursprünglich „tape archiver“, konnte als Bandlaufwerke ansprechen. Es wird aber seit 20 Jahren in meiner Erfahrung ganz überwiegend für Archivierung in Dateien verwendet und sehr selten für Bandlaufwerke. Dafür kam dann irgendwann cpio, das aber auch für beide Zwecke verwendbar ist, wie tar. Nur ist cpio weniger verbreitet und man muss wohl als durchschnittlicher Linux-Anwender häufiger die man-Seite anschauen, wenn man das verwendet, während man bei tar eher die wichtigsten Optionen auswendig kennen könnte.