Рекомендации по длине столбца SQL varchar

Каждый раз, когда вы настраиваете новую таблицу SQL или добавляете новый столбец varchar в существующую таблицу, мне интересно, что самое лучшее для length.

Итак, скажем, у вас есть столбец с именем name типа varchar. Итак, вы должны выбрать длину. Я не могу придумать имя > 20 символов, но вы никогда не узнаете. Но вместо того, чтобы использовать 20, я всегда округляю до следующего числа 2 ^ n. В этом случае я бы выбрал 32 как длину. Я делаю это, потому что с точки зрения компьютерного ученого число 2 ^ n выглядит больше even для меня, чем другие числа, и я просто предполагаю, что архитектура под ними может обрабатывать эти числа немного лучше других.

С другой стороны, сервер MSSQL, например, устанавливает значение длины по умолчанию равным 50, когда вы решите создать столбец varchar. Это заставляет меня думать об этом. Почему 50? это просто случайное число или на основе средней длины столбца или что?

Он также может быть - или, возможно, - что разные реализации SQL-серверов (например, MySQL, MSSQL, Postgres,...) имеют разные наилучшие значения длины столбца.

Ответ 1

Никаких СУБД, которые я знаю, не имеет никакой "оптимизации", которая сделает длину VARCHAR с длиной 2^n более эффективной, чем одна с длиной max, которая не является степенью 2.

Я думаю, что ранние версии SQL Server фактически обрабатывали VARCHAR длиной 255 по сравнению с версией с максимальной максимальной длиной. Я не знаю, все ли так.

Для почти всех СУБД фактическое требуемое хранилище определяется только количеством символов, которые вы вставляете в него, а не длиной max, которую вы определяете. Таким образом, с точки зрения хранения (и, скорее всего, и производительности), не имеет значения, объявляете ли вы столбец как VARCHAR(100) или VARCHAR(500).

Вы должны видеть длину max для столбца VARCHAR как своего рода ограничение (или бизнес-правило), а не техническую/физическую вещь.

Для PostgreSQL лучшей настройкой является использование text без ограничения длины и CHECK CONSTRAINT, который ограничивает количество символов в соответствии с тем, что требуется вашему бизнесу.

Если это требование изменится, изменение ограничения проверки выполняется намного быстрее, чем изменение таблицы (поскольку таблицу не нужно переписывать)

То же самое может быть применено для Oracle и других - в Oracle это будет VARCHAR(4000) вместо text.

Я не знаю, существует ли разница в физической памяти между VARCHAR(max) и, например, VARCHAR(500) в SQL Server. Но, по-видимому, есть влияние производительности при использовании VARCHAR(max) по сравнению с varchar(8000).

Смотрите эту ссылку (опубликовано Erwin Brandstetter в качестве комментария)

Редактировать 2013-09-22

Относительно комментария Bigown:

В версиях Postgres до 9.2 (которые не были доступны при написании исходного ответа) изменение в определении столбца переписало всю таблицу, см., например, здесь. С 9.2 это уже не так, и быстрый тест подтвердил, что увеличение размера столбца для таблицы с 1,2 миллионами строк действительно занимает всего 0,5 секунды.

Для Oracle это, похоже, также верно, судя по тому, как требуется изменить столбец большой таблицы VARCHAR. Но я не мог найти для этого никаких ссылок.

Для MySQL в руководстве сказано "В большинстве случаев ALTER TABLE создает временную копию исходной таблицы". И мои собственные тесты подтверждают, что: запуск ALTER TABLE в таблице с 1,2 миллионами строк (так же, как в моем тесте с Postgres), чтобы увеличить размер столбца, занял 1,5 минуты. Однако в MySQL вы не можете использовать "обходной путь" для использования ограничения проверки для ограничения количества символов в столбце.

Для SQL Server я не мог найти четкую инструкцию по этому поводу, но время выполнения для увеличения размера столбца VARCHAR (опять же таблица из 1,2 миллиона строк выше) указывает, что нет переписать имеет место.

Изменить 2017-01-24

Кажется, я был (по крайней мере частично) неправильным в отношении SQL Server. См. этот ответ от Aaron Bertrand, который показывает, что заявленная длина столбцов nvarchar или VARCHAR имеет огромное значение для производительности.

Ответ 2

VARCHAR(255) и VARCHAR(2) занимают ровно столько же места на диске! Поэтому единственная причина ограничить это, если у вас есть конкретная потребность в ее уменьшении. В противном случае сделайте все 255.

В частности, при сортировке более крупный столбец занимает больше места, поэтому, если это ущемляет производительность, вам нужно беспокоиться об этом и сделать их меньше. Но если вы только когда-либо выбираете 1 строку из этой таблицы, вы можете просто сделать их всего 255, и это не имеет значения.

Смотрите: Каковы оптимальные размеры varchar для MySQL?

Ответ 3

Всякий раз, когда я настраиваю новую таблицу SQL, я чувствую то же самое, когда 2 ^ n более "четный"... но, суммируя ответы здесь, нет существенного влияния на пространство хранения, если просто определить varchar (2 ^ n) или даже varchar (Макс).

Тем не менее, вы все равно должны предвидеть потенциальные последствия для хранилища и производительности при установке высокого предела varchar(). Например, допустим, вы создали столбец varchar (MAX) для хранения описаний продуктов с полнотекстовой индексацией. Если длина 99% описаний составляет всего 500 символов, а затем вдруг появляется кто-то, кто заменяет упомянутые описания статьями в Википедии, вы можете заметить непредвиденные значительные потери памяти и производительности.

Еще одна вещь от Билла Карвина:

