bytea
データ型はバイナリ列の保存を可能にします。
表 8.6を参照してください。
表8.6 バイナリ列データ型
型名 | 格納サイズ | 説明 |
---|---|---|
bytea | 1または4バイトと実際のバイナリ列の長さ | 可変長のバイナリ列 |
バイナリ列はオクテット(またはバイト)の連続です。 バイナリ列は2つの点で文字列と区別されます。 1点目は、バイナリ列はゼロの値のオクテットと他の「表示できない」オクテット(通常10進数表記で32から126の範囲外のオクテット)を保存できるということです。 文字列ではゼロというオクテットは使用できません。 また、データベースで選択している文字セット符号化方式で無効なオクテット値やオクテット値の並びも使用できません。 2点目は、バイナリ列を演算すると実際のバイトが処理されるのに対して、文字列の処理はロケール設定に従うということです。 まとめると、バイナリ列はプログラマが「バイト列そのもの」と考えるものを格納するのに適し、文字列はテキストを格納するのに適しています。
bytea
型は入出力用に2つの書式をサポートします。
「hex」書式とPostgreSQLの歴史的な「エスケープ」書式です。
入力ではこれらの両方とも常に受け入れられます。
出力書式はbytea_output設定パラメータに依存し、デフォルトではhexです。
(hex書式はPostgreSQL 9.0から導入されたものであることに注意してください。
以前のバージョンや一部のツールではこれを理解しません。)
標準SQLは、BLOB
またはBINARY LARGE OBJECT
という、異なるバイナリ列型を定義します。
入力書式はbytea
と異なりますが、提供される関数および演算子はほぼ同じです。
bytea
のhex書式
「hex」書式ではバイナリデータの各バイトを上位4ビット、下位4ビットの順で2桁の16進数に符号化します。
(エスケープ書式と区別するために)文字列全体は\x
という並びの後に付けられます。
一部の文脈では、先頭のバックスラッシュを二重にしてエスケープさせる必要があるかもしれません(以下を参照 4.1.2.1)。
これはエスケープ書式でバックスラッシュを二重にしなければならない場合と同じで、詳細は以下に示します。
入力する16進数の桁は大文字でも小文字でも構いません。
数字のペアの間に空白文字を入れることができます。
(しかし桁の組み合わせの間や先頭の\x
の間には入れることはできません。)
hex書式は外部のアプリケーションおよびプロトコルの間で広く互換性を持ち、また、エスケープ書式と比べ変換が高速になる傾向があります。
このため使用が好まれます。
例
SELECT '\xDEADBEEF';
bytea
のエスケープ書式
「エスケープ」書式はbytea
型用の伝統的なPostgreSQLの書式です。
これは、バイナリ列をASCII文字の並びとして表現しASCII文字として表現できないバイトは特殊なエスケープシーケンスとして表現するという方式を取ります。
アプリケーションの見地から文字として表現されたバイトが有意であれば、この表現は簡便です。
しかし現実にはバイナリ列と文字列の間の区別があいまいになりますので、通常は混乱します。
また選択されたこのエスケープ機構自体が多少非効率的です。
このためこの書式はおそらくほとんどの新しいアプリケーションでは避けるべきでしょう。
エスケープ書式でbytea
値を入力する際に、特定の値のオクテットをエスケープする必要があります。
なお、すべてのオクテットの値をエスケープすることができます。
一般的にあるオクテットをエスケープするには、それをその3桁の8進数に変換し、バックスラッシュを前に付けます。
他にもバックスラッシュ自体(10進数表記のオクテットで92)を二重のバックスラッシュとして表現することができます。
表 8.7には、エスケープする必要がある文字と、その適用可能な代替エスケープシーケンスを示しています。
表8.7 オクテットをエスケープしたbytea
リテラル
10進オクテット値 | 説明 | エスケープされた入力表現 | 例 | 出力表現 |
---|---|---|---|---|
0 | ゼロオクテット | '\000' | '\000'::bytea; | \x00 |
39 | 単一引用符 | '''' もしくは'\047' | ''''::bytea; | \x27 |
92 | バックスラッシュ | '\\' もしくは'\\134' | '\\'::bytea; | \x5c |
0から31まで、および127から255まで | 「表示できない」オクテット | '\ (8進数) | '\001'::bytea; | \x01 |
実際には、表示できないオクテットに対するエスケープ要求はロケールの設定に依存して異なります。 ロケールの設定によっては、エスケープをしないで済むこともあります。
表 8.7で示したように、シングルクォートが二重に必要な理由は、SQLコマンド中のあらゆる文字列に当てはまるためです。
一般的な文字列パーサは最も外側のシングルクォートを消費し、シングルクォートのペアを一つの文字データに減らします。
bytea
を入力する関数が見るのは単に一つのシングルクォートであり、一個の単純なデータ文字として扱います。
しかし、bytea
を入力する関数はバックスラッシュを特別なものとして扱い、表 8.7に示されているその他の動作はこの関数で実装されています。
一般的な文字列パーサはバックスラッシュのペアを一つの文字データに減らすため、文脈によってはバックスラッシュは上記に見られるように、重ねる必要があります。 4.1.2.1も参照ください。
Bytea
オクテットはデフォルトではhex
書式で出力されます。
bytea_outputをescape
に変えると、「表示できない」オクテットは先頭にバックスラッシュがついた3桁のオクテットの値に変換されます。
ほとんどの「表示可能な」オクテットはクライアント文字セットの標準的な表示で出力されます。例:
SET bytea_output = 'escape'; SELECT 'abc \153\154\155 \052\251\124'::bytea; bytea ---------------- abc klm *\251T
10進数で92(バックスラッシュ)を持つオクテットは出力時に二重になります。 詳細は表 8.8を参照してください。
表8.8 bytea
出力のエスケープされたオクテット
10進オクテット値 | 説明 | エスケープされた出力表現 | 例 | 出力結果 |
---|---|---|---|---|
92 | バックスラッシュ | \\ | '\134'::bytea | \\ |
0から31および127から255 | 「表示できない」オクテット | \ (8進数) | '\001'::bytea; | \001 |
32から126 | 「表示できる」オクテット | クライアント文字セットにおける表現 | '\176'::bytea; | ~ |
使用するPostgreSQLのフロントエンドによっては、bytea
文字列をエスケープまたはアンエスケープする追加的な作業が必要になることがあります。
例えば、使用するインタフェースが改行文字や復帰文字を自動的に翻訳してしまう場合、これらの文字もエスケープしなければならないかもしれません。