Символьные типы

Таблица 4. Символьные типы

ИмяОписание
character varying(n), varchar(n)переменная длина с ограничением
character(n), char(n)фиксированная длина, с дополнением
mvarchar(n)переменная длина с ограничением; для совместимости с Microsoft SQL Server
mchar(n)фиксированная длина, с дополнением; для совместимости с Microsoft SQL Server
textпеременная неограниченная длина

В Таблице 4 приведены типы символов общего назначения, доступные в QHB.

SQL определяет два основных типа символов: character varying(n) и character(n), где n — положительное целое число. Оба этих типа могут хранить строки длиной до n символов (не байтов). Попытка сохранить более длинную строку в столбце такого типа приведет к ошибке, если только избыточные символы не являются пробелами — тогда строка будет усечена до максимальной длины. (Это несколько странное исключение продиктовано стандартом SQL.) Если сохраняемая строка короче объявленной длины, значения типа character будут дополнены пробелами; значения типа character varying просто сохранят более короткую строку.

Если явно преобразовывать значение в character varying(n) или character(n), то значение чрезмерной длины будет усечено до n символов, не вызывая ошибку. (Это также продиктовано стандартом SQL.)

Обозначения varchar(n) и char(n) являются псевдонимами для character varying(n) и character(n) соответственно. Запись character без указания длины равнозначна character(1). Если же записать без указания длины character varying, этот тип примет строки любого размера. Последнее является расширением QHB.

В версии QHB 1.2.0 добавлены типы данных mchar и mvarchar, являющиеся аналогами типов char и varchar, но имеющие ряд особенностей поведения, повторяющих поведение типов nchar и nvarchar в Microsoft SQL Server.

Отличия от стандартных типов char и varchar в QHB:

  • сравнение без учета регистра, в том числе, если один из аргументов mchar или mvarchar, а второй нет (для сравнения с учетом регистра вводятся специальные версии операторов сравнения: &<, &<=, &=, &>= и &>).
  • mchar фиксированной длины дополняется пробелами справа, но при сравнениях эти пробелы игнорируются;
  • данные типа mchar или mvarchar хранятся в кодировке utf-16 (для пользователя это не важно);
  • для сравнения и приведения к верхнему/нижнему регистру используется ICU, поэтому результат не зависит от операционной системы;
  • функция получения подстроки substr(str, pos [, length]), а не substring.

Отличия от поведения nchar и nvarchar в Microsoft SQL Server:

  • mchar и mvarchar без указания длины трактуются как строки неопределенной неограниченной длины (похоже на nvarchar(max));
  • mchar неопределенной длины не дополняется пробелами справа (но явно заданные пробелы все-таки хранятся);
  • функция вычисления длины строки length(string), а не len, как в Microsoft SQL Server.

Для типов данных mchar и mvarchar поддерживаются индексы B-деревья и хэш-индексы.

Кроме того, QHB предоставляет тип text, в котором хранятся строки любой длины. Хотя тип text не соответствует стандарту SQL, он есть и в некоторых других СУБД SQL.

Значения типа character физически дополняются пробелами до указанной ширины n символов и сохраняются и отображаются таким образом. Однако конечные пробелы считаются семантически несущественными и не учитываются при сравнении двух значений типа character. В сопоставлениях, где пробелы являются значащими, такое поведение может привести к неожиданным результатам; например, SELECT 'a '::CHAR(2) collate "C" < E'a\n'::CHAR(2) возвращает true, несмотря на то, что в локали C символ пробел считается больше символа новой строки. При преобразовании значения character в какой-либо другой тип конечные пробелы удаляются. Обратите внимание, что конечные пробелы являются семантически значимыми в значениях character varying и text, а также при сопоставлении с шаблоном, т. е. в операторе LIKE и в регулярных выражениях.

Какие конкретно символы можно сохранять в этих типах данных, зависит от набора символов базы данных, выбираемого при ее создании. Независимо от того, какой набор установлен, символ с кодом 0 (иногда называемый NULL) сохранить нельзя. Подробную информацию см. в разделе Поддержка кодировок.

Потребность в памяти для короткой строки (до 126 байт) составляет 1 байт плюс фактическая строка, которая в случае типа character включает заполнение пробелами. Более длинные строки требуют 4 байта служебной информации вместо 1. Длинные строки сжимаются системой автоматически, поэтому физический размер на диске может быть меньше. Очень длинные значения также хранятся в фоновых таблицах, чтобы не мешать быстрому доступу к более коротким значениям столбцов. В любом случае максимально возможный размер сохраняемой строки символов составляет около 1 ГБ. (Максимально допустимое значение n в объявлении типа данных меньше этого числа. Менять это бесполезно, поскольку в многобайтовых кодировках число символов и байтов может быть совершенно разным. Если вы хотите сохранить длинные строки без определенного верхнего предела, то вместо того чтобы задавать произвольный предел длины, используйте text или character varying без указания длины.)

Совет
Между этими типами нет разницы в производительности, за исключением увеличения места для хранения при использовании типа с пробелом и нескольких дополнительных циклов ЦП для проверки длины при сохранении в столбце с ограниченной длиной. Хотя тип character(n) имеет преимущества в производительности в некоторых других СУБД, в QHB такого преимущества нет; на самом деле из-за дополнительных затрат на хранение character(n) обычно самый медленный из всех типов. В большинстве случаев вместо него следует использовать text или character varying.

Информацию о синтаксисе строковых литералов см. в подразделе Строковые константы, а информацию о доступных операторах и функциях — в главе Функции и операторы.

Пример 1. Использование символьных типов

CREATE TABLE test1 (a character(4));
INSERT INTO test1 VALUES ('ok');
SELECT a, char_length(a) FROM test1; -- (1)

  a   | char_length
------+-------------
 ok   |           2


CREATE TABLE test2 (b varchar(5));
INSERT INTO test2 VALUES ('ok');
INSERT INTO test2 VALUES ('good      ');
INSERT INTO test2 VALUES ('too long');
ERROR:  value too long for type character varying(5)
INSERT INTO test2 VALUES ('too long'::varchar(5)); -- явное усечение
SELECT b, char_length(b) FROM test2;

   b   | char_length
-------+-------------
 ok    |           2
 good  |           5
 too l |           5

(1): Функция char_length рассматривается в разделе Строковые функции и операторы.

В QHB есть еще два символьных типа фиксированной длины, показанных в Таблице 5. Тип name существует только для хранения идентификаторов во внутренних системных каталогах и не предназначен для использования обычными пользователями. Его длина в настоящее время определяется как 64 байта (63 используемых символа плюс знак конца строки), но на него следует ссылаться, используя константу NAMEDATALEN в исходном коде C. Длина задается во время компиляции (и, следовательно, настраивается для специальных целей); максимальная длина по умолчанию может измениться в будущем выпуске. Тип "char" (обратите внимание на кавычки) отличается от char(1) тем, что требует только один байт памяти. Он используется внутри системных каталогов как упрощенный тип для перечисления.

Таблица 5. Специальные символьные типы

ИмяРазмерОписание
"char"1 байтоднобайтовый внутренний тип
name64 байтавнутренний тип для имен объектов