В чем разница CHAR и VARCHAR в SQL
Что проверяют
Для тестировщика это вопрос не про устройство хранения, а про баги, которые из этой разницы вырастают: пробелы в конце строки, обрезка, границы длины, кириллица. Следом обычно просят: «Какие проверки вы бы сделали для поля, которое пишется в VARCHAR(50)?»
Как отвечать
Сначала суть:
CHAR(n): фиксированная длина, короткое значение дополняется пробелами доn. Подходит для значений строго одной длины: код страныRU, код валютыUSD;VARCHAR(n): переменная длина доn, хранится фактическое значение плюс служебные байты с длиной.
Дальше покажите, что знаете поведение конкретных СУБД:
- PostgreSQL: хвостовые пробелы в
charпри сравнении не учитываются и отбрасываются при приведении кtext. Выигрыша в скорости уcharнет, документация прямо советуетtextилиvarchar.varcharбез длины хранит строку любой длины, а вставка значения длиннееnдаёт ошибкуvalue too long; - MySQL: у
CHARхвостовые пробелы срезаются при чтении. При превышении длины в строгом режиме (он по умолчанию с 5.7) будет ошибка, без него значение молча обрежется с предупреждением; - Oracle: в
VARCHAR2(10)по умолчанию длина считается в байтах, кириллица в UTF-8 занимает два байта на символ, и влезет только пять букв. В PostgreSQL и MySQLnзадаётся в символах.
Отсюда проверки:
- граничные значения:
n-1,nиn+1символов, причём одинаково на фронте, в API и в базе; - кириллица и эмодзи: в MySQL эмодзи в колонку с кодировкой
utf8(она жеutf8mb3) не запишется, нужнаutf8mb4; - пробелы: значение с пробелом в конце, строка только из пробелов, пустая строка против
NULL.
Где спотыкаются
Повторяют, что CHAR быстрее. Для PostgreSQL это миф, а для тестов важнее другое: фиксированная длина и дополнение пробелами.
Сравнивают в автотесте результат выборки из CHAR(10) точным равенством со строкой без пробелов. В одних СУБД и драйверах тест проходит, в других падает, и выглядит это как нестабильный тест.
Проверяют длину только в интерфейсе. Фронт ограничил поле 100 символами, а в колонке VARCHAR(50): через API длинное значение уходит в базу и там ломается или обрезается.