跳到主要内容

二进制字符串函数和操作符

bytea 保存原始字节,不是文本;最常见的输入输出形式是十六进制,例如 decode('00ff', 'hex') 得到两个字节。以下示例使用 PostgreSQL。

基本操作​

SELECT encode(decode('00ff', 'hex'), 'hex'); -- 00ff
SELECT octet_length(decode('00ff', 'hex')); -- 2
SELECT encode(decode('aabb', 'hex') || decode('cc', 'hex'), 'hex'); -- aabbcc
SELECT encode(substring(decode('aabbcc', 'hex') from 2 for 1), 'hex'); -- bb

|| 连接字节串,substring 与 overlay 按字节位置操作,位置从 1 开始。get_byte(data, n) 和 set_byte(data, n, value) 的偏移却从 0 开始,字节值范围为 0 到 255;越界会报错。position(bytes in data) 查找字节序列,未找到返回 0。

编码与文本​

encode(bytea, 'hex') 或 'base64' 用于传输展示,decode(text, format) 则还原字节。它们不负责把自然语言文本转换为字符编码:

SELECT encode(convert_to('你好', 'UTF8'), 'hex');
SELECT convert_from(convert_to('你好', 'UTF8'), 'UTF8'); -- 你好

convert_to、convert_from 明确文本编码,错误编码可能导致解码失败;不要把任意二进制当作 UTF-8 文本。

位与校验​

get_bit(data, n)、set_bit(data, n, value) 可以按位读取或修改 bytea,位偏移从 0 开始;使用前先确定协议定义的位序。md5(bytea) 输出十六进制摘要,sha256(bytea) 输出二进制摘要;摘要可用于校验内容,不要用无盐的快速散列函数存储密码。NULL 输入通常传播为 NULL,大对象频繁在 SQL 内复制或拼接也会带来内存和 I/O 成本。