Блог СУБД SoQoL

Классика не устаревает или кто-то просто отличился?

Мы помним, что «по классике» CHAR — строковый тип фиксированной длины и если хранимые величины менее фиксированной длины типа, то они дополняются пробелами.

VARCHAR — строковый тип переменной длины, в котором хранимые величины не дополняются пробелами.

Эти два типа данных реализованы во всех популярных СУБД. В SoQoL они также реализованы, но в текущей версии CHAR пока представлен как синоним VARCHAR.

А как эти типы реализованы в других СУБД?

Посмотрим подробнее, как проявляется разная реализация типов CHAR / VARCHAR при работе с:
- функцией concat;
- операцией конкатенации «||».

Для начала рассмотрим самый распространённый случай, когда имя и фамилию нужно объединить в одну строку:

create table WORKS (NAME varchar (15), SURNAME varchar (25));
insert into WORKS values ('Иванова', 'Мария');

1. С функцией это будет выглядеть так:
select concat (NAME, concat (' ', SURNAME)) as FULLNAME from WORKS;

2. При операции конкатенации:
select NAME || ' ' || SURNAME as FULLNAME from WORKS;

В обоих случаях получаем в результате строку 'Иванова Мария'
И так работает во многих известных СУБД.

Но этот простой и наглядный пример мы рассмотрели в случае, если объединяются значения типа VARCHAR. А теперь посмотрим пример с его собратом – типом CHAR, и тут история будет интереснее.

Возьмём для примера похожую таблицу, но заменим в ней VARCHAR на CHAR и посмотрим поведение в разных СУБД:

create table TEST (SAY1 char (15), SAY2 char (25));
insert into TEST values ('ФА', 'СОЛЬ');

1. select concat (SAY1, SAY2) from TEST;

Результаты:
- SoQoL: 'ФАСОЛЬ'
- Oracle: 'ФА СОЛЬ '
- PostgreSQL 15: 'ФА СОЛЬ '
- MySQL 8.0: 'ФАСОЛЬ'

2. select SAY1 || SAY2 from TEST;

Результаты:
- SoQoL: 'ФАСОЛЬ'
- Oracle: 'ФА СОЛЬ '
- PostgreSQL 15: 'ФАСОЛЬ'

Функция CONCAT эквивалентна операции конкатенации, но результат мы видим – разный. В чём «соль»?

Если рассуждать логически...

Значения типа CHAR дополняются пробелами до его зафиксированного размера. И их (пробелы) необходимо учитывать при работе со значениями типа CHAR. Такую позицию и показывает Oracle в обоих случаях.

Но куда mysql дел дополненные пробелы типа CHAR? Или в mysql CHAR = VARCHAR?
И почему Postgres показывает разное поведение при объедении значений CHAR с помощью функции CONCAT и операции конкатенации?

SoQoL показывает одинаковое поведение и в последующем мы хотели тип CHAR доработать до его «классического» представления. Но теперь призадумались – а нужно ли? Кто-то пользуется ещё типом CHAR или из этих двух братьев достаточно только VARCHAR?

Что скажете, опытные пользователи СУБД?

Обсудить в телеграм!