Programmierung

Große binäre Objekte

Für Datenbanksysteme besteht die Anforderung, neben der Speicherung von Daten in atomaren Datentypen wie String, Float, Integer etc. auch unstrukturierte Daten ablegen zu können. Hierzu zählen zum Beispiel Dokumente, Multimedia- und Audiodaten.


Für diese Daten bieten die Systeme in aller Regel den Datentyp Blob (Binary Large Object) an. Ein Blob ist in der Lage, beliebige Binärdaten zu speichern. Diese werden vom System nicht weiter interpretiert. Das heißt, es spielt keine Rolle, ob sich in dem Blob ein XML-Dokument oder eine Rastergrafik befindet.

In CONZEPT 16 ist das Verarbeiten von Blob-Daten ebenfalls möglich. Die binären Daten werden in der Datenbank in einer Verzeichnisstruktur, vergleichbar mit einem Dateisystem, gespeichert. Voraussetzung für das Ablegen von Daten als Blobs ist das Vorhandensein mindestens eines Verzeichnisses.

Zum Verarbeiten der Verzeichnisse und binärer Daten stellt CONZEPT 16 eine Reihe von Befehlen zur Verfügung. Im Nachfolgenden werde ich auf einige Funktionen eingehen.

Anlegen Verzeichnisstruktur
// Verzeichnis "Dokumente" erzeugen
tDirHdl    # BinDirOpen(0,'Dokumente',_BinCreate);

// Unterverzeichnis "PDF" erzeugen
tSubDirHdl # BinDirOpen(tDirHdl,'PDF',_BinCreate);

// Handles schließen
tDirHdl   ->BinClose();
tSubDirHdl->BinClose();

Im obigen Beispiel wird in der Root das Verzeichnis mit dem Namen "Dokumente" erzeugt. Unterhalb von "Dokumente" das Verzeichnis "PDF". Der nächste Schritt besteht aus dem Anlegen eines binären Objekts und dem Einlesen eines extern vorliegenden Dokumentes.

Anlegen eines binären Objekts und füllen mit Daten
define
{
  mDocument : _Sys->spPathMyDocuments + '\MyDocument.pdf'
}

// Öffnen Verzeichnis "PDF"
tDirHdl # BinDirOpen(0,'Dokumente\PDF');

// Binäres Objekt anlegen
tBinHdl # tDirHdl->BinOpen(FsiSplitName(mDocument,_FsiNameNE),_BinCreate | _BinLock);

// Externe Datei "MyDocument.pdf" als Blob einlesen
tBinHdl->BinImport(mDocument);

// Handles schließen
tBinHdl->BinClose();
tDirHdl->BinClose();
Exportieren des Inhalts binärer Objekte

Je nach Anwendungsfall kann es erforderlich sein, den Inhalt wieder aus der Datenbank zu exportieren. Hierfür steht uns die Funktion BinExport() zur Verfügung:

define
{
  mDocument : _Sys->spPathMyDocuments + '\MyDocument.pdf'
}

// Öffnen Verzeichnis "PDF"
tDirHdl # BinDirOpen(0,'Dokumente\PDF');

// Binäres Objekt öffnen
tBinHdl # tDirHdl->BinOpen(FsiSplitName(mDocument,_FsiNameNE));

// Inhalt exportieren
tBinHdl->BinExport(mDocument);

// Handles schließen
tBinHdl->BinClose();
tDirHdl->BinClose();
Verwendung von binären Objekten innerhalb der Anwendung

In Abhängigkeit des Dateityps können die Inhalte binärer Objekte direkt aus der Datenbank in verschiedenen Oberflächen- und Druck-Objekten für die Ausgabe verwendet werden. Dazu wird in der entsprechenden Eigenschaft der Name und Pfad des binären Objekts angegeben:

// Anzeige binäres Objekt in einem DocView-Objekt
tDocView->wpFileName # '>0\Dokumente\PDF\MyDocument.pdf';

Weiterführende Informationen zu den binären Objekten finden sich in der Dokumentation im Kapitel "Binäre Objekte".

6 Kommentare

6 Kommentare “Große binäre Objekte”

  1. Der Fall ist eigentlich schon länger bestätigt und unter anderem mit dem Ticket "VS-BB4891DE" bei Euch registriert. Am 28.02.2012 habe ich zudem nochmals nachgehakt.

    Ich habe es soeben erneut mit der Version 5.07.03 getestet, am beanstandeten Verhalten hat sich leider nichts geändert. Dabei habe ich allerdings noch festgestellt, dass es funktioniert, wenn nur die Option "_BinLock" verwendet wird. Wenn allerdings mit "_BinCreate | _BinLock" gearbeitet wird, kommt es zu beschriebenem Problem.

    Besten Dank für Eure Bemühungen.

  2. @Fabian
    Das können wir nicht bestätigen. Wir erhalten als Resultat den Wert -1506 (_ErrBinLocked). Bitte melde Dich doch einmal bei uns. Eventuell liegt es an einer bestimmten Konstellation.

  3. Wünschenswert wäre nun natürlich noch, dass die Benutzersperren von den Bin-Befehlen korrekt ausgewertet werden würden. Dies ist nämlich beim Befehl BinDirOpen() nicht der Fall. Unabhängig davon, ob ein Benutzer bereits eine Sperre auf einen binären Pfad eingerichtet hat, erhält der zweite Benutzer, der ebenfalls eine Sperranfrage stellt, einen gültigen Deskriptor als Ergebnis zurück, statt dem für diesen Fall vorgesehenen Fehlercode _ErrBinLocked.

  4. @Klaus
    Vielen Dank für die Fragen. Nachfolgend die Antworten:

    Zu Frage 1)
    Die Zugriffszeit ist unabhängig von der Anzahl binärer Objekte die sich in einem Verzeichnis befinden.

    Zu Frage 2)
    Beim Zugriff auf binäre Objekte mit einer hohen Verzeichnistiefe ist es empfehlenswert, zuerst das Zielverzeichnis mit der Funktion BinDirOpen() zu öffnen und anschließend das Objekt zu lesen.

    Beispiel:
    tDirHdl # BinDirOpen(tDirHdl,’Verzeichnis 1Verzeichnis 2’Verzeichnis 3);
    tBinHdl # tDirHdl->BinOpen(‚MyDocument.pdf‘);
    tDirHdl->BinClose();
    tBinHdl->BinClose();

    Das Lesen des Objekts unter Angabe der kompletten Verzeichnisstruktur kann bei einer hohen Verzeichnistiefe etwas langsamer ausfallen.

    Beispiel:
    tBinHdl # BinOpen(0,’Verzeichnis 1Verzeichnis 2Verzeichnis 3MyDocument.pdf‘);
    tBinHdl->BinClose();

    ZU Frage 3)
    Weitere Optimierungsmöglichkeiten sind nicht erforderlich.

  5. vielen Dank für die Infos zu den BLOBs.
    Ich habe hierzu auch ein paar Fragen

    Ergibt sich für die Zugriffszeit auf binäre Objekte ein Unterschied, wenn sehr viele Objekte in einem (Unter-)Verzeichnis sind oder die Objekte auf mehrere Verzeichnisse verteilt sind ?

    Hat die Verzeichnistiefe (viele geschachtelte Unterverzeichnisse) einen Einfluss auf die Zugriffszeiten ?

    Kann man hier bereits im Vorfeld bei der Planung eine Optimierung der Zugriffszeiten erreichen ?

    Schon jetzt vielen Dank für Erfahrungswerte hierzu.

Kommentar abgeben