Комментарии 13
Даже если это никак не отражается на хранении, то для оптимизатора эта информация важна - для оценки ресурсов необходимых для выполнения запроса.
"Да, иногда это полезно, но иногда это лишь случайный забор посреди дороги." - догадаемся кто писал это.
для оптимизатора эта информация важна
Да, только вот это уже другой тезис. Статья не говорит, что ограничения бесполезны. Прежде всего речь о хранении данных
Если же говорить про оптимизатор, то он берет реальные оценки ширины из статистики по фактическим данным, а не из N.
В pg_stats для этого есть avg_width.
То есть если в varchar(1000) лежат строки по 20 байт, планировщик после ANALYZE будет видеть примерно эти 20 байт, а не паниковать из-за огромного N, это было бы довольно тупо со стороны СУБД.
В mssql - да. В pg это так и не осилили.
В PostgreSQL оптимизатор не использует объявленную максимальную длину строки, опираясь в этом вопросе на статистику.
Жесть, LLM-стиль сквозит из каждого третьего предложения. Ну, ещё объяснения как для тупых: не влияет. Смотри, проверим, что не влияет. Вот видишь, не влияет. Формула: не влияет. Так что не влияет.
В SQL server nvarchar(n) в символах
Разница в поведении между varchar(N) и text давно уже расписана: https://ru-postgres.livejournal.com/65930.html
Для MySQL, немного сложнее: да, varchar не резервирует место для хранения данных, но есть лимит на общую длину строки в БД (т.е. всех колонок вместе, не созраненной строки в одной ячейке). Что-то около ~64K bytes. вот тут уже учитывается сколько у вас "больших" varchar колонок - при добавлении очередной varchar(255) база скажет row size limit exceed (даже на пустой таблице, без данных)
Да, отличный нюанс, спасибо.
Еще один хороший пример того, почему казалось бы схожую функциональность не стоит воспринимать одинаково в разных СУБД.
вот тут уже учитывается сколько у вас "больших" varchar колонок
Угу. А заодно - какой у них CHARSET (ведь нужно указанный макс. размер, который в символах, пересчитать в макс. размер хранения, который в байтах).
А ещё в MySQL, в отличие от PostgreSQL, нельзя указать просто VARCHAR, без указания максимального размера помещаемых данных.
база скажет row size limit exceed (даже на пустой таблице, без данных)
Именно поэтому использование xTEXT(size) или xTEXT+CHECK(size) в MySQL предпочтительнее VARCHAR(size) - и оно работает ровно так, как описано в статье.
Разница между VARCHAR и TEXT начинается с того, что исторически это разные oid в pg_type, что порой приводит к странным последствиям. Особенно в некоторых расширениях.
Поэтому, рекомендую вместо
some_string textписать просто
some_string varcharбез скобок и максимальной длины.

VARCHAR(N) в PostgreSQL: ограничение, а не экономия памяти