Короткий ответ
В PostgreSQL VARCHAR(n) и TEXT хранятся одинаково и не имеют разницы в производительности — VARCHAR(n) лишь добавляет ограничение максимальной длины, TEXT не ограничивает длину вовсе, а CHAR(n) дополняет строку пробелами до фиксированной длины n и почти никогда не нужен в современных приложениях.
Как это работает подробнее
Внутри PostgreSQL все три типа используют один и тот же механизм хранения переменной длины (varlena); VARCHAR(n) добавляет проверку длины при вставке/обновлении, CHAR(n) всегда дополняет строку до n символов пробелами справа.
Пример кода
example.sql
CREATE TABLE demo (a CHAR(5), b VARCHAR(5), c TEXT);
INSERT INTO demo VALUES ('ab', 'ab', 'ab');
SELECT a = 'ab', length(a), length(b) FROM demo;
-- a = 'ab' -> false, потому что a хранится как 'ab ' (с паддингом пробелами), length(a) = 5
-- b и c хранят ровно 'ab', length(b) = 2Что использовать на практике
- Практика. Для большинства полей (имена, описания, email) рекомендуется TEXT без ограничения длины на уровне БД, валидацию делать на уровне приложения/ORM; VARCHAR(n) оправдан, когда ограничение длины — реальное бизнес-правило.
Подводные камни
- Ошибка. Выбирают CHAR(n) по привычке из других СУБД, не замечая паддинг пробелами, что ломает сравнение строк; жёстко ограничивают VARCHAR(255) «по умолчанию» без анализа требований.