{"id":55000466,"date":"2007-06-01T00:00:00","date_gmt":"2021-02-11T21:16:37","guid":{"rendered":"http:\/\/access-im-unternehmen.aix-dev.de\/aiu\/?p=466"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-30T00:00:00","slug":"Komprimierte_Binaerspeicherung_","status":"publish","type":"post","link":"https:\/\/access-im-unternehmen.de\/Komprimierte_Binaerspeicherung_\/","title":{"rendered":"Komprimierte Bin&auml;rspeicherung"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/vg04.met.vgwort.de\/na\/826749b8e07e45e391bc6dbb3df598d4\" width=\"1\" height=\"1\" alt=\"\"><\/p>\n<p><b>Dateien oder andere Bin&auml;robjekte in Datenbanktabellen zu speichern, ist bei vielen Access-Entwicklern verp&ouml;nt. Das Hauptargument, das man dabei zu h&ouml;ren bekommt, ist das unverh&auml;ltnism&auml;&szlig;ige Aufbl&auml;hen der Datenbanken. Das greift jedoch nur dann, wenn die Objekte in einem OLE-Feld als OLE-Objekte abgespeichert werden. Denn dabei findet eine Konversion der Quelldateien in OLE-kompatible Dokumentenformate statt, die sie vergr&ouml;&szlig;ern. Dabei lassen sich die Dateien mit wirklich bin&auml;rer Speicherung als BLOBs durchaus Platz sparend unterbringen &#8211; vor allem, wenn man sie dann noch zus&auml;tzlich mit einer Komprimierung versieht. Im folgenden Beitrag werden einige Anwendungsbeispiele und die zugrunde liegenden Techniken beleuchtet.<\/b><\/p>\n<\/p><\/div>\n<div class=\"story\">\n<p class=\"zwischen-berschrift-oberer-spaltenrand\">Wozu Bin&auml;robjekte<\/p>\n<p>Das sicher am h&auml;ufigsten nachgefragte Feature f&uuml;r Bin&auml;robjekte in Datenbanken ist die Anzeige von Bildern. Das ist auch nachvollziehbar, denn Entit&auml;ten in Datenbanken sind mit wahren Objekten der Realit&auml;t verkn&uuml;pft, die nun mal eine visuelle Entsprechung haben.<\/p>\n<p>Ein Kunde hat ein Gesicht, ein Produkt ein Aussehen, eine Firma ein Logo. Das Konterfei eines Kunden also dem entsprechenden Kundendatensatz zuzuordnen, ein Produktbild ins Warenwirtschaftssystem zu bringen oder im Lieferantenformular Logos zu platzieren, macht durchaus Sinn.<\/p>\n<p>Interessant w&auml;re aber auch, etwa die Korrespondenz mit einem Kunden in Form von Texten, Word-Dokumenten, PDFs oder Excel-Dateien mit in eine Datenbank aufzunehmen, damit man direkt aus dem Kundenformular schnell darauf zugreifen kann.<\/p>\n<p>&uuml;blicherweise speichert man in der Datenbank lediglich Verweise auf das Dateisystem und &ouml;ffnet die Dateien zur Laufzeit mit der entsprechenden Anwendung. Das ist tats&auml;chlich empfehlenswert, solange man sicher sein kann, dass sich Pfade nicht &auml;ndern, Dateien nicht verschoben werden und jeder Anwender &uuml;berhaupt Zugriff auf die Verzeichnisse im Netzwerk hat.<\/p>\n<p>Tritt einer dieser F&auml;lle ein, dann ist man mit der Schwierigkeit konfrontiert, die Pfade in der Datenbank upzudaten oder Berechtigungen neu zu vergeben.<\/p>\n<p>Das alles w&auml;re &uuml;berfl&uuml;ssig, wenn sich die Dateien gleich innerhalb der Datenbank bef&auml;nden.<\/p>\n<p><b>Wie kann man Bin&auml;rdaten speichern<\/b><\/p>\n<p>Es gibt je nach Access-Version bis zu drei &uuml;bliche M&ouml;glichkeiten der Bin&auml;rspeicherung, denen dieser Beitrag noch eine weitere hinzuf&uuml;gt &#8211; die Speicherung komprimierter Daten:<\/p>\n<ul>\n<li class=\"aufz-hlung\">OLE-Objekte<\/li>\n<li class=\"aufz-hlung\">BLOBs<\/li>\n<li class=\"aufz-hlung\">Komprimierte BLOBs<\/li>\n<li class=\"aufz-hlung\">Anlagen (Access 2007)<\/li>\n<\/ul>\n<p>Ole-Felder sind f&uuml;r die erstgenannten drei M&ouml;glichkeiten der zu verwendende Datentyp des Bin&auml;r-Containers. In Access 2007 wurde zus&auml;tzlich der neue Typ <b>Attachment <\/b>(<b>Anlagefeld<\/b>) eingef&uuml;hrt.<\/p>\n<p><b>OLE-Objekte<\/b><\/p>\n<p>OLE-Objekte sind sehr leicht zu handhaben, weil Access sich dabei sowohl um die Speicherung wie auch die Anzeige der Dateien k&uuml;mmert. Sie lassen sich direkt in der Datenblattansicht in OLE-Feldern speichern und durch einfachen Doppelklick &ouml;ffnen. Das Speichern geschieht etwa &uuml;ber den Eintrag <b>Objekt einf&uuml;gen&#8230; <\/b>des Kontextmen&uuml;s eines leeren OLE-Felds. Im anschlie&szlig;end erscheinenden Dialog aktiviert man <b>Aus Datei erstellen<\/b>, w&auml;hlt die Datei &uuml;ber den <b>Durchsuchen<\/b>-Button aus und deaktiviert au&szlig;erdem das Kontrollk&auml;stchen <b>Verkn&uuml;pfen<\/b>.<\/p>\n<p>Bei dieser Vorgehensweise wird die Datei in jedem Fall in ein OLE-kompatibles Format konvertiert. Das bedeutet, dass sie mit Informationen zu einem auf dem Rechner verkn&uuml;pften OLE-Server versehen wird. Ist dem Dateityp im System kein OLE-Server &#8211; das ist ein OLE-automationsf&auml;higes Programm &#8211; zugeordnet, so wird ein Paket erstellt. Das ist ebenfalls ein OLE-Format &#8211; quasi ein Wrapper, ein Container f&uuml;r eine Datei. Beim Doppelklick wird diese Datei tempor&auml;r wiederhergestellt und mit der verkn&uuml;pften Anwendung ge&ouml;ffnet.<\/p>\n<p>Bei einer dezidiert mit einem OLE-Server verkn&uuml;pften Datei muss hingegen genau dieser OLE-Server auch auf dem Zielrechner installiert sein, wenn man der Fehlermeldung <b>OLE-Server ist nicht vorhanden oder konnte nicht gefunden werden <\/b>entgehen will. Speichert man etwa ein Word-Dokument in das OLE-Feld, dann muss auf dem Zielrechner ebenfalls Word installiert sein, wenn die Datei wieder aufgerufen werden soll. W&uuml;rde das Dokument hingegen als Paket gespeichert, dann k&auml;me gegebenenfalls auch Wordpad zum &ouml;ffnen in Betracht.<\/p>\n<p>Man kann hier schon das wichtigste Problem im Zusammenhang mit OLE-Objekten ablesen: Ohne passenden OLE-Server keine Anzeige der Datei. Gerade bei Bilddateien kommt es h&auml;ufig vor, dass diese &uuml;ber den OLE-Server Microsoft Photo Editor gespeichert werden, der aber auf einem Zielrechner nicht vorhanden ist. Ein JPG etwa kann selbst dann nicht ge&ouml;ffnet werden, wenn andere taugliche Bildanzeigen installiert sind. <\/p>\n<p>Hinzu kommt, dass eine Datei als OLE-Objekt im OLE-Server in ein f&uuml;r ihn schnell lesbares Format umgewandelt und auch so abgespeichert wird. Ein JPG wird etwa h&auml;ufig in ein bitmap-&auml;hnliches Format konvertiert, das weitaus gr&ouml;&szlig;er ist als die Ursprungsdatei. So kommt das Aufbl&auml;hen der Datenbank zustande.<\/p>\n<p><b>BLOBs<\/b><\/p>\n<p>Beim Speichern als BLOBs (Binary Large Objects) hat man solche Probleme nicht. Hierbei wird die Datei Byte f&uuml;r Byte identisch mit dem Original im OLE-Feld gespeichert, dessen Kennzeichnung somit nicht mehr korrekt ist, weil es nun mit OLE &uuml;berhaupt nichts mehr zu tun hat. Richtiger w&auml;re die Bezeichnung <b>LongVarBinary<\/b>, wie sie &auml;hnlich auch in SQL verwendet wird. Bei dieser Methode w&auml;chst die Datenbank entsprechend der Gr&ouml;&szlig;e der eingelesenen Datei. Nachteil: Das Speichern und Auslesen muss per VBA-Routinen erfolgen, weil die Oberfl&auml;che von Access keine entsprechenden Mittel zur Verf&uuml;gung stellt.<\/p>\n<p><b>Komprimierte BLOBs<\/b><\/p>\n<p>Das Speichern als komprimiertes BLOB funktioniert in gleicher Weise, nur mit dem Unterschied, dass die Datei zuvor mit geeigneten Algorithmen komprimiert wird. Dieses Komprimieren k&ouml;nnte man bereits im Dateisystem vollziehen, indem man die Datei zun&auml;chst mit einer Zip-Anwendung in eine Archiv-Datei konvertiert und erst dann einliest. Das ist jedoch &uuml;berfl&uuml;ssig, weil es M&ouml;glichkeiten gibt, die Kompression rein im Speicher durchzuf&uuml;hren. In diesem Beitrag wird von solchen M&ouml;glichkeiten Gebrauch gemacht, wobei die Open-Source-Komponente <b>zlib<\/b> zum Einsatz kommt.<\/p>\n<p>Tab. 1 zeigt den Speicherbedarf f&uuml;r die unterschiedlichen Methoden.<\/p>\n<div class=\"story\">\n<table style=\"border-collapse: collapse; border: black 1px solid\">\n<tbody>\n<tr>\n<td>\n<p class=\"tabellenkopf\">Beispieldatei<\/p>\n<\/td>\n<td>\n<p class=\"tabellenkopf\">Gr&ouml;&szlig;e<\/p>\n<\/td>\n<td>\n<p class=\"tabellenkopf\">OLE-Objekt<\/p>\n<\/td>\n<td>\n<p class=\"tabellenkopf\">BLOB<\/p>\n<\/td>\n<td>\n<p class=\"tabellenkopf\">Komprimiertes BLOB<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<\/td>\n<td>\n<\/td>\n<td>\n<\/td>\n<td>\n<\/td>\n<td>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<\/td>\n<td>\n<\/td>\n<td>\n<\/td>\n<td>\n<\/td>\n<td>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<\/td>\n<td>\n<\/td>\n<td>\n<\/td>\n<td>\n<\/td>\n<td>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><b><span style=\"color:darkgrey\">Tabelle 1: Speicherbedarf realistischer Beispieldaten bei unterschiedlichen Verfahren<\/span><\/b><\/p>\n<\/p><\/div>\n<p>F&uuml;r welches der drei Verfahren man sich hiernach entscheidet, ist wohl klar: OLE-Speicherung vergr&ouml;&szlig;ert die Datenbank gegen&uuml;ber komprimierter BLOB-Speicherung f&uuml;r die hier verwendeten Formate um den Faktor 54!<\/p>\n<p>Solche Erfahrungen hat Microsoft dann wohl auch mit dazu bewegt, in Access 2007 den neuen Feldtyp <b>Anlage <\/b>(<b>Attachment<\/b>) einzuf&uuml;hren, dem ebenfalls eine komprimierte BLOB-Speicherung zu eigen ist. In Attachments k&ouml;nnen Sie Dateien mit dem gleichen Komfort &uuml;ber die Oberfl&auml;che speichern wie bisher in OLE-Feldern. Sie werden dabei aber nicht ver&auml;ndert, brauchen keinen OLE-Server und werden automatisch immer dann komprimiert, wenn es sinnvoll ist, also eine nennenswerte Verkleinerung der Daten zu erwarten ist. Das geschieht alles hinter den Kulissen.<\/p>\n<p>Es stellt sich also die Frage: Ist mit Access 2007 das Thema erledigt Nach den Erfahrungen des Autors: Nicht ganz! Zum einen ist die Performance beim Ein- und Auslesen von Attachments deutlich geringer als das Gespann von BLOBs und ZLIB &#8211; etwa um den Faktor 1,5 -, zum anderen ist die Dateigr&ouml;&szlig;e etwas limitiert. Offenbar ben&ouml;tigt Access 2007 beim Einlesen von Dateien etwa gut das Doppelte der Dateigr&ouml;&szlig;e an RAM &#8211; den einen Teil f&uuml;r die Datei selbst, den anderen f&uuml;r das Ergebnis der Komprimierung.<\/p>\n<p>So war es auf einem Rechner mit 700 MB freiem physischem RAM nicht m&ouml;glich, Dateien gr&ouml;&szlig;er als 220 MB in ein Anlagefeld zu speichern. Nicht, dass so gro&szlig;e Dateien &uuml;berhaupt in Datenbanken gespeichert werden sollten, aber bereits weit unter dieser Gr&ouml;&szlig;e lie&szlig; die Performance erheblich zu w&uuml;nschen &uuml;brig. Attachments kommen daher eher f&uuml;r kleinere Dateien in Betracht.<\/p>\n<p>Ein anderer Punkt ist, dass es noch kaum Erfahrungen mit einer gr&ouml;&szlig;eren Anzahl von Attachments in Access 2007-Datenbanken gibt und es nicht als sicher gelten kann, ob sich hier nicht die Probleme in puncto Stabilit&auml;t wiederholen k&ouml;nnten, die es auch schon etwa mit Memofeldern gab.<\/p>\n<p><b>BLOBS speichern<\/b><\/p>\n<p>Bin&auml;rdaten k&ouml;nnen &uuml;ber die Datenzugriffsbibliotheken DAO oder ADO in Tabellen gespeichert werden. DAO erwartet dabei zun&auml;chst ein Byte-Array als Zwischenspeicher f&uuml;r die Dateien, gefolgt von der Methode <b>Field.AppendChunk<\/b>, w&auml;hrend ADO seit Version 2.5 ein <b>Stream<\/b>-Objekt mit der Methode <b>LoadFromFile <\/b>kennt, dessen Inhalt anschlie&szlig;end per <b>Stream.Read <\/b>einem Feldinhalt zugewiesen werden kann.<\/p>\n<p>Das sieht einfacher aus und ist es auch, geht aber leider langsamer vonstatten als die DAO-Methode, sodass es keinen Grund gibt, hier ADO einzusetzen &#8211; au&szlig;er Sie arbeiten mit Access-Projekten (ADP), in denen DAO nicht verwendet werden kann. Sie finden beide Verfahren im Modul <b>mdlBLOBs <\/b>der Beispieldatenbank <b>binaer.mdb<\/b>.<\/p>\n<p>Die Routine aus Listing 1 verdeutlicht das Prinzip. Sie l&auml;dt eine Datei in ein Byte-Array und speichert dessen Inhalt anschlie&szlig;end in einem Tabellenfeld, das als OLE-Objekt definiert wurde.<\/p>\n<div class=\"abbildung\">\n<table>\n<tbody>\n<tr>\n<td>\n<p class=\"kastentabelleheader\">Listing 1: Datei per DAO in ein Tabellenfeld einlesen<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<pre>Sub SpeichereDatei()<\/pre>\n<pre>     Dim bin() As Byte<\/pre>\n<pre>     Dim rst As DAO.Recordset<\/pre>\n<pre>     Open \"c:\\dateiname.dat\" For Binary Access Read As #1<\/pre>\n<pre>     ReDim bin(LOF(1))<\/pre>\n<pre>     Get #1, , bin<\/pre>\n<pre>     Close #1<\/pre>\n<pre>     Set rst = CurrentDb.OpenRecordset(\"Tabelle1\", dbOpenDynaset)<\/pre>\n<pre>     rst.AddNew<\/pre>\n<pre>     rst!Binaerfeld.AppendChunk bin()<\/pre>\n<pre>     rst.Update<\/pre>\n<pre>     rst.Close<\/pre>\n<pre>End Sub<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/div>\n<p>Sie finden &auml;hnliche Routinen auch an anderen Stellen und in der Access-Hilfe. M&ouml;glicherweise f&auml;llt Ihnen dabei auf, dass die dort aufgef&uuml;hrten Codes etwas l&auml;nger sind als in Listing 1. Das liegt daran, dass das Byte-Array h&auml;ufig nicht in einem Rutsch in das Feld gespeichert wird, sondern in einer Schleife h&auml;ppchenweise &#8211; daher auch der Begriff <b>Chunk <\/b>(St&uuml;ck, Brocken).<\/p>\n<p><!--30percent--><\/p>\n<p>Das kommt aus Zeiten, in denen die Rechner noch nicht mit gigabytegro&szlig;em RAM versehen waren und mit dem Speicher sorgsam umgegangen werden musste. Beim Aufteilen in kleinere H&auml;ppchen spart man Arbeitsspeicher ein. Heutzutage ist das nicht mehr notwendig und das Array kann komplett zugewiesen werden, sofern Sie nicht auf die Idee kommen sollten, Ihre Sammlung von Video-Dateien in der Datenbank zu speichern &#8230;<\/p>\n<p>Erstaunlich einfach funktioniert das Speichern des Arrays &uuml;brigens, wenn Sie ein gebundenes Formular verwenden, dessen Datenherkunft das OLE-Feld enth&auml;lt. Dann reduziert sich der Code auf die Prozedur aus Listing 2.<\/p>\n<div class=\"abbildung\">\n<table>\n<tbody>\n<tr>\n<td>\n<p class=\"kastentabelleheader\">Listing 2: Datei per DAO in ein Formularfeld einlesen<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<pre>Private Sub SpeichereDatei()<\/pre>\n<pre>     Dim bin() As Byte<\/pre>\n<pre>     Open \"c:\\dateiname.dat\" For Binary Access Read As #1<\/pre>\n<pre>     ReDim bin(LOF(1))<\/pre>\n<pre>     Get #1, , bin<\/pre>\n<pre>     Close #1<\/pre>\n<pre>     Me!Binaerfeld.Value = bin()<\/pre>\n<pre>End Sub<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/div>\n<p>Es wird also schlichtweg das Byte-Array dem Tabellenfeld des Formulars verabreicht, ohne dass die Methode <b>AppendChunk <\/b>zum Einsatz kommen m&uuml;sste. Ein Steuerelement f&uuml;r das OLE-Feld m&uuml;ssen Sie dabei erst gar nicht vorsehen.<\/p>\n<p>Der Vollst&auml;ndigkeit halber finden Sie in Listing 3 noch eine zu Listing 1 analoge Routine, die ADO verwendet.<\/p>\n<div class=\"abbildung\">\n<table>\n<tbody>\n<tr>\n<td>\n<p class=\"kastentabelleheader\">Listing 3: Datei per ADO 2.5 oder h&ouml;her in ein Tabellenfeld einlesen<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<pre>Sub SpeichereDatei()<\/pre>\n<pre>     Dim rst As New ADODB.Recordset<\/pre>\n<pre>     Dim rsStm As New ADODB.Stream<\/pre>\n<pre>     rst.Open \"Tabelle1\", CurrentProject.Connection, _<\/pre>\n<pre>     adOpenDynamic, adLockPessimistic<\/pre>\n<pre>     rst.AddNew<\/pre>\n<pre>     With rsStm<\/pre>\n<pre>         .Type = adTypeBinary<\/pre>\n<pre>         .Open<\/pre>\n<pre>         .LoadFromFile \"c:\\dateiname.dat\"<\/pre>\n<pre>         rst!Binaerfeld.Value = .Read<\/pre>\n<pre>         .Close<\/pre>\n<pre>     End With<\/pre>\n<pre>     rst.Close<\/pre>\n<pre>End Sub<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/div>\n<p><b>BLOBs auslesen<\/b><\/p>\n<p>Was bei einer als OLE-Objekt im Tabellenfeld gespeicherten Datei per Doppelklick geht oder im Falle eines gebundenen OLE-Felds im Formular sogar automatisch passiert, das erfordert bei BLOBs wieder etwas VBA-Code: Das Auslesen und Anzeigen der Datei.<\/p>\n<p>Dabei erfolgt unter DAO wie ADO jeweils der umgekehrte Vorgang wie beim Einlesen: Unter DAO wird zun&auml;chst ein Byte-Array mit der <b>GetChunk<\/b>-Methode eines Recordset-Feldes bef&uuml;llt und anschlie&szlig;end als Datei abgespeichert.<\/p>\n<p>Diese kann dann mit der f&uuml;r sie verkn&uuml;pften Anwendung ge&ouml;ffnet werden. Hierf&uuml;r k&ouml;nnen die VBA-Anweisung <b>Shell<\/b> oder die API-Funktion <b>ShellExecute<\/b> verwendet werden. Unter ADO wird zun&auml;chst ein Stream-Objekt mit dem Inhalt des Bin&auml;rfelds gef&uuml;llt und anschlie&szlig;end mit der Methode <b>SaveToFile <\/b>in eine Datei gespeichert.<\/p>\n<p>Ein passender DAO-Code s&auml;he etwa wie in Listing 4 aus und die Routine, welche die mit der Prozedur aus Listing 2 in ein Formularfeld kopierte Datei wiederherstellt, finden Sie in Listing 5.<\/p>\n<div class=\"abbildung\">\n<table>\n<tbody>\n<tr>\n<td>\n<p class=\"kastentabelleheader\">Listing 4: Datei per DAO aus Bin&auml;rfeld wiederherstellen und anzeigen<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<pre>Sub DateiWiederherstellen()<\/pre>\n<pre>     Dim bin() As Byte<\/pre>\n<pre>     Dim lSize As Long<\/pre>\n<pre>     Dim rst As DAO.Recordset<\/pre>\n<pre>     Set rst = CurrentDb.OpenRecordset(\"SELECT Binaerfeld &quot; _<br \/> &amp; &quot;FROM Tabelle1 WHERE ID=1\", dbOpenDynaset)<\/pre>\n<pre>     lSize = rst!Binaerfeld.FieldSize - 1<\/pre>\n<pre>     Redim bin(lSize)<\/pre>\n<pre>     bin = rst(0).GetChunk(0, lSize)<\/pre>\n<pre>     Open \"c:\\dateiname.dat\" For Binary Access Write As #1<\/pre>\n<pre>     Put #1, , bin()<\/pre>\n<pre>     Close #1<\/pre>\n<pre>     rst.Close<\/pre>\n<pre>     ShellExecute 0, \"open\", \"c:\\dateiname.dat\", vbNullString, _<br \/> CurDir, 1<\/pre>\n<pre>End Sub<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/div>\n<div class=\"abbildung\">\n<table>\n<tbody>\n<tr>\n<td>\n<p class=\"kastentabelleheader\">Listing 5: Datei aus Formularfeld wiederherstellen und anzeigen<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<pre>Private Sub ZeigeDatei()<\/pre>\n<pre>     Dim bin() As Byte<\/pre>\n<pre>     bin = Me!Binaerfeld.Value<\/pre>\n<pre>     Open \"c:\\dateiname.dat\" For Binary Access Read As #1<\/pre>\n<pre>     Put #1, , bin<\/pre>\n<pre>     Close #1<\/pre>\n<pre>     ShellExecute 0, \"open\", \"c:\\dateiname.dat\", vbNullString, _<br \/> CurDir, 1<\/pre>\n<pre>End Sub<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/div>\n<p>Fehlt noch das Pendant zu der Routine aus Listing 3, diesmal mit ADO (s. Listing 6).<\/p>\n<div class=\"abbildung\">\n<table>\n<tbody>\n<tr>\n<td>\n<p class=\"kastentabelleheader\">Listing 6: Datei per ADO 2.5 oder h&ouml;her aus Tabellenfeld wiederherstellen und anzeigen<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<pre>Sub DateiWiederherstellen()<\/pre>\n<pre>     Dim rst As New ADODB.Recordset<\/pre>\n<pre>     Dim rsStm As New ADODB.Stream<\/pre>\n<pre>     rst.Open \"SELECT Binaerfeld FROM Tabelle1 WHERE ID=1\", _<\/pre>\n<pre>     CurrentProject.Connection, adOpenDynamic, adLockPessimistic<\/pre>\n<pre>     With rsStm<\/pre>\n<pre>         .Type = adTypeBinary<\/pre>\n<pre>         .Open<\/pre>\n<pre>         .Write rst(0).Value<\/pre>\n<pre>         .SaveToFile \"c:\\dateiname.dat\", adSaveCreateOverWrite<\/pre>\n<pre>         .Close<\/pre>\n<pre>     End With<\/pre>\n<pre>     rst.Close<\/pre>\n<pre>     ShellExecute 0, \"open\", \"c:\\dateiname.dat\", vbNullString, CurDir, 1<\/pre>\n<pre>End Sub<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table><\/div>\n<p>Die Deklaration der eingesetzten API-Funktion <b>ShellExecute<\/b>, die zum Anzeigen einer beliebigen Datei benutzt werden kann, finden Sie in der Beispieldatenbank <b>binaer.mdb <\/b>im Modul <b>mdlHelper<\/b>. Die Funktion startet automatisch die systemweit mit einer Dateiendung verkn&uuml;pfte Anwendung.<\/p>\n<p><b>BLOB-Module<\/b><\/p>\n<p>Die zuvor aufgef&uuml;hrten Codes sind ziemlich rudiment&auml;r und veranschaulichen lediglich die grunds&auml;tzlichen Funktionsweisen. In den Beispieldatenbanken <b>binaer.mdb <\/b>und <b>binaer.accdb <\/b>sind ausf&uuml;hrlichere Module enthalten, die allgemein verwendbare Routinen beherbergen.<\/p>\n<p>Das Modul <b>mdlBLOBs <\/b>zeigt Funktionen, denen Dateinamen, Tabellennamen, Feldbezeichnungen als Parameter &uuml;bergeben werden k&ouml;nnen, um Dateien auszulesen und wiederherzustellen.<\/p>\n<p>Statt Dateien k&ouml;nnen auch Byte-Arrays direkt in Tabellenfelder geschrieben und aus ihnen extrahiert werden. In der Access 2007-Datenbank <b>binaer.accdb <\/b>gibt es zus&auml;tzlich das Modul <b>mdlBLOBs2007<\/b>, das demonstriert, wie die gleichen Vorg&auml;nge sich auch auf Anlagefelder anwenden lassen.<\/p>\n<p>Diese Prozeduren lassen sich, eventuell mit leichten Anpassungen, auch in anderen Datenbanken verwenden.<\/p>\n<p><b>BLOBs komprimiert speichern und auslesen<\/b><\/p>\n<p>Die in Tab. 1 zusammengefassten Messungen haben gezeigt, dass sich mit zus&auml;tzlicher Komprimierung viele Dateitypen bin&auml;r noch deutlich Platz sparender in einer Datenbank unterbringen lassen. Ein gangbarer Weg w&auml;re, eine Datei zun&auml;chst in ein ZIP-Archiv zu packen und dieses Archiv dann abzuspeichern.<\/p>\n<p>Beim Auslesen m&uuml;sste man dann das Archiv als Datei wiederherstellen und anschlie&szlig;end entpacken. Das lie&szlig;e sich auch per VBA und mit den Kommandozeilenanweisungen einiger Packer wie WinZip automatisieren.<\/p>\n<p>Dieser etwas umst&auml;ndliche und zudem performancebremsende Weg l&auml;sst sich aber umgehen, wenn die Bin&auml;rdaten direkt im Speicher komprimiert werden, statt in eine Archivdatei.<\/p>\n<p>Die wohl am weitesten verbreitete Komponente hierf&uuml;r ist die ZLIB-Bibliothek [1]. Die <b>zlib.dll <\/b>&#8211; ein Open-Source-Projekt &#8211; enth&auml;lt beispielsweise eine API-Funktion <b>compress<\/b>, der man ein Byte-Array mit den Bin&auml;rdaten &uuml;bergibt, und als Ergebnis wiederum ein Byte-Array mit den komprimierten Daten bekommt.<\/p>\n<p>Der umgekehrte Vorgang erfolgt &uuml;ber die Funktion <b>uncompress<\/b>. Die Packraten dieser Bibliothek entsprechen etwa denen des ZIP-Verfahrens.<\/p>\n<p>Sie brauchen die DLL nicht selbst herunterzuladen. Starten Sie einfach eine der beiden Beispieldatenbanken und schon wird die DLL automatisch im gleichen Verzeichnis erzeugt. Sie befindet sich als Bin&auml;robjekt in der Tabelle <b>tblBinSimple <\/b>und wird &uuml;ber eine Prozedur des Intro-Formulars auf &auml;hnliche Weise als Datei extrahiert, wie es in Listing 4 dargestellt ist.<\/p>\n<p>Das zeigt &uuml;brigens einen weiteren Anwendungsfall der BLOB-Speicherung: Sie k&ouml;nnen in Ihrer Datenbank direkt vom VBA-Projekt ben&ouml;tigte Komponenten unterbringen und quasi auf dem Zielsystem installieren. Sie ersparen sich damit die separate Weitergabe von Zusatzkomponenten. <\/p>\n<p>Wundern Sie sich nicht, dass der Dateiname der DLL <b>zlibwapi.dll <\/b>lautet. Das ist eine modifizierte Version der Originalbibliothek, die kompatibler mit VBA-Datentypen ist [2]. Mit der Originalversion <b>zlib.dll <\/b>bekommt man Schwierigkeiten bei der Deklaration der Funktionen.<\/p>\n<p>Um die Bibliothek benutzen zu k&ouml;nnen, ben&ouml;tigen Sie ein Modul mit den entsprechenden API-Deklarationen und einigen &ouml;ffentlichen Funktionen, die sich dann leicht an beliebiger Stelle des VBA-Projekts aufrufen lassen. In den Beispieldatenbanken hei&szlig;t dieses Modul <b>mdlZipLib<\/b>. <\/p>\n<p>Die Prozedur, um ein Byte-Array zu komprimieren, hei&szlig;t darin <b>CompressByteArray<\/b>. Der folgende Code zeigt, wie die Funktion angesprochen wird:<\/p>\n<pre>Dim arrBin() As Byte\r\nRedim arrBin(100)\r\n&apos; ... hier Byte-Array f&uuml;llen\r\nCompressByteArray arrBin\r\n&apos; arrBin enth&auml;lt nun die komprimierten Daten<\/pre>\n<p>Wenn Sie also etwa eine Datei bereits wie in Listing 1 in ein Byte-Array eingelesen haben, dann reicht eine einzige Zeile weiteren Codes aus, um die Kompression durchzuf&uuml;hren.<\/p>\n<p>Anschlie&szlig;end kann das Byte-Array in das Tabellenfeld gespeichert werden. Einfacher geht&#8220;s nicht!<\/p>\n<p>Zum Auslesen der Datei dekomprimieren Sie die aus dem Tabellenfeld erhaltenen Bin&auml;rdaten mit der Prozedur <b>DecompressByteArray<\/b>:<\/p>\n<pre>Dim arrBin() As Byte\r\n&apos;hier Byte-Array per GetChunk aus Tabellenfeld &apos;f&uuml;llen\r\nDecompressByteArray arrBin\r\n&apos; Entpacktes Byte-Array weiterverwenden<\/pre>\n<p><b>Texte komprimiert abspeichern<\/b><\/p>\n<p>Bisher war nur von Dateien und deren Speicherung als BLOBs in einem Ole-Feld einer Tabelle die Rede. Es lassen sich aber auch Strings mit ZLIB komprimieren. Die beiden im Modul <b>mdlZipLib <\/b>befindlichen Prozeduren <b>CompressString <\/b>und <b>DecompressString <\/b>sind hierf&uuml;r verantwortlich.<\/p>\n<p>Und eines wurde bisher verschwiegen: Auch Memo-Felder lassen sich als Container f&uuml;r Bin&auml;rdaten verwenden. Sie sollten damit allerdings vorsichtig sein.<\/p>\n<p>Zum einen lassen sich die Bin&auml;rdaten eines Memofelds leicht zerst&ouml;ren, wenn Sie die Eigenschaft <b>Unicode-Kompression <\/b>des Feldes von <b>Nein <\/b>auf <b>Ja <\/b>stellen, zum anderen werden Memofelder von der JET-Engine etwas komplizierter behandelt als Ole-Felder.<\/p>\n<p>Wie sie intern gespeichert werden, h&auml;ngt etwa von der Gr&ouml;&szlig;e ihres Inhalts ab. Die Stabilit&auml;t l&auml;sst stellenweise zu w&uuml;nschen &uuml;brig und es ist immer wieder von F&auml;llen der Datenkorruption im Zusammenhang mit Memofeldern zu h&ouml;ren. Beachten Sie vor allem einen Tipp: Setzen Sie keinen Index auf ein Memofeld!<\/p>\n<p>Das Komprimieren von Texten macht vor allem dann Sinn, wenn sie ausreichend lang sind. Ein <b>ZLIB-compress <\/b>zugef&uuml;hrter String der L&auml;nge 100 hat im komprimierten Resultat durchschnittlich die L&auml;nge 80. Hier lohnt die Kompression kaum. Bei einer L&auml;nge von 1.000 aber ergibt sich bereits ein Gewinn von etwa 500 Byte, also um den Faktor 2.<\/p>\n<p>In den Demodatenbanken finden Sie ein Beispiel f&uuml;r den sinnvollen Einsatz von Textkompression im Formular <b>frmKomponisten <\/b>(siehe Bild 1). Es baut auf der Tabelle <b>tblKomponisten <\/b>als Datenherkunft auf, die die Biografietexte von 120 Komponisten in zwei Memofeldern enth&auml;lt: Einmal im Original, einmal in ZLIB-komprimierter Form.<\/p>\n<div class=\"image\">\n            <img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2007_03\/BinaerspeicherungMitZlib-web-images\/frmKomponisten2_opt.jpeg\" alt=\"frmKomponisten2.png\" \/>\n        <\/div>\n<div class=\"story\">\n<p><b><span style=\"color:darkgrey\">Bild 1: In der Tabelle tblKomponisten komprimiert gespeicherte Texte werden im Formular angezeigt.<\/span><\/b><\/p>\n<\/p><\/div>\n<p>Zur Laufzeit (Ereignis <b>Form_Current<\/b>) werden die Texte im Formular mit der Funktion <b>UncompressString <\/b>entpackt und angezeigt.<\/p>\n<p>Auf der rechten Seite des Formulars befindet sich ein Navigations-Bar (Listenfeld), mit dem Sie per Mausklick einzelne Komponisten aufrufen k&ouml;nnen (wenn Sie die Maus aus dem Listenfeld herausbewegen, dann verschwindet es automatisch, und wenn Sie die Maus dem rechten Rand des Formulars n&auml;hern, dann blendet es sich wieder ein).<\/p>\n<p>Dass die Texte in der Tabelle sowohl in komprimierter wie unkomprimierter Form abgespeichert sind, dient der Demonstration der Leistungsf&auml;higkeit der ZLIB-Bibliothek. Rufen Sie einfach die Abfrage <b>qry_BioSize<\/b> auf: Sie zeigt die Summen des Speicherbedarfs der Originaltexte wie auch der komprimierten Daten an.<\/p>\n<p>Im Original sind dies 547 kB, komprimiert 285 kB. Das ist auch ein guter Anhaltswert f&uuml;r die durchschnittliche Kompressionsrate von deutschen Texten. Man kann von einer Reduzierung des Speicherbedarfs knapp um den Faktor 2 ausgehen, wenn die Texte nicht zu kurz sind.<\/p>\n<p>An dieser Stelle vielleicht eine kurze Erl&auml;uterung des Kompressionsalgorithmus von ZLIB: Dieser arbeitet mit so genannten Dictionaries.<\/p>\n<p>Grob dargestellt werden dazu alle W&ouml;rter eines Textes oder gleichartige Datenteile in eine Art Inhaltsverzeichnis aufgenommen, auf dessen Eintr&auml;ge anschlie&szlig;end nur noch mit Zeigern verwiesen werden muss, um die Daten seriell anzugeben. Je kleiner dieses Verzeichnis ist, desto h&ouml;her wird die Kompressionsrate.<\/p>\n<p>Besteht ein Text etwa aus einer Liste von Zeilen, die sich h&auml;ufig wiederholen, so k&ouml;nnen locker auch mal Kompressionsraten von 50 erreicht werden. Auch Texte, die eine hohe Zahl von Leerzeichen zur &#8222;Formatierung&#8220; enthalten, sind Kandidaten f&uuml;r gute Kompression. Dasselbe gilt f&uuml;r HTML-Dokumente, die naturgem&auml;&szlig; zahlreiche sich wiederholende HTML-Tags enthalten.<\/p>\n<p>Weitere Anwendungsm&ouml;glichkeiten f&uuml;r komprimiert gespeicherte Texte: In der Datenbank verwaltete E-Mails, Hilfetexte, Protokolle und Logs, Messwertreihen &#8230; <\/p>\n<p>Und &uuml;brigens: Die Komprimierung mit ZLIB f&uuml;hrt nebenbei automatisch zu einer Verschl&uuml;sselung der Daten. Wer also ein Backend klaut, der kann zumindest mit den komprimierten Texten nichts anfangen, solange er nicht das Kompressionsverfahren kennt.<\/p>\n<p><b>Demo einer Dokumentenspeicherung <\/b><\/p>\n<p>Bild 2 zeigt das Formular <b>frmDemo <\/b>der Beispieldatenbank <b>binaer.mdb<\/b>. Es hat die Tabelle <b>tblDocuments <\/b>als Datenherkunft, die neben dem BLOB, in dem die Dokumentdateien gespeichert sind, noch zus&auml;tzliche informative Felder enth&auml;lt.<\/p>\n<div class=\"image\">\n            <img decoding=\"async\" src=\"..\/fileadmin\/_temp_\/2007_03\/BinaerspeicherungMitZlib-web-images\/frmDemo2_opt.jpeg\" alt=\"frmDemo2.png\" \/>\n        <\/div>\n<div class=\"story\">\n<p><b><span style=\"color:darkgrey\">Bild 2: Bin&auml;r gespeicherte Dokument-Dateien im Formular anzeigen<\/span><\/b><\/p>\n<\/p><\/div>\n<p>Diese Felder werden beim Anf&uuml;gen einer Datei &uuml;ber die entsprechende Schaltfl&auml;che links unten automatisch gef&uuml;llt und sind schreibgesch&uuml;tzt. Das einzige Feld, in das manuell etwas eingetragen werden kann, ist das Feld <b>Beschreibung<\/b>. Die Infos &uuml;ber Dateigr&ouml;&szlig;e, Objekttyp, OLE-Server, OLE-GUID (CLSID) und Checksum der Datei werden per VBA und zum Teil per API-Funktionen ermittelt, die sich im Modul <b>mdlHelper <\/b>befinden.<\/p>\n<p>Beim Hinzuf&uuml;gen einer Datei &ouml;ffnet sich ein Dateiauswahldialog, mit dem Sie eine beliebige Datei ausw&auml;hlen k&ouml;nnen. Anschlie&szlig;end fragt die Anwendung, ob die Datei komprimiert abgespeichert werden soll. In diesem Fall kommt die ZLIB-Bibliothek zum Einsatz und die Checkbox <b>Gezippt <\/b>bekommt ein H&auml;kchen. Au&szlig;erdem wird dann neben der Gr&ouml;&szlig;e der Ursprungsdatei auch die des komprimierten Resultats angezeigt &#8211; damit k&ouml;nnen Sie auch gut kontrollieren, welche Dateitypen sich f&uuml;r die Komprimierung besonders eignen.<\/p>\n<p>Mit <b>Datei wiederherstellen <\/b>&ouml;ffnet sich ein <b>Speichern<\/b>-Dialog, &uuml;ber den Sie die Datei unter gegebenenfalls neuem Namen in ein beliebiges Verzeichnis extrahieren k&ouml;nnen. Die Schaltfl&auml;che <b>Datei &ouml;ffnen <\/b>zeigt die Datei direkt in der mit ihr verkn&uuml;pften Anwendung an, wobei die oben erw&auml;hnte API-Funktion <b>ShellExecute <\/b>zum Einsatz kommt.<\/p>\n<p>Der Clou ist aber die Schaltfl&auml;che <b>Anzeigen<\/b>, die versucht, die in ein tempor&auml;res Verzeichnis &#8211; hier das Datenbankverzeichnis &#8211; extrahierte Datei direkt im Formular anzuzeigen. Daf&uuml;r wird nicht ein Objektfeld-Steuerelement verwendet, sondern ein Webbrowser-ActiveX-Steuerelement. Dieses Steuerelement steht auf allen Rechnern zur Verf&uuml;gung, die den Internet Explorer installiert haben &#8211; also quasi immer.<\/p>\n<p>Eine Datei l&auml;sst sich in ihm anzeigen, wenn sie mit einem OLE-Server verkn&uuml;pft ist. Dazu reicht der Aufruf der Methode <b>Navigate <\/b>des Steuerelements. Beispiel:<\/p>\n<pre>WebControl1.Object.Navigate \"e:\\datenbanken\\artikel.doc\"<\/pre>\n<p>Hiermit wird ein Word-Dokument in das WebControl eingebettet. Das funktioniert auch mit Excel-Dateien, PDFs &#8211; falls der Adobe Reader installiert ist -, mit zahlreichen Bilddateiformaten und sogar mit ZIP-Dateien: Die werden wie im Explorer als Ordner-Symbol angezeigt und k&ouml;nnen per Doppelklick ge&ouml;ffnet werden. Ist kein OLE-Server mit der Dateiendung verkn&uuml;pft, dann zeigt das WebControl das gleiche Verhalten wie der Internet Explorer: Es fragt, ob man die Datei speichern oder &ouml;ffnen will.<\/p>\n<p>Den einzigen Nachteil, den die BLOB-Speicherung hier gegen&uuml;ber gebundenen OLE-Feldern hat: Die Datei muss tempor&auml;r physisch wiederhergestellt werden, um geladen werden zu k&ouml;nnen. In einer Produktivumgebung sollte man ein separates Verzeichnis f&uuml;r die tempor&auml;ren Dateien anlegen, das beim Beenden der Datenbank automatisch wieder geleert wird, damit sich keine nicht mehr genutzten Dateien ansammeln.<\/p>\n<p><b>Tipps f&uuml;r den Umgang mit Bin&auml;rdaten<\/b><\/p>\n<p>Bin&auml;rdaten nehmen in einer Tabelle im Verh&auml;ltnis zu den &#8222;normalen&#8220; Datenfeldern viel Raum ein. Deshalb werden OLE- und Memo-Felder intern auch als abgetrennte Bl&ouml;cke von JET verwaltet. Das hat unter anderem Performancegr&uuml;nde. Es bringt allerdings manchmal Probleme mit der Synchronisation von OLE-Feldern mit dem Rest des Datensatzes mit sich.<\/p>\n<p>Als Konsequenz kann man sich &uuml;berlegen, dann gleich die Bin&auml;rdaten in separate Tabellen auszulagern und diese per 1:1-Beziehung mit der Mastertabelle zu verkn&uuml;pfen &#8211; oder 1:n, falls einem Hauptdatensatz mehrere Bin&auml;robjekte zugeordnet werden sollen.<\/p>\n<p>Gegebenenfalls kann man die Bin&auml;rdaten in eine separate Backend-Datei verbannen. Dieses &#8222;Bin&auml;r-Backend&#8220; enth&auml;lt dann nur eine Tabelle, die zus&auml;tzlich zum &#8222;normalen&#8220; Backend mit dem Frontend verkn&uuml;pft wird. Die Vorteile davon sind:<\/p>\n<ul>\n<li class=\"aufz-hlung\">Die Stabilit&auml;t der Daten wird erh&ouml;ht. Da Bin&auml;rdaten schon wegen des h&ouml;heren Traffics zum Backend am fehleranf&auml;lligsten sind, werden die Hauptdaten dann nicht von m&ouml;glicher Datenkorruption ber&uuml;hrt.<\/li>\n<li class=\"aufz-hlung\">Die Gr&ouml;&szlig;e von Bin&auml;rdaten f&uuml;hrt dazu, dass gr&ouml;&szlig;ere Teile der Backend-Datei durch Zugriff gesperrt werden, als bei den normalen Daten. Das bedingt auch einen h&ouml;heren Aufwand an Sperrverwaltung f&uuml;r den Server und senkt die Zugriffsperformance insgesamt. Wenn f&uuml;r die Bin&auml;rdaten ein separates Backend vorgesehen wird, so ber&uuml;hrt dieses den Zugriff auf die Hauptdaten nicht.<\/li>\n<li class=\"aufz-hlung\">Sind die Bin&auml;rdaten ausgelagert, dann bleibt das Haupt-Backend vergleichsweise klein und kann damit auch schneller komprimiert werden &#8211; ein Vorgang, der regelm&auml;&szlig;ig ausgef&uuml;hrt werden sollte. Die Gefahr von Datenkorruption beim Komprimieren &#8211; das kommt durchaus vor &#8211; wird zudem minimiert.<\/li>\n<li class=\"aufz-hlung\">Wenn es notwendig sein sollte, dass ein Backend einmal &uuml;ber das Internet transferiert werden muss (etwa zu Wartungs- und Analysezwecken), dann reicht meist das Haupt-Backend, das ohne die Bin&auml;rdaten wesentlich kleiner gepackt werden kann.<\/li>\n<li class=\"aufz-hlung\">Das Limit von 2 GB f&uuml;r die Gr&ouml;&szlig;e einer Access-Datenbank wird auf 4 GB erh&ouml;ht. Wenn nach mehr verlangt wird, dann ist auch das Aufsplitten des Bin&auml;r-Backends in weitere denkbar.<\/li>\n<\/ul>\n<p><b>Zusammenfassung<\/b><\/p>\n<p>Die Scheu vor dem Speichern von Dateien und anderen Bin&auml;rdaten in Datenbanken ist nach Erfahrung des Autors unbegr&uuml;ndet. Es gibt zahlreiche Anwendungszwecke, von denen die Verwaltung von Bildern und Dokumenten sicher die am h&auml;ufigsten eingesetzte ist.<\/p>\n<p>Das oft ins Feld gef&uuml;hrte Aufbl&auml;hen von Datenbanken mit Bin&auml;rdaten ist nur mit OLE-Objekten ein Problem und reduziert sich durch den Einsatz von Komprimierungsroutinen auf ein Mindestma&szlig;.<\/p>\n<p>Dennoch sollte man es nicht &uuml;bertreiben und sich nicht unbedingt gleich an die Grenze von 2 GB f&uuml;r ein Backend heranwagen. Die d&uuml;rfte allerdings auch nicht so schnell erreicht sein, denn in einem so gro&szlig;en Backend h&auml;tten in ZLIB-komprimiertem Zustand etwa 30.000 PDF-Dokumente mit je 20 Seiten Platz.<\/p>\n<p><b>Quellen:<\/b><\/p>\n<p class=\"quellen\">[1] ZLIB-Projekt: http:\/\/www.zlib.net\/<\/p>\n<p class=\"quellen\">[2] ZLIBWapi-Variante: http:\/\/www.winimage.com\/zLibDll\/minizip.html<\/p>\n<h3>Downloads zu diesem Beitrag<\/h3>\n<p>Enthaltene Beispieldateien:<\/p>\n<p>binaer.mdb<\/p>\n<p>zlibwapi.dll<\/p>\n<p>binaer.accdb<\/p>\n<p><a href=\"..\/fileadmin\/beispiele\/6FA66886-ADB2-415A-9E90-A1F4DDBC66BA\/aiu_466.zip\">Download<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Dateien oder andere Bin&auml;robjekte in Datenbanktabellen zu speichern, ist bei vielen Access-Entwicklern verp&ouml;nt. Das Hauptargument, das man dabei zu h&ouml;ren bekommt, ist das unverh&auml;ltnism&auml;&szlig;ige Aufbl&auml;hen der Datenbanken. Das greift jedoch nur dann, wenn die Objekte in einem OLE-Feld als OLE-Objekte abgespeichert werden. Denn dabei findet eine Konversion der Quelldateien in OLE-kompatible Dokumentenformate statt, die sie vergr&ouml;&szlig;ern. Dabei lassen sich die Dateien mit wirklich bin&auml;rer Speicherung als BLOBs durchaus Platz sparend unterbringen &#8211; vor allem, wenn man sie dann noch zus&auml;tzlich mit einer Komprimierung versieht. Im folgenden Beitrag werden einige Anwendungsbeispiele und die zugrunde liegenden Techniken beleuchtet.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[662007,66032007,44000040,44000034,44000025],"tags":[],"class_list":["post-55000466","post","type-post","status-publish","format-standard","hentry","category-662007","category-66032007","category-Allgemein","category-ImportExport","category-VBA_und_Programmiertechniken"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.9 (Yoast SEO v27.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Komprimierte Bin&auml;rspeicherung  - Access im Unternehmen<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/access-im-unternehmen.de\/Komprimierte_Binaerspeicherung_\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Komprimierte Bin&auml;rspeicherung\" \/>\n<meta property=\"og:description\" content=\"Dateien oder andere Bin&auml;robjekte in Datenbanktabellen zu speichern, ist bei vielen Access-Entwicklern verp&ouml;nt. Das Hauptargument, das man dabei zu h&ouml;ren bekommt, ist das unverh&auml;ltnism&auml;&szlig;ige Aufbl&auml;hen der Datenbanken. Das greift jedoch nur dann, wenn die Objekte in einem OLE-Feld als OLE-Objekte abgespeichert werden. Denn dabei findet eine Konversion der Quelldateien in OLE-kompatible Dokumentenformate statt, die sie vergr&ouml;&szlig;ern. Dabei lassen sich die Dateien mit wirklich bin&auml;rer Speicherung als BLOBs durchaus Platz sparend unterbringen - vor allem, wenn man sie dann noch zus&auml;tzlich mit einer Komprimierung versieht. Im folgenden Beitrag werden einige Anwendungsbeispiele und die zugrunde liegenden Techniken beleuchtet.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/access-im-unternehmen.de\/Komprimierte_Binaerspeicherung_\/\" \/>\n<meta property=\"og:site_name\" content=\"Access im Unternehmen\" \/>\n<meta property=\"article:published_time\" content=\"2021-02-11T21:16:37+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/vg04.met.vgwort.de\/na\/826749b8e07e45e391bc6dbb3df598d4\" \/>\n<meta name=\"author\" content=\"Andr\u00e9 Minhorst\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Andr\u00e9 Minhorst\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"23\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Komprimierte_Binaerspeicherung_\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Komprimierte_Binaerspeicherung_\\\/\"},\"author\":{\"name\":\"Andr\u00e9 Minhorst\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\"},\"headline\":\"Komprimierte Bin&auml;rspeicherung\",\"datePublished\":\"2021-02-11T21:16:37+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Komprimierte_Binaerspeicherung_\\\/\"},\"wordCount\":4246,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Komprimierte_Binaerspeicherung_\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg04.met.vgwort.de\\\/na\\\/826749b8e07e45e391bc6dbb3df598d4\",\"articleSection\":{\"0\":\"2007\",\"1\":\"3\\\/2007\",\"3\":\"Import\\\/Export\",\"4\":\"VBA und Programmiertechniken\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Komprimierte_Binaerspeicherung_\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Komprimierte_Binaerspeicherung_\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Komprimierte_Binaerspeicherung_\\\/\",\"name\":\"Komprimierte Bin&auml;rspeicherung - Access im Unternehmen\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Komprimierte_Binaerspeicherung_\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Komprimierte_Binaerspeicherung_\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/vg04.met.vgwort.de\\\/na\\\/826749b8e07e45e391bc6dbb3df598d4\",\"datePublished\":\"2021-02-11T21:16:37+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Komprimierte_Binaerspeicherung_\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/access-im-unternehmen.de\\\/Komprimierte_Binaerspeicherung_\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Komprimierte_Binaerspeicherung_\\\/#primaryimage\",\"url\":\"http:\\\/\\\/vg04.met.vgwort.de\\\/na\\\/826749b8e07e45e391bc6dbb3df598d4\",\"contentUrl\":\"http:\\\/\\\/vg04.met.vgwort.de\\\/na\\\/826749b8e07e45e391bc6dbb3df598d4\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/Komprimierte_Binaerspeicherung_\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Komprimierte Bin&auml;rspeicherung\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#website\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"name\":\"Access im Unternehmen\",\"description\":\"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access\",\"publisher\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/access-im-unternehmen.de\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#organization\",\"name\":\"Andr\u00e9 Minhorst Verlag\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"contentUrl\":\"https:\\\/\\\/access-im-unternehmen.de\\\/wp-content\\\/uploads\\\/2019\\\/09\\\/aiu_wp.png\",\"width\":370,\"height\":111,\"caption\":\"Andr\u00e9 Minhorst Verlag\"},\"image\":{\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/access-im-unternehmen.de\\\/#\\\/schema\\\/person\\\/13395c4bcd7d7963efe33be9c584d93f\",\"name\":\"Andr\u00e9 Minhorst\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g\",\"caption\":\"Andr\u00e9 Minhorst\"}}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Komprimierte Bin&auml;rspeicherung  - Access im Unternehmen","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/access-im-unternehmen.de\/Komprimierte_Binaerspeicherung_\/","og_locale":"de_DE","og_type":"article","og_title":"Komprimierte Bin&auml;rspeicherung","og_description":"Dateien oder andere Bin&auml;robjekte in Datenbanktabellen zu speichern, ist bei vielen Access-Entwicklern verp&ouml;nt. Das Hauptargument, das man dabei zu h&ouml;ren bekommt, ist das unverh&auml;ltnism&auml;&szlig;ige Aufbl&auml;hen der Datenbanken. Das greift jedoch nur dann, wenn die Objekte in einem OLE-Feld als OLE-Objekte abgespeichert werden. Denn dabei findet eine Konversion der Quelldateien in OLE-kompatible Dokumentenformate statt, die sie vergr&ouml;&szlig;ern. Dabei lassen sich die Dateien mit wirklich bin&auml;rer Speicherung als BLOBs durchaus Platz sparend unterbringen - vor allem, wenn man sie dann noch zus&auml;tzlich mit einer Komprimierung versieht. Im folgenden Beitrag werden einige Anwendungsbeispiele und die zugrunde liegenden Techniken beleuchtet.","og_url":"https:\/\/access-im-unternehmen.de\/Komprimierte_Binaerspeicherung_\/","og_site_name":"Access im Unternehmen","article_published_time":"2021-02-11T21:16:37+00:00","og_image":[{"url":"http:\/\/vg04.met.vgwort.de\/na\/826749b8e07e45e391bc6dbb3df598d4","type":"","width":"","height":""}],"author":"Andr\u00e9 Minhorst","twitter_card":"summary_large_image","twitter_misc":{"Verfasst von":"Andr\u00e9 Minhorst","Gesch\u00e4tzte Lesezeit":"23\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/access-im-unternehmen.de\/Komprimierte_Binaerspeicherung_\/#article","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/Komprimierte_Binaerspeicherung_\/"},"author":{"name":"Andr\u00e9 Minhorst","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f"},"headline":"Komprimierte Bin&auml;rspeicherung","datePublished":"2021-02-11T21:16:37+00:00","mainEntityOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Komprimierte_Binaerspeicherung_\/"},"wordCount":4246,"commentCount":0,"publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Komprimierte_Binaerspeicherung_\/#primaryimage"},"thumbnailUrl":"http:\/\/vg04.met.vgwort.de\/na\/826749b8e07e45e391bc6dbb3df598d4","articleSection":{"0":"2007","1":"3\/2007","3":"Import\/Export","4":"VBA und Programmiertechniken"},"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/access-im-unternehmen.de\/Komprimierte_Binaerspeicherung_\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/access-im-unternehmen.de\/Komprimierte_Binaerspeicherung_\/","url":"https:\/\/access-im-unternehmen.de\/Komprimierte_Binaerspeicherung_\/","name":"Komprimierte Bin&auml;rspeicherung - Access im Unternehmen","isPartOf":{"@id":"https:\/\/access-im-unternehmen.de\/#website"},"primaryImageOfPage":{"@id":"https:\/\/access-im-unternehmen.de\/Komprimierte_Binaerspeicherung_\/#primaryimage"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/Komprimierte_Binaerspeicherung_\/#primaryimage"},"thumbnailUrl":"http:\/\/vg04.met.vgwort.de\/na\/826749b8e07e45e391bc6dbb3df598d4","datePublished":"2021-02-11T21:16:37+00:00","breadcrumb":{"@id":"https:\/\/access-im-unternehmen.de\/Komprimierte_Binaerspeicherung_\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/access-im-unternehmen.de\/Komprimierte_Binaerspeicherung_\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/Komprimierte_Binaerspeicherung_\/#primaryimage","url":"http:\/\/vg04.met.vgwort.de\/na\/826749b8e07e45e391bc6dbb3df598d4","contentUrl":"http:\/\/vg04.met.vgwort.de\/na\/826749b8e07e45e391bc6dbb3df598d4"},{"@type":"BreadcrumbList","@id":"https:\/\/access-im-unternehmen.de\/Komprimierte_Binaerspeicherung_\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/access-im-unternehmen.de\/"},{"@type":"ListItem","position":2,"name":"Komprimierte Bin&auml;rspeicherung"}]},{"@type":"WebSite","@id":"https:\/\/access-im-unternehmen.de\/#website","url":"https:\/\/access-im-unternehmen.de\/","name":"Access im Unternehmen","description":"Das Magazin f\u00fcr Datenbankentwickler auf Basis von Microsoft Access","publisher":{"@id":"https:\/\/access-im-unternehmen.de\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/access-im-unternehmen.de\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/access-im-unternehmen.de\/#organization","name":"Andr\u00e9 Minhorst Verlag","url":"https:\/\/access-im-unternehmen.de\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/","url":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","contentUrl":"https:\/\/access-im-unternehmen.de\/wp-content\/uploads\/2019\/09\/aiu_wp.png","width":370,"height":111,"caption":"Andr\u00e9 Minhorst Verlag"},"image":{"@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/access-im-unternehmen.de\/#\/schema\/person\/13395c4bcd7d7963efe33be9c584d93f","name":"Andr\u00e9 Minhorst","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1b9d010cf1716692cb9c34f21554e07d17d461acaea5b61b8cb21cbec678d48a?s=96&d=mm&r=g","caption":"Andr\u00e9 Minhorst"}}]}},"_links":{"self":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000466","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/comments?post=55000466"}],"version-history":[{"count":0,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/posts\/55000466\/revisions"}],"wp:attachment":[{"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/media?parent=55000466"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/categories?post=55000466"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/access-im-unternehmen.de\/data\/wp\/v2\/tags?post=55000466"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}