Die meisten Datenbanksysteme bieten einen Datentyp, der Rohdaten speichern kann, und PostgreSQL ist keine Ausnahme. Ich verwende den Begriff Rohdaten, um zu bedeuten, dass die Datenbank die Struktur oder Bedeutung eines Werts nicht versteht. Im Gegensatz dazu versteht PostgreSQL die Struktur und Bedeutung anderer Datentypen. Wenn Sie beispielsweise eine INTEGER-Spalte definieren, weiß PostgreSQL, dass die Datenbytes, die Sie in diese Spalte einfügen, einen Integer-Wert darstellen sollen. PostgreSQL weiß, was eine Ganzzahl ist?es kann Ganzzahlen hinzufügen, multiplizieren, in und aus String-Form konvertieren und so weiter. Rohdaten hingegen sind nur eine Sammlung von Bits?PostgreSQL kann keine Bedeutung in den Daten ableiten.

PostgreSQL bietet den Typ BYTEA zum Speichern von Rohdaten an. Eine BYTEA-Spalte kann theoretisch Werte beliebiger Länge enthalten, aber es scheint, dass die maximale Länge 1 GB beträgt.

Die Größe eines BYTEA-Werts beträgt 4 Byte plus die tatsächliche Anzahl der Byte im Wert.

Syntax für Literalwerte

Die Eingabe eines BYTEA-Werts kann etwas schwierig sein. Ein BYTEA-Literal wird als String-Literal eingegeben: Es ist nur eine Zeichenfolge, die in einfache Anführungszeichen eingeschlossen ist. Wie geben Sie vor diesem Hintergrund einen BYTEA-Wert ein, der ein einzelnes Anführungszeichen enthält? Wenn Sie auf die Diskussion über Zeichenfolgenliteralwerte (früher in diesem Kapitel) zurückblicken, werden Sie feststellen, dass Sie Sonderzeichen in einen Zeichenfolgenwert aufnehmen können, indem Sie sie maskieren. Insbesondere kann ein einzelnes Anführungszeichen auf drei Arten maskiert werden:

  • Verdoppeln Sie die einfachen Anführungszeichen (‚Dies ist ein einfaches Anführungszeichen“‚)

  • Vor dem einfachen Anführungszeichen steht ein Backslash (‚Dies ist ein einfaches Anführungszeichen \“)

  • Fügen Sie stattdessen den Oktalwert des Zeichens ein (‚Dies ist ein einfaches Anführungszeichen \047‘)

Es gibt zwei weitere Zeichen, die Sie bei der Eingabe von BYTEA-Literalen maskieren müssen. Ein Byte, dessen Wert Null ist (nicht das Zeichen 0, sondern das Nullbyte), muss maskiert werden, und das Backslash-Zeichen muss maskiert werden. Sie können jedes Zeichen mit der Form „\\ddd“ maskieren (wobei ddd eine Oktalzahl ist). Sie können jedes druckbare Zeichen mit dem Formular „\\c“ maskieren. Wenn Sie also einen BYTEA-Wert speichern möchten, der ein Nullbyte enthält, können Sie ihn folgendermaßen eingeben:

'This is a zero byte \000'

Wenn Sie einen BYTEA-Wert speichern möchten, der einen umgekehrten Schrägstrich enthält, können Sie ihn in einem der folgenden Formulare eingeben:

'This is a backslash \\''This is also a backslash \134'

Wenn Sie diese Regeln mit den Regeln zum Zitieren von Zeichenfolgenliteralen vergleichen, werden Sie feststellen, dass BYTEA-Literale doppelt so viele Backslash-Zeichen benötigen. Dies ist eine Eigenart des Designs des PostgreSQL-Parsers. BYTEA-Literale werden von zwei verschiedenen Parsern verarbeitet. Der Haupt-PostgreSQL-Parser sieht ein BYTEA-Literal als String-Literal (verschlingt den ersten Satz von Backslash-Zeichen). Dann verarbeitet der BYTEA-Parser das Ergebnis und verschlingt den zweiten Satz von Backslash-Zeichen.

Wenn Sie also einen BYTEA-Wert wie This is a backslash \haben, zitieren Sie ihn als ‚This is a backslash \\\\‘. Nachdem der String-Parser diesen String verarbeitet hat, wurde er in ‚This is a backslash \\‘ umgewandelt. Der BYTEA-Parser wandelt dies schließlich in This is a backslash \ .

Unterstützte Operatoren

PostgreSQL bietet einen einzigen BYTEA-Operator: concatenation. Sie können einen BYTEA-Wert mit dem Verkettungsoperator (||) an einen anderen BYTEA-Wert anhängen.

Beachten Sie, dass Sie zwei BYTEA-Werte nicht vergleichen können, auch nicht für Gleichheit / Ungleichheit. Sie können natürlich einen BYTEA-Wert mit dem Operator CAST() in einen anderen Wert konvertieren, wodurch andere Operatoren geöffnet werden.

Large-Objects

Der BYTEA-Datentyp ist derzeit auf das Speichern von Werten beschränkt, die nicht größer als 1 GB sind. Wenn Sie Werte speichern müssen, die größer sind, als in eine BYTEA-Spalte passen, können Sie large-objects . Ein large-object ist ein Wert, der außerhalb einer Tabelle gespeichert ist. Wenn Sie beispielsweise mit jeder Zeile in Ihrer Tapes-Tabelle ein Foto speichern möchten, fügen Sie eine OID-Spalte hinzu, die einen Verweis auf das entsprechende Large-object enthält:

movies=# ALTER TABLE tapes ADD COLUMN photo_id OID;ALTER

Jeder Wert in der Spalte photo_id bezieht sich auf einen Eintrag in der Systemtabelle pg_largeobject. PostgreSQL bietet eine Funktion, die eine externe Datei (z. B. eine JPEG-Datei) in die Tabelle pg_largeobject lädt:

movies=# INSERT INTO tapes VALUESmovies-# (movies(# 'AA-55892',movies(# 'Casablanca',movies(# lo_import('/tmp/casablanca.jpg' )movies(# );

Die Funktion lo_import() lädt die benannte Datei in pg_largeobject und gibt einen OID-Wert zurück, der sich auf das Large-object bezieht. Wenn Sie nun diese Zeile auswählen, sehen Sie die OID, nicht die tatsächlichen Bits, aus denen das Foto besteht:

movies=# SELECT * FROM tapes WHERE title = 'Casablanca'; tape_id | title | photo_id----------+------------+---------- MC-68873 | Casablanca | 510699

Wenn Sie das Foto wieder in eine Datei schreiben möchten, können Sie die Funktion lo_export() verwenden:

movies=# SELECT lo_export( 510699, '/tmp/Casablanca.jpg' ); lo_export----------- 1(1 row)

Um alle großen Objekte in der aktuellen Datenbank anzuzeigen, verwenden Sie den Metabefehl \lo_list von psql:

movies=# \lo_list Large objects ID | Description--------+------------- 510699 |(1 row)

Sie können große Objekte mit der Funktion lo_unlink () aus Ihrer Datenbank entfernen:

movies=# SELECT lo_unlink( 510699 ); lo_unlink----------- 1(1 row)movies=# \lo_list Large objects ID | Description----+-------------(0 rows)

Wie kommen Sie zu den tatsächlichen Bits hinter der Referenz-OID? Kannst du nicht?zumindest nicht mit psql. Die Unterstützung für große Objekte muss in die Clientanwendung integriert sein, die Sie verwenden. psql ist ein textorientiertes Werkzeug und hat keine Möglichkeit, ein Foto anzuzeigen, also ist das Beste, was Sie tun können, die Rohdaten in der pg_largeobject Tabelle pg_largeobject . Einige Clientanwendungen, wie die Conjectrix Workstation, unterstützen große Objekte und können die Rohdaten in den meisten Fällen richtig interpretieren.