Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16 / 17

8.4. 二进制数据类型 #

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

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

表 8.6. 二进制数据类型

名称 存储大小 描述
bytea 1 或 4 个字节外加实际的二进制字符串 可变长度二进制字符串

二进制字符串是由八位字节(或字节)序列组成的。二进制字符串与字符字符串有两种区别。首先,二进制字符串明确允许存储值为零的八位字节和其他 不可打印 八位字节(通常在十进制范围 32-126 之外的八位字节)。字符字符串不允许零八位字节,也不允许根据数据库选择的字符集编码而无效的其他八位字节值和八位字节序列。其次,对二进制字符串进行操作时会处理实际的字节,而处理字符字符串时则取决于区域设置。简而言之,二进制字符串适合存储程序员认为是原始字节的数据,而字符字符串适合存储文本。

bytea 类型支持两种输入和输出格式:十六进制格式和PostgreSQL传统转义格式。输入时总是接受这两种格式。输出格式取决于配置参数bytea_output;默认值是十六进制。(注意,十六进制格式是在 PostgreSQL 9.0 中引入的;早期版本和某些工具无法理解这种格式。)

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

8.4.1. bytea 十六进制格式 #

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

示例

SET bytea_output = 'hex';

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

8.4.2. bytea 转义格式 #

转义 格式是用于 bytea 类型的传统 PostgreSQL 格式。它的做法是将二进制字符串表示为 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字符串方面做一些额外工作。例如,如果你的界面自动转换换行符和回车符,你可能还需要对其进行转义。