Существует одно возможное влияние на производительность: в MySQL временные таблицы и таблицы MEMORY хранят столбец VARCHAR в виде столбца фиксированной длины, дополненного его максимальной длиной. Если вы разрабатываете столбцы VARCHAR, размер которых значительно превышает необходимый вам размер, вы будете использовать больше памяти, чем нужно. Это влияет на эффективность кэша, скорость сортировки и т.д.

В основном, просто придумайте разумные бизнес-ограничения и ошибки немного большего размера. Как отметил @onedaywhen, фамилии в Великобритании обычно составляют от 1 до 35 символов. Если вы решите сделать его varchar (64), вы на самом деле не будете причинять вреда... если только вы не храните фамилию этого парня, длина которой, как говорят, составляет до 666 символов. В этом случае, возможно, varchar (1028) имеет больше смысла.

И в случае, если это полезно, вот как может выглядеть varchar 2 ^ 5 - 2 ^ 10, если заполнено:

varchar(32)     Lorem ipsum dolor sit amet amet.

varchar(64)     Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie

varchar(128)    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas

varchar(256)    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas
                velit metus, sit amet tristique purus condimentum eleifend. Quis
                que mollis magna vel massa malesuada bibendum. Proinde tincidunt

varchar(512)    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas
                velit metus, sit amet tristique purus condimentum eleifend. Quis
                que mollis magna vel massa malesuada bibendum. Proinde tincidunt
                dolor tellus, sit amet porta neque varius vitae. Seduse molestie
                lacus id lacinia tempus. Vestibulum accumsan facilisis lorem, et
                mollis diam pretium gravida. In facilisis vitae tortor id vulput
                ate. Proin ornare arcu in sollicitudin pharetra. Crasti molestie

varchar(1024)   Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donecie
                vestibulum massa. Nullam dignissim elementum molestie. Vehiculas
                velit metus, sit amet tristique purus condimentum eleifend. Quis
                que mollis magna vel massa malesuada bibendum. Proinde tincidunt
                dolor tellus, sit amet porta neque varius vitae. Seduse molestie
                lacus id lacinia tempus. Vestibulum accumsan facilisis lorem, et
                mollis diam pretium gravida. In facilisis vitae tortor id vulput
                ate. Proin ornare arcu in sollicitudin pharetra. Crasti molestie
                dapibus leo lobortis eleifend. Vivamus vitae diam turpis. Vivamu
                nec tristique magna, vel tincidunt diam. Maecenas elementum semi
                quam. In ut est porttitor, sagittis nulla id, fermentum turpist.
                Curabitur pretium nibh a imperdiet cursus. Sed at vulputate este
                proin fermentum pretium justo, ac malesuada eros et Pellentesque
                vulputate hendrerit molestie. Aenean imperdiet a enim at finibus
                fusce ut ullamcorper risus, a cursus massa. Nunc non dapibus vel
                Lorem ipsum dolor sit amet, consectetur Praesent ut ultrices sit

Ответ 4

Наилучшее значение - это значение, которое подходит для данных, определенных в базовом домене.

Для некоторых доменов VARCHAR(10) подходит для атрибута Name, для других доменов VARCHAR(255) может быть лучшим выбором.

Ответ 5

Добавляя к ответу a_horse_with_no_name, вы можете найти следующее из интересов...

не имеет значения, объявляете ли вы столбец как VARCHAR (100) или VACHAR (500).

-- try to create a table with max varchar length
drop table if exists foo;
create table foo(name varchar(65535) not null)engine=innodb;

MySQL Database Error: Row size too large.

-- try to create a table with max varchar length - 2 bytes for the length
drop table if exists foo;
create table foo(name varchar(65533) not null)engine=innodb;

Executed Successfully

-- try to create a table with max varchar length with nullable field
drop table if exists foo;
create table foo(name varchar(65533))engine=innodb;

MySQL Database Error: Row size too large.

-- try to create a table with max varchar length with nullable field
drop table if exists foo;
create table foo(name varchar(65532))engine=innodb;

Executed Successfully

Не забывайте байты длины и нулевой байт, поэтому:

name varchar(100) not null будет 1 байт (длина) + до 100 символов (latin1)

name varchar(500) not null будет 2 байта (длина) + до 500 символов (latin1)

name varchar(65533) not null будет 2 байта (длина) + до 65533 символов (latin1)

name varchar(65532) будет 2 байта (длина) + до 65532 символов (latin1) + 1 нулевой байт

Надеюсь, что это поможет:)

Ответ 6

Всегда проверяйте у своего эксперта в области бизнеса. Если это вы, посмотрите на отраслевой стандарт. Если, например, рассматриваемый домен является фамилией естественного человека (фамилия), то для британского бизнеса я бы пошел в каталог UK Govtalk для стандартов данных информацию о человеке и узнайте, что фамилия будет от 1 до 35 символов.

Ответ 7

Я не проверял это в последнее время, но в прошлом я знал, что драйвер JDBC зарезервирует кусок памяти во время выполнения запроса, чтобы вернуть возвращаемый набор результатов. Размер блока памяти зависит от определений столбцов и размера выборки. Таким образом, длина столбцов varchar2 влияет на объем памяти. Это вызвало серьезные проблемы с производительностью для меня много лет назад, так как мы всегда использовали varchar2 (4000) (максимальный в то время), а сбор мусора был намного менее эффективным, чем сегодня.

Ответ 8

В некотором смысле вы правы, хотя все, что меньше 2 ^ 8 символов, все равно будет регистрироваться как байт данных.

Если вы учитываете базового персонажа, который оставляет что-либо с VARCHAR <255, он занимает столько же места.

255 является хорошим базовым определением, если вы не хотите особо ограничивать чрезмерный ввод.