8.4. Двоичные типы данных

Для хранения двоичных данных предназначен тип bytea; см. Табл. 8-6.

Таблица 8-6. Двоичные типы данных

ИмяРазмерОписание
bytea1 или 4 байта плюс сама двоичная строкадвоичная строка переменной длины

Двоичные строки представляют собой последовательность октетов (байт) и имеют два отличия от текстовых строк. Во-первых, в двоичных строках можно хранить байты с кодом 0 и другими "непечатаемыми" значениями (обычно это значения вне диапазона 32..126). В текстовых строках нельзя сохранять нулевые байты, а также значения и последовательности значений, не соответствующие выбранной кодировке базы данных. Во-вторых, в операциях с двоичными строками обрабатываются байты в чистом виде, тогда как текстовые строки обрабатываются в зависимости от языковых стандартов. То есть, двоичные строки больше подходят для данных, которые программист видит как "просто байты", а символьные строки — для хранения текста.

Тип bytea поддерживает два внешних формата ввода и вывода: традиционный для PostgreSQL формат "спецпоследовательностей" и "шестнадцатеричный". Входные данные принимаются в обоих форматах, а формат выходных данных зависит от параметра конфигурации bytea_output; по умолчанию выбран шестнадцатеричный. (Заметьте, что шестнадцатеричный формат был введён в PostgreSQL 9.0; в ранних версиях и некоторых программах он не будет работать.)

Стандарт SQL определяет другой тип двоичных данных, BLOB (BINARY LARGE OBJECT, большой двоичный объект). Его входной формат отличается от форматов bytea, но функции и операторы в основном те же.

8.4.1. Шестнадцатеричный формат bytea

В "шестнадцатеричном" формате двоичные данные кодируются двумя шестнадцатеричными цифрами на байт, при этом первая цифра соответствует старшим 4 битам. К полученной строке добавляется префикс \x (чтобы она отличалась от формата спецпоследовательности). В некоторых контекстах обратную косую черту нужно выделить, продублировав её, в тех же случаях это нужно сделать для формата спецпоследовательности; подробнее это описано ниже. Шестнадцатеричные цифры могут быть в любом регистре, а между парами цифр допускаются пробельные символы (но не внутри пары и не в начале последовательности \x). Этот формат совместим со множеством внешних приложений и протоколов, к тому же обычно преобразуется быстрее, поэтому предпочтительнее использовать его.

Пример:

SELECT E'\\xDEADBEEF';

8.4.2. Формат спецпоследовательностей bytea

Формат "спецпоследовательностей" традиционно использовался в PostgreSQL для значений типа bytea. В нём двоичная строка представляется в виде последовательности ASCII-символов, а байты, непредставимые в виде ASCII-символов, передаются в виде спецпоследовательностей. Этот формат может быть удобен, если с точки зрения приложения представление байт в виде символов имеет смысл. Но на практике это обычно создаёт путаницу, так как двоичные и символьные строки могут выглядеть одинаково, а кроме того выбранный механизм спецпоследовательностей довольно неуклюж. Поэтому в новых приложениях этот формат обычно не стоит использовать.

Передавая значения bytea в формате спецпоследовательности, байты с определёнными значениями необходимо записывать специальным образом, хотя так можно записывать и все значения. В общем виде для этого значение байта нужно преобразовать в трёхзначное восьмеричное число и добавить перед ним обратную косую черту (и продублировать её, если значение записывается в текстовой спецстроке). Саму обратную косую черту (символ с кодом 92) можно записать в виде двух таких символов. В Табл. 8-7 перечислены символы, которые нужно записывать спецпоследовательностями, и приведены альтернативные варианты записи там, где они возможны.

Таблица 8-7. Спецпоследовательности записи значений bytea

Десятичное значение байтаОписаниеСпецпоследова- тельность вводаПримерВыводимое представление
0нулевой байтE'\\000'SELECT E'\\000'::bytea;\000
39апостроф'''' или E'\\047'SELECT E'\''::bytea;'
92обратная косая чертаE'\\\\' или E'\\134'SELECT E'\\\\'::bytea;\\
от 0 до 31 и от 127 до 255"непечатаемые" байтыE'\\xxx' (значение байта)SELECT E'\\001'::bytea;\001

Набор непечатаемых символов, которые нужно записывать спецпоследовательностями, определяется языковыми стандартами. В некоторых случаях можно оставить в буквальном виде и другие символы. Заметьте, что во всех примерах в Табл. 8-7 задаётся значение ровно одного байта, хотя выходное представление может состоять из нескольких символов.

Необходимость дублирования обратных косых черт в записи спецпоследовательностей, показанного в Табл. 8-7, объясняется тем, что строковая константа должна пройти два этапа разбора на сервере PostgreSQL. Первая обратная косая черта из каждой пары воспринимается анализатором строки как спецсимвол (если используется синтаксис спецпоследовательностей) и таким образом пропускается, оставляя только вторую косую черту. (Для избавления от этой вложенности можно использовать строки в долларах.) Оставшаяся обратная косая черта затем распознаётся функцией ввода bytea как спецсимвол, предваряющий трёхзначное восьмеричное значение или следующий спецсимвол. Например, переданная серверу строковая константа E'\\001' преобразуется в \001, проходя через анализатор спецстрок. Затем строка \001 передаётся функции ввода типа bytea, где она преобразуется в один байт с десятичным значением 1. Заметьте, что символ апостроф для функции ввода bytea не отличается от остальных, поэтому он записывается как обычно принято в строках. (См. также Разд. 4.1.2.1.)

Данные bytea иногда выводятся также в спецпоследовательностях. При этом каждый "непечатаемый" байт представляется в виде трёхзначного восьмеричного значения после обратной косой черты. Большинство "печатаемых" байт представляются обычными символами из клиентского набора символов. Байт с десятичным кодом 92 (обратная косая черта) при выводе дублируется. Это иллюстрирует Табл. 8-8.

Таблица 8-8. Спецпоследовательности выходных значений bytea

Десятичное значение байтаОписаниеСпецпоследовательность выводаПримерВыводимый результат
92обратная косая черта\\SELECT E'\\134'::bytea;\\
от 0 до 31 и от 127 до 255"непечатаемые" байты\xxx (значение байта)SELECT E'\\001'::bytea;\001
от 32 до 126"печатаемые" байтыпредставление из клиентского набора символовSELECT E'\\176'::bytea;~

В зависимости от применяемой клиентской библиотеки PostgreSQL, для преобразования значений bytea в спецстроки и обратно могут потребоваться дополнительные действия. Например, если приложение сохраняет в строках символы перевода строк, возможно их также нужно будет представить спецпоследовательностями.