Skip to content

8.4. 二进制数据类型#

8.4.1. bytea 十六进制格式
8.4.2. bytea 转义格式

bytea数据类型允许存储二进制字符串;请参见表 8.6

表 8.6. 二进制数据类型

名称存储大小说明
bytea1 或 4 个字节加上实际二进制字符串可变长度二进制字符串

二进制字符串是一系列八位字节(或字节)。二进制字符串与字符字符串有两种区别。首先,二进制字符串专门允许存储值为零和其他“不可打印”的八位字节(通常是十进制范围 32 到 126 之外的八位字节)。字符字符串不允许零八位字节,也不允许根据数据库所选字符集编码无效的任何其他八位字节值和八位字节值序列。其次,对二进制字符串的操作处理实际字节,而对字符字符串的处理取决于区域设置。简而言之,二进制字符串适合存储程序员认为是“原始字节”的数据,而字符字符串适合存储文本。

bytea类型支持两种输入和输出格式:“hex”格式和PostgreSQL的历史“escape”格式。在输入时始终接受这两种格式。输出格式取决于配置参数bytea_output;默认值为 hex。(请注意,hex 格式是在PostgreSQL9.0 中引入的;早期版本和某些工具无法理解它。)

SQL标准定义了一种不同的二进制字符串类型,称为BLOBBINARY LARGE OBJECT。输入格式不同于bytea,但提供的函数和运算符大多相同。

8.4.1.byteaHex 格式#

“hex”格式将二进制数据编码为每字节 2 个十六进制数字,最高有效半字节在前。整个字符串以序列\x开头(以区别于转义格式)。在某些情况下,可能需要通过加倍来转义初始反斜杠(请参见第 4.1.2.1 节)。对于输入,十六进制数字可以是大写或小写,并且数字对之间允许有空格(但数字对内或起始\x序列中不允许有空格)。hex 格式与广泛的外部应用程序和协议兼容,并且比转义格式转换得更快,因此更推荐使用它。

示例

SET bytea_output = 'hex';

SELECT '\xDEADBEEF'::bytea;
   bytea
------------
 \xdeadbeef

8.4.2.bytea转义格式#

“escape”格式是PostgreSQL中bytea类型的传统格式。它采用将二进制字符串表示为 ASCII 字符序列的方法,同时将无法表示为 ASCII 字符的那些字节转换为特殊的转义序列。如果从应用程序的角度来看,将字节表示为字符有意义,那么这种表示方式可能很方便。但在实践中,它通常会令人困惑,因为它模糊了二进制字符串和字符字符串之间的区别,而且所选择的特定转义机制有些笨拙。因此,对于大多数新应用程序,可能应该避免使用此格式。

以转义格式输入bytea值时,某些值的八位字节必须转义,而所有八位字节值可以转义。通常,要转义八位字节,请将其转换为三位八进制值,并在其前面加上反斜杠。反斜杠本身(八进制十进制值 92)也可以用双反斜杠表示。表 8.7显示了必须转义的字符,并在适用时提供了备用转义序列。

表 8.7.bytea字面量转义八位字节

十进制八位字节值说明转义输入表示示例十六进制表示形式
0零八位字节'\000''\000'::bytea\x00
39单引号'''''\047'''''::bytea\x27
92反斜杠'\\''\134''\\'::bytea\x5c
0 到 31 以及 127 到 255不可打印 八位字节'\xxx'(八进制值)'\001'::bytea\x01

转义不可打印八位字节的要求根据区域设置而异。在某些情况下,您可以不转义它们。

必须将单引号加倍的原因(如表 8.7所示)在于,对于 SQL 命令中的任何字符串字面量都是如此。通用字符串字面量解析器使用最外层的单引号,并将任何一对单引号缩减为一个数据字符。bytea输入函数看到的是一个单引号,它将其视为普通数据字符。但是,bytea输入函数将反斜杠视为特殊字符,而表 8.7中显示的其他行为是由该函数实现的。

在某些情况下,与上面显示的内容相比,反斜杠必须加倍,因为通用字符串字面量解析器还将一对反斜杠缩减为一个数据字符;请参见第 4.1.2.1 节

默认情况下,Bytea八位字节以hex格式输出。如果您将bytea_output更改为escape,则“不可打印”八位字节将转换为等效的三位八进制值,并在前面加上一个反斜杠。大多数“可打印”八位字节都通过客户端字符集中的标准表示形式输出,例如:

SET bytea_output = 'escape';

SELECT 'abc \153\154\155 \052\251\124'::bytea;
     bytea
----------------
 abc klm *\251T

十进制值为 92(反斜杠)的八位字节在输出中加倍。详细信息请参见表 8.8

表 8.8.bytea输出转义八位字节

十进制八位字节值说明转义输出表示形式示例输出结果
92反斜杠\\'\134'::bytea\\
0 到 31 以及 127 到 255不可打印 八位字节\xxx(八进制值)'\001'::bytea\001
32 到 126可打印 八位字节客户端字符集表示'\176'::bytea~

根据您使用的PostgreSQL前端,您可能需要在转义和取消转义bytea字符串方面执行其他工作。例如,如果您的界面自动转换换行符和回车符,您可能还需要转义它们。