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

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

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

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

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

Тип bytea поддерживает два внешних формата ввода и вывода: традиционный для Postgres Pro формат «спецпоследовательностей» и «шестнадцатеричный». Входные данные принимаются в обоих форматах, а формат выходных данных зависит от параметра конфигурации 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

Формат «спецпоследовательностей» традиционно использовался в Postgres Pro для значений типа 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, объясняется тем, что строковая константа должна пройти два этапа разбора на сервере Postgres Pro. Первая обратная косая черта из каждой пары воспринимается анализатором строки как спецсимвол (если используется синтаксис спецпоследовательностей) и таким образом пропускается, оставляя только вторую косую черту. (Для избавления от этой вложенности можно использовать строки в долларах.) Оставшаяся обратная косая черта затем распознаётся функцией ввода 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;~

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