8.4. 二進制資料類型

bytea 資料類型允許儲存二進制字串。 參閱Table 8-6

Table 8-6. 二進制資料類型

名字儲存空間描述
bytea4 字元加上實際的二進制字串變長的二進制字串

二進制字串是一個字元數值的序列。 二進制字串和字元字串的區別有兩個: 首先,二進制字串完全可以允許儲存字元零值以及其它"不可打印的"字元 (定義為範圍在 32 到 126 之外的字元)。 字元串不允許字元零,並且也不允許那些從資料庫選定的字元集編碼裡面認為是非法的其它字元值或者字元序列。 第二,對二進制串的處理就是實際上的字元,而字元串的處理和取決於區域設置。 簡單說,二進制字串適用於儲存那些程序員認為是"裸字元"的資料, 而字元串適合儲存文本。

在輸入 bytea 數值的時候, 在一個 SQL 語句的文本串裡面, 您必須逃逸某些字元值(但 可以逃逸所有字元值) 通常,要逃逸一個字元值,需要把它的數值轉換成與其十進制字元值對應的三位八進制數字, 並且前導兩個反斜槓。有些八進制數值有可選的逃逸序列, 在 Table 8-7 中顯示, 同時給出了可選的逃逸序列。

Table 8-7. bytea 文本逃逸八進制

十進制數值描述輸入逃逸資料表現形式例子輸出形式
0 零的八進制 '\\000' select '\\000'::bytea; \000
39 單引號 '\'' 或者 '\\047' select '\''::bytea; '
92 反斜槓 '\\\\' 或者 '\\134' select '\\\\'::bytea; \\
0 到 31 和 127 到 255"不可打印"字元'\\xxx' (八進制值)SELECT '\\001'::bytea;\001

逃逸"不可打印"字元的要求因區域設置而異。在某些場合下,您可以不逃逸它們。 請注意Table 8-7裡的每個例子都是剛好一個字元長,雖然字元零和反斜槓輸出形式比一個字元要長。

您必須寫這麼多反斜槓的原因,如 Table 8-7 所示, 是因為一個寫成字串文本的輸入字串必須透過 PostgreSQL 伺服器裡的兩個分析階段。 每個反斜槓對的第一個反斜槓會被字串文本分析其理解成一個逃逸字元而消耗掉, 剩下反斜槓對中的第二個。剩下的反斜槓被 bytea 輸入函數當作一個三位八進制值或者是逃逸另外一個反斜槓的開始。 比如,一個傳遞給伺服器的字串文本 '\\001' 在透過字串分析器之後會成為 \001。而 \001 則發送給 bytea 輸入函數,在這裡它被轉換成一個十進制值為 1 的單個字元。請注意,省略字元不會被 bytea 特殊對待, 因此它遵循字串文本的普通規則。(又見 Section 4.1.2.1。)

Bytea 字元也在輸出中逃逸的。通常, 每個"不可打印"的字元值都轉化成對應的前導反斜槓的三位八進制數值。 大多數"可打印的"字元值是以客戶端字元集的標準資料表現形式出現的。 十進制值為 92 (反斜槓)的字元有一個特殊的可選輸出形式。細節在 Table 8-8 裡描述。

Table 8-8. bytea 輸出逃逸序列

字元的十進制值描述逃逸的輸出形式例子輸出結果
92 反斜槓 \\ select '\\134'::bytea; \\
0 到 31 和 127 到 255 "不可打印"八進制字元 \xxx(octal value) select '\\001'::bytea; \001
32 到 126 "可打印"八進制字元 客戶端字元集資料表現形式 select '\\176'::bytea; ~

根據您使用的前端的不同,在逃不逃逸 bytea 字串的問題上您可能有一些額外的工作要做。 比如,如果您的接口自動轉換進行(發音:hang)和回車,那您可能還要逃逸它們。

SQL 標準定義了一種不同的二進制字串類型, 叫做 BLOB 或者 BINARY LARGE OBJECT。 期輸入格式和 bytea 不同,但是提供的函數和操作符大多一樣。