8.4. Двоичные типы данных
Для хранения двоичных данных предназначен тип bytea
; см. Таблицу 8.6.
Таблица 8.6. Двоичные типы данных
Имя | Размер | Описание |
---|---|---|
bytea | 1 или 4 байта плюс сама двоичная строка | двоичная строка переменной длины |
Двоичные строки представляют собой последовательность октетов (байт) и имеют два отличия от текстовых строк. Во-первых, в двоичных строках можно хранить байты с кодом 0 и другими «непечатаемыми» значениями (обычно это значения вне десятичного диапазона 32..126). В текстовых строках нельзя сохранять нулевые байты, а также значения и последовательности значений, не соответствующие выбранной кодировке базы данных. Во-вторых, в операциях с двоичными строками обрабатываются байты в чистом виде, тогда как текстовые строки обрабатываются в зависимости от языковых стандартов. То есть, двоичные строки больше подходят для данных, которые программист видит как «просто байты», а символьные строки — для хранения текста.
Тип bytea
поддерживает два формата ввода и вывода: «шестнадцатеричный» и традиционный для PostgreSQL формат «спецпоследовательностей». Входные данные принимаются в обоих форматах, а формат выходных данных зависит от параметра конфигурации bytea_output; по умолчанию выбран шестнадцатеричный. (Заметьте, что шестнадцатеричный формат был введён в PostgreSQL 9.0; в ранних версиях и некоторых программах он не будет работать.)
Стандарт SQL определяет другой тип двоичных данных, BLOB
(BINARY LARGE OBJECT
, большой двоичный объект). Его входной формат отличается от форматов bytea
, но функции и операторы в основном те же.
8.4.1. Шестнадцатеричный формат bytea
В «шестнадцатеричном» формате двоичные данные кодируются двумя шестнадцатеричными цифрами на байт, при этом первая цифра соответствует старшим 4 битам. К полученной строке добавляется префикс \x
(чтобы она отличалась от формата спецпоследовательности). В некоторых контекстах обратную косую черту нужно экранировать, продублировав её (см. Подраздел 4.1.2.1). Вводимые шестнадцатеричные цифры могут быть в любом регистре, а между парами цифр допускаются пробельные символы (но не внутри пары и не в начале последовательности \x
). Этот формат совместим со множеством внешних приложений и протоколов, к тому же обычно преобразуется быстрее, поэтому предпочтительнее использовать его.
Пример:
SET bytea_output = 'hex'; SELECT '\xDEADBEEF'::bytea; bytea ------------ \xdeadbeef
8.4.2. Формат спецпоследовательностей bytea
Формат «спецпоследовательностей» традиционно использовался в PostgreSQL для значений типа bytea
. В нём двоичная строка представляется в виде последовательности 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 | «непечатаемые» байты | E'\\ (восьмеричное значение) | '\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 | «непечатаемые» байты | \ (значение байта) | '\001'::bytea | \001 |
от 32 до 126 | «печатаемые» байты | представление из клиентского набора символов | '\176'::bytea | ~ |
В зависимости от применяемой клиентской библиотеки PostgreSQL, для преобразования значений bytea
в спецстроки и обратно могут потребоваться дополнительные действия. Например, если приложение сохраняет в строках символы перевода строк, возможно их также нужно будет представить спецпоследовательностями.