Собесов

CHAR vs VARCHAR: фиксированная и переменная длина

SQLТипы данныхЛёгкаяJunior

Условие

В чём различие CHAR(n) и VARCHAR(n) в SQL? Что произойдёт, если в CHAR(10) вставить строку длиной 20 символов?

Решение

CHAR(n) VARCHAR(n) TEXT
Длина Фиксированная — всегда n Переменная — до n Переменная — без лимита
Хранение Дополняется пробелами справа По факту По факту
Сравнение С учётом padding Без padding Без padding
Когда выбирать Полезно для констант одинаковой длины (ISO-коды) Имена, описания Тексты, логи, JSON

Что вернёт 'abc'::CHAR(10) в PostgreSQL

Строка 'abc ' — длина 10, хвост пробелы. При выводе обычно RTRIM уже сделан, но при сравнении = пробелы могут неожиданно мешать.

Превышение длины

Если в CHAR(10) или VARCHAR(10) попробовать вставить 20 символов, поведение зависит от СУБД:

СУБД Поведение
PostgreSQL Ошибка value too long (если только не через cast ::char(10) — обрежет)
MySQL (strict mode) Ошибка
MySQL (без strict) Молча обрежет
Oracle Ошибка
SQL Server Ошибка

Всегда задавайте STRICT режим — иначе можно тихо потерять данные.

Зачем тогда CHAR

Аргумент: «фиксированная длина быстрее». На современных СУБД это миф:

  • В PostgreSQL CHAR обычно медленнее VARCHAR/TEXT из-за логики padding.
  • В Oracle есть оптимизация для CHAR в индексах, но небольшая.

На практике в PostgreSQL пишут TEXT для всего и не используют CHAR. В аналитических базах (ClickHouse, Snowflake) есть String без указания длины.

VARCHAR vs TEXT в PostgreSQL

В PostgreSQL VARCHAR(n), VARCHAR без длины и TEXT хранятся одинаково (TOAST). Разница только в проверке длины. Лучше использовать TEXT + check-constraint, если нужна валидация длины — это явнее и легче править.

Подводные камни

  1. Сравнение CHAR со строкой без padding'abc' = 'abc ' может быть TRUE или FALSE в зависимости от СУБД и режима.
  2. Молчаливое обрезание в MySQL без strict mode — данные теряются.
  3. LENGTH('abc'::CHAR(10)) — в PostgreSQL может вернуть 3 (TRIM при выводе) или 10. Проверьте, прежде чем полагаться.
  4. Кодировкаn это символы, а не байты. UTF-8 строка занимает больше байтов в файле.

Эталонный ответ

CHAR(n) — фиксированная длина (паддинг пробелами). VARCHAR(n) — до n символов. При попытке вставить 20 символов в CHAR(10) будет ошибка либо обрезание (зависит от СУБД и режима). В PostgreSQL обычно используют TEXT.

Хочешь увидеть разбор?

Зарегистрируйся бесплатно — откроется развёрнутое решение этой задачи и ещё 4 на выбор.

Зарегистрироваться и увидеть разбор
Уже есть аккаунт? Войти