Условие
В чём различие 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, если нужна валидация длины — это явнее и легче править.
Подводные камни
- Сравнение
CHARсо строкой без padding —'abc' = 'abc 'может бытьTRUEилиFALSEв зависимости от СУБД и режима. - Молчаливое обрезание в MySQL без strict mode — данные теряются.
LENGTH('abc'::CHAR(10))— в PostgreSQL может вернуть 3 (TRIM при выводе) или 10. Проверьте, прежде чем полагаться.- Кодировка —
nэто символы, а не байты. UTF-8 строка занимает больше байтов в файле.
Эталонный ответ
CHAR(n) — фиксированная длина (паддинг пробелами). VARCHAR(n) — до n символов. При попытке вставить 20 символов в CHAR(10) будет ошибка либо обрезание (зависит от СУБД и режима). В PostgreSQL обычно используют TEXT.