3.4. 二进制串 #
bytea 数据类型允许存储二进制串。
表 3.6. 二进制串类型
| 类型名 | 存储尺寸 | 描述 |
|---|---|---|
bytea | 4字节外加实际的二进制串 | 变长(无特定限制)的二进制串 |
二进制串是不关联任何字符集或排序规则的八位组序列。Bytea
明确允许存储值为零的字节和其他“不可打印”字节。
某些值的字节必须转义(但所有字节值都可以转义)在 SQL 语句中用作字符串字面量的一部分时。一般而言,转义一个字节时,把它转换为等于其十进制字节值的三位八进制数,并在前面加两个反斜杠。某些字节值有替代的转义序列,如表 3.7所示。
表 3.7. SQL 字面量转义字节
| 十进制字节值 | 描述 | 输入转义表示 | 示例 | 打印结果 |
|---|---|---|---|---|
0 | 零字节 | '\\000' | select '\\000'::bytea; | \000 |
39 | 单引号 | '\\'' or '\\047' | select '\''::bytea; | ' |
92 | 反斜线 | '\\\\' or '\\134' | select '\\\\'::bytea; | \\ |
注意,上面每个示例的结果都恰好是一个字节长,尽管零字节和反斜杠的输出表示多于一个字符。Bytea
的输出字节也会被转义。一般而言,每个“不可打印”字节的十进制值都会被转换为等值的三位八进制数,并在前面加一个反斜杠。大多数“可打印”字节以其在客户端字符集中的标准表示出现。十进制值为
92(反斜杠)的字节有一个特殊的替代输出表示。细节见表 3.8。
表 3.8. SQL 输出转义字节
| 十进制字节值 | 描述 | 输出转义表示 | 示例 | 打印结果 |
|---|---|---|---|---|
92 | 反斜线 | \\ | select '\\134'::bytea; | \\ |
0 to 31 and 127 to 255 | “不可打印”字节 | \### (octal value) | select '\\001'::bytea; | \001 |
32 to 126 | “可打印”字节 | ASCII 表示 | select '\\176'::bytea; | ~ |
SQL
字符串字面量(输入串)必须以两个反斜杠为前导,因为它们在
PostgreSQL 后端中必须经过两个解析器。第一个反斜杠会被字符串字面量解析器解释为转义字符并因此被消耗,留下其后的字节。剩下的反斜杠被
bytea
输入函数识别为三位八进制值的前缀。例如,以
'\\001' 形式传给后端的字符串字面量,经过字符串字面量解析器之后变成
'\001'。然后
'\001' 被送到
bytea 输入函数,在那里它被转换为十进制值为
1 的单个字节。
由于类似的原因,反斜杠必须输入为
'\\\\'(或
'\\134')。第一和第三个反斜杠会被字符串字面量解析器解释为转义字符并因此被消耗,留给
bytea
输入函数的字符串中有两个反斜杠,而该函数把它们解释为表示单个反斜杠。例如,以
'\\\\' 形式传给后端的字符串字面量,经过字符串字面量解析器之后变成
'\\'。然后
'\\' 被送到
bytea 输入函数,在那里它被转换为十进制值为
92 的单个字节。
单引号稍有不同:它必须输入为
'\''(或
'\\134'),而不是
'\\''。这是因为,虽然字面量解析器把单引号当作特殊字符处理并会消耗那个反斜杠,但
bytea
输入函数不把单引号识别为特殊字节。因此,以
'\'' 形式传给后端的字符串字面量,经过字符串字面量解析器之后变成
'''。然后
''' 被送到
bytea 输入函数,在那里它保持其十进制值为
39 的单个字节不变。
根据你所用的
PostgreSQL
前端不同,在对
bytea
字符串进行转义和反转义方面可能还有额外的工作要做。例如,如果你的接口会自动翻译换行符和回车符,你可能还必须对它们转义。如果你所用语言的解析器也把反斜杠当作转义字符,你可能不得不把反斜杠再翻倍。
Bytea
提供了 SQL99 第 4.3
节二进制串类型的大部分功能。SQL99
二进制串与 PostgreSQL
bytea 的对比见表 3.9。
表 3.9. SQL99 二进制串与 PostgreSQL
BYTEA 类型的对比
| SQL99 | BYTEA |
|---|---|
数据类型名为 BINARY LARGE OBJECT
或 BLOB | 数据类型名为 BYTEA |
| 不关联任何字符集或排序规则的八位组序列。 | 相同 |
| 由包含数据类型名和最大字节长度的二进制数据类型描述符描述 | 由包含数据类型名但不指定最大长度的二进制数据类型描述符描述 |
| 所有二进制串都可按照比较谓词的规则相互比较。 | 相同 |
| 二进制串的值只能比较相等。 | 二进制串的值可以比较相等、大于、大于等于、小于、小于等于 |
| 对二进制串进行操作并返回二进制串的运算符包括连接、子串、覆盖和修剪 | 对二进制串进行操作并返回二进制串的运算符包括连接、子串和修剪。修剪的
leading 和 trailing
参数尚未实现。
|
| 涉及二进制串的其他运算符包括长度、位置和 like 谓词 | 相同 |
二进制串字面量由偶数个十六进制数字组成,用单引号括起,前带“X”,例如
X'1a43fe' | 二进制串字面量由按表 3.7所示规则转义的字节组成 |