Символьные типы
Таблица 4. Символьные типы
| Имя | Описание |
|---|---|
| character varying(n), varchar(n) | переменная длина с ограничением |
| character(n), char(n), bpchar(n) | фиксированная длина, дополненная пробелами |
| bpchar | переменная неограниченная длина, с усеченными пробелами |
| mvarchar(n) | переменная длина с ограничением; для совместимости с Microsoft SQL Server |
| mchar(n) | фиксированная длина, дополненная пробелами; для совместимости с Microsoft SQL Server |
| text | переменная неограниченная длина |
В Таблице 4 приведены типы символов общего назначения, доступные в QHB.
SQL определяет два основных типа символов: character varying(n) и character(n), где n — положительное целое число. Оба этих типа могут хранить строки длиной до n символов (не байтов). Попытка сохранить более длинную строку в столбце такого типа приведет к ошибке, если только избыточные символы не являются пробелами — тогда строка будет усечена до максимальной длины. (Это несколько странное исключение продиктовано стандартом SQL.) Однако если явно преобразовывать значение в character varying(n) или character(n), то значение чрезмерной длины будет усечено до n символов, не вызывая ошибку. (Это тоже продиктовано стандартом SQL.) Если сохраняемая строка короче объявленной длины, значения типа character будут дополнены пробелами; значения типа character varying просто сохранят более короткую строку.
Кроме того, QHB предоставляет тип text, в котором хранятся строки любой длины. Хотя тип text не соответствует стандарту SQL, он есть и в некоторых других СУБД SQL. text является собственным строковым типом данных QHB в том аспекте, что большинство встроенных функций, работающих со строками, объявляются принимающими или возвращающими text, а не character varying. Во многих случаях character varying действует так, как если бы это был домен поверх типа text.
Имя типа varchar является псевдонимом для character varying, тогда как bpchar (с указанием длины) и char — для character. Псевдонимы varchar и char определены в стандарте SQL; bpchar является расширением QHB.
Если длина n задана, она должна быть больше нуля и не может превышать 10 485 760. Если character varying (или varchar) используется без указания длины, этот тип принимает принимает строки любой длины. Если у bpchar отсутствует указатель длины, он тоже принимает строки любой длины, но завершающие пробелы не являются семантически значимыми. Если у character (или char) отсутствует такой указатель, это равнозначно character(1).
Значения типа character физически дополняются пробелами до указанной ширины
n символов и сохраняются и отображаются таким образом. Однако конечные пробелы
считаются семантически несущественными и не учитываются при сравнении двух
значений типа character. В сопоставлениях, где пробелы являются значащими,
такое поведение может привести к неожиданным результатам; например, SELECT 'a '::CHAR(2) collate "C" < E'a\n'::CHAR(2) возвращает true, несмотря на то, что в
локали C символ пробел считается больше символа перевода строки. При преобразовании
значения character в какой-либо другой тип конечные пробелы удаляются. Обратите
внимание, что конечные пробелы являются семантически значимыми в значениях
character varying и text, а также при сопоставлении с шаблоном, т. е. в
предложении LIKE и в регулярных выражениях.
В версии 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-деревья и хеш-индексы.
Какие конкретно символы можно сохранять в этих типах данных, зависит от набора символов базы данных, выбираемого при ее создании. Независимо от того, какой набор установлен, символ с кодом ноль (иногда называемый NUL) сохранить нельзя. Подробную информацию см. в разделе Поддержка кодировок.
Потребность в памяти для короткой строки (до 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) тем, что использует всего один байт памяти и поэтому способен хранить только один символ ASCII. Он применяется внутри системных каталогов как упрощенный тип для перечисления.
Таблица 5. Специальные символьные типы
| Имя | Размер | Описание |
|---|---|---|
| "char" | 1 байт | однобайтовый внутренний тип |
| name | 64 байта | внутренний тип для имен объектов |