CHAR vs VARCHAR: разница и когда что
Карьерник — квиз-тренажёр в Telegram с 1500+ вопросами для собесов аналитика. SQL, Python, A/B, метрики. Бесплатно.
Зачем знать разницу
На собеседовании для junior-аналитика это популярный вопрос: «чем отличается CHAR от VARCHAR?». Казалось бы, оба — строки. Но ответ показывает, читали ли вы документацию или только копипастили с Stack Overflow.
Для аналитика практически это проявляется так: на собесе спросят, почему сравнение WHERE code = 'AB' не работает (потому что в базе CHAR(5) и лежит 'AB ' с паддингом). В продакшене встречаете таблицы, где поле country_code — CHAR(2). В ETL приходят файлы с фиксированной длиной поля — тут CHAR семантически правильнее.
Плюс есть performance-нюансы: CHAR всегда занимает фиксированное место (быстрее на чтение, больше по памяти), VARCHAR — только используемое (экономнее, но overhead на длину).
В статье:
- Короткий ответ и сравнительная таблица
- CHAR — фиксированная длина с паддингом
- VARCHAR — переменная длина
- Разница в Postgres / MySQL / MSSQL
- Performance
- Когда что выбирать
- TEXT, BLOB, CLOB — другие типы строк
Короткий ответ
- CHAR(n) — фиксированная длина. Всегда n символов. Короткие строки дополняются пробелами справа.
- VARCHAR(n) — переменная длина, максимум n. Только используемое.
- TEXT — без ограничения длины (Postgres / MySQL).
Сравнение
| CHAR(n) | VARCHAR(n) | TEXT | |
|---|---|---|---|
| Длина | фиксированная n | до n | без лимита |
| Padding | пробелы справа | нет | нет |
| Память | n × 4 байта (UTF-8) | длина + 1-4 | длина + 4 |
| Скорость чтения | быстрее (фикс.) | чуть медленнее | аналогично VARCHAR |
| Когда выбирать | коды, хеши фикс. длины | обычный текст | длинный текст |
Пример padding
CREATE TABLE t (c CHAR(5));
INSERT INTO t VALUES ('AB');
SELECT c, LENGTH(c), c = 'AB' FROM t;Результат:
c='AB '(с пробелами!)LENGTH(c)= 5c = 'AB'— в разных СУБД по-разному
Postgres
c = 'AB' возвращает TRUE (Postgres игнорирует trailing spaces при сравнении).
MySQL
Тоже сравнивает без учёта паддинга по умолчанию (зависит от collation).
MSSQL
С ANSI_PADDING OFF — TRUE. С ON — FALSE. По умолчанию зависит от настроек.
Правило: если собираетесь сравнивать CHAR-поле как строку — всегда TRIM() для надёжности.
Примеры использования
CHAR — хорошо
-- коды фиксированной длины
country_code CHAR(2) -- 'RU', 'US', 'KZ'
currency_code CHAR(3) -- 'USD', 'EUR', 'RUB'
-- хеши
md5_hash CHAR(32)
-- фиксированные ID
some_id CHAR(12)VARCHAR — стандарт
-- имена, email
name VARCHAR(100)
email VARCHAR(255)
-- описания / комментарии
description VARCHAR(500)TEXT — длинный текст
-- статьи, отзывы
article_body TEXT
review TEXTПроизводительность
CHAR
Плюсы:
- Фиксированное смещение в row → быстрое чтение
- Нет overhead на длину
Минусы:
- Больше памяти при коротких значениях (паддинг пустотой)
- Trim при выборке может быть нужен
VARCHAR
Плюсы:
- Только используемое место
- Нет паддинга
Минусы:
- Overhead 1-4 байта на длину
- Вариативный размер row → сложнее layout
TEXT в Postgres
TEXT = VARCHAR без ограничения. Внутри то же самое. Нет performance разницы.
В других СУБД может отличаться (MySQL хранит TEXT off-row).
В Postgres
Специфика Postgres:
VARCHAR(n)≈TEXTс check constraint на длину- Нет разницы в производительности между VARCHAR и TEXT
- CHAR считается анахронизмом (padding мешает)
Рекомендация Postgres community: используйте TEXT (или VARCHAR без длины) везде, где нет строгого требования на фиксированную длину.
В MySQL
- CHAR(n) до 255
- VARCHAR(n) до 65 535
- TEXT может храниться off-row (performance impact)
- TINYTEXT, MEDIUMTEXT, LONGTEXT — разные limits
MySQL часто имеет реальную разницу CHAR vs VARCHAR по perf на некоторых workloads.
В MSSQL
- CHAR / VARCHAR — ASCII
- NCHAR / NVARCHAR — Unicode (UTF-16)
- Всегда используйте N-варианты для текста
Когда выбирать CHAR
- Строгая фиксированная длина (коды, хеши)
- Быстрое чтение критично
- Консистентность (уровень DB, не приложения)
Когда выбирать VARCHAR / TEXT
- Переменная длина (90% случаев)
- Экономия памяти на коротких значениях
- Более стандартный подход
На собесе
«Разница CHAR и VARCHAR?» CHAR фиксированная длина с паддингом. VARCHAR — переменная до n.
«Что быстрее?» CHAR теоретически быстрее из-за фикс. offset, но практически разница микроскопичная.
«Когда CHAR?» Когда поле всегда одной длины (country code, hash).
«Postgres: TEXT или VARCHAR?» Одинаково. TEXT проще — без limit.
Частые ошибки
1. CHAR для телефона
Телефоны разной длины (10 цифр vs 11 с + ). VARCHAR.
2. VARCHAR(255) "на всякий случай"
Классика. В большинстве СУБД 255 — не magic number. Подбирайте адекватно.
3. Сравнение CHAR без TRIM
Может работать, может — нет. Зависит от collation / config.
4. TEXT для всего
В MySQL TEXT хранится off-row → slower queries. Используйте VARCHAR если знаете max.
Связанные темы
FAQ
Postgres рекомендует VARCHAR или TEXT?
TEXT. VARCHAR без length то же самое.
CHAR(n) реально быстрее?
Теоретически да, на тысячах операций — возможно. В аналитике неощутимо.
NCHAR vs CHAR?
NCHAR — Unicode (UTF-16). Для международного текста.
Максимум VARCHAR?
Postgres: 1 GB. MySQL: 65 535 байт на row (с учётом всех VARCHAR). MSSQL: 8000 для VARCHAR / VARCHAR(MAX) до 2 GB.
Тренируйте SQL — откройте тренажёр с 1500+ вопросами для собесов.