У меня есть contacts
таблица , которая содержит такие поля, как postcode
, first name
, last name
, town
, country
, и phone number
т.д., все из которых определены как VARCHAR(255)
даже если ни один из этих полей не будет когда - нибудь близко к тому 255 символов. (Если вам интересно, это так, потому что миграции Ruby on Rails сопоставляют поля String VARCHAR(255)
по умолчанию, и я никогда не удосужился переопределить это).
Поскольку VARCHAR будет хранить только количество фактических символов поля (вместе с длиной поля), есть ли какое-либо явное преимущество (производительность или иное) в использовании, скажем, VARCHAR(16)
сверх VARCHAR(255)
?
Кроме того, большинство этих полей имеют индексы. Влияет ли вообще больший размер VARCHAR в поле на размер или производительность индекса?
К вашему сведению, я использую MySQL 5.
Ответы:
В хранилище
VARCHAR(255)
достаточно умен, чтобы хранить только ту длину, которая вам нужна в данной строке, в отличие отCHAR(255)
которой всегда хранится 255 символов.Но поскольку вы пометили этот вопрос с помощью MySQL, я упомяну совет, относящийся к MySQL: по мере того, как строки копируются с уровня механизма хранения на уровень SQL,
VARCHAR
поля преобразуются в,CHAR
чтобы получить преимущество работы со строками фиксированной ширины. Таким образом, строки в памяти заполняются до максимальной длины объявленногоVARCHAR
столбца.Когда ваш запрос неявно создает временную таблицу, например, при сортировке или
GROUP BY
, это может использовать много памяти. Если вы используете многоVARCHAR(255)
полей для данных, которые не должны быть такими длинными, временная таблица может стать очень большой.Вам также может быть интересно узнать, что такое поведение «заполнения» означает, что строка, объявленная с набором символов utf8, дополняется до трех байтов на символ даже для строк, которые вы храните с однобайтовым содержимым (например, символы ascii или latin1). И аналогично набор символов utf8mb4 заставляет строку заполнять до четырех байтов на символ в памяти.
Таким образом,
VARCHAR(255)
в utf8 для хранения короткой строки, такой как «Нет мнения», требуется 11 байт на диске (десять символов нижнего набора символов плюс один байт для длины), но он занимает 765 байт в памяти и, следовательно, во временных таблицах или отсортированных результатах.Я помогал пользователям MySQL, которые по незнанию часто создавали временные таблицы объемом 1,5 ГБ и заполняли свое дисковое пространство. У них было много
VARCHAR(255)
столбцов, в которых на практике хранились очень короткие строки.Лучше всего определять столбец в зависимости от типа данных, которые вы собираетесь хранить. Как отмечали другие люди, он имеет преимущества в обеспечении соблюдения ограничений, связанных с приложением. Но у него есть физические преимущества, позволяющие избежать потери памяти, о которой я говорил выше.
Конечно, трудно определить самый длинный почтовый адрес, поэтому многие люди выбирают длинный,
VARCHAR
который определенно длиннее любого адреса. А 255 является обычным, потому что это максимальная длина,VARCHAR
для которой длина может быть закодирована одним байтом. Это также была максимальнаяVARCHAR
длина в MySQL старше 5.0.источник
255
что длина строки может уместиться в один байтВ дополнение к соображениям размера и производительности при установке размера varchar (и, возможно, более важно, поскольку хранение и обработка становятся дешевле каждую секунду), недостатком использования varchar (255) «просто потому, что» является снижение целостности данных .
Определение максимальных пределов для строк - это хорошая вещь, которую нужно сделать, чтобы предотвратить попадание в СУБД более длинных, чем ожидалось, строк и последующего переполнения буфера или исключений / ошибок при извлечении и анализе значений из базы данных, которые длиннее (больше байтов), чем ожидалось.
Например, если у вас есть поле, которое принимает двухсимвольные строки для сокращений стран, у вас нет никаких причин ожидать, что ваши пользователи (в данном контексте программисты) будут вводить полные названия стран. Поскольку вы не хотите, чтобы они вводили "Антигуа и Барбуда" (AG) или "Остров Херд и острова Макдоналда" (HM), вы не разрешаете это на уровне базы данных. Кроме того, вполне вероятно, что некоторые программисты еще не ознакомились с проектной документацией ( которая, безусловно, существует ), чтобы знать, что этого не следует делать.
Настройте поле так, чтобы оно принимало два символа, и позвольте СУБД обрабатывать их (либо аккуратно, усекая, либо неуклюже, отклоняя их SQL с ошибкой).
Примеры реальных данных, у которых нет причин превышать определенную длину:
И так далее...
Найдите время, чтобы подумать о своих данных и их ограничениях. Если вы архитектор, разработчик или программист, в конце концов , это ваша работа .
Используя varchar (n) вместо varchar (255), вы устраняете проблему, когда пользователи (конечные пользователи, программисты, другие программы) вводят неожиданно длинные данные , которые позже будут преследовать ваш код.
И я не говорил, что вам не следует также применять это ограничение в коде бизнес-логики, используемом вашим приложением.
источник
the design documentation (which surely exists)
Ха. : DЯ с тобой. Суетливое внимание к деталям - боль в шее, и ценность ее ограничена.
Когда-то диск был драгоценным товаром, и мы привыкли к его оптимизации. Стоимость хранения упала в 1000 раз, поэтому время, затрачиваемое на сжатие каждого байта, менее ценно.
Если вы используете только поля типа CHAR, вы можете получить строки фиксированной длины. Это может сэкономить немного времени на перезагрузке диска, если вы выбрали точные размеры полей. Вы можете получить более плотно упакованные данные (меньше операций ввода-вывода для сканирования таблиц) и более быстрые обновления (легче найти открытые места в блоке для обновлений и вставок).
Однако, если вы переоцениваете свои размеры или ваши фактические размеры данных изменчивы, вы будете тратить пространство впустую на поля CHAR. Данные будут упакованы менее плотно (что приведет к большему количеству операций ввода-вывода для больших объемов извлечения).
Как правило, выигрыш в производительности от попытки установить размер для переменных полей незначителен. Вы можете легко выполнить сравнительный анализ, используя VARCHAR (255) по сравнению с CHAR (x), чтобы увидеть, можете ли вы измерить разницу.
Однако иногда мне нужно дать «маленький», «средний», «большой» намек. Поэтому я использую 16, 64 и 255 для размеров.
источник
В настоящее время я не могу представить, что это действительно имеет значение.
Использование полей переменной длины связано с вычислительными затратами, но с избытком современных процессоров об этом даже не стоит думать. Система ввода-вывода настолько медленная, что практически не требует каких-либо вычислительных затрат для обработки varchars. Фактически, стоимость varchar в вычислительном отношении, вероятно, является чистой выгодой по сравнению с объемом дискового пространства, сэкономленным за счет использования полей переменной длины над полями фиксированной длины. Скорее всего, у вас более высокая плотность строк.
Теперь сложность полей varchar заключается в том, что вы не можете легко найти запись по ее номеру записи. Когда у вас есть размер строки фиксированной длины (с полями фиксированной длины), тривиально вычислить дисковый блок, на который указывает идентификатор строки. Благодаря размеру строк переменной длины такое просто невозможно.
Итак, теперь вам нужно поддерживать какой-то индекс номера записи, как и любой другой первичный ключ, ИЛИ вам нужно создать надежный идентификатор строки, который кодирует детали (например, блок и т. Д.) В идентификаторе. Однако, если вы это сделаете, идентификатор придется пересчитывать, если когда-либо строка перемещается в постоянное хранилище. Ничего страшного, просто нужно переписать все записи индекса и убедиться, что вы либо а) никогда не открываете его потребителю, либо б) никогда не утверждаете, что число является надежным.
Но поскольку сегодня у нас есть поля varchar, единственное значение varchar (16) по сравнению с varchar (255) состоит в том, что БД будет применять ограничение в 16 символов для varchar (16). Если предполагается, что модель БД действительно представляет физическую модель данных, то длина полей может иметь значение. Если, однако, это просто «хранилище», а не «модель И хранилище», в этом нет никакой необходимости.
Затем вам просто нужно различать текстовое поле, которое является индексируемым (например, varchar), и тем, что нет (например, текстовое поле или поле CLOB). Индексируемые поля, как правило, имеют ограничение по размеру для облегчения индексации, тогда как поля CLOB - нет (в разумных пределах).
источник
По моему опыту, если вы разрешите тип данных из 255 символов, какой-нибудь глупый пользователь (или какой-нибудь опытный тестировщик) фактически заполнит его.
Тогда у вас возникнут всевозможные проблемы, включая то, сколько места вы отводите для этих полей в отчетах и экранных дисплеях в вашем приложении. Не говоря уже о возможности превышения ограничения на количество строк для данных в вашей базе данных (если у вас было более нескольких из этих 255 символьных полей).
Намного проще выбрать разумный предел вначале, а затем обеспечить его соблюдение через приложение и базу данных.
источник
Хорошая практика - выделять немного больше того, что вам нужно. Телефонные номера никогда бы не стали такими большими.
Одна из причин заключается в том, что, если вы не проверяете большие записи, несомненно, кто-то будет использовать все, что есть. Тогда в вашем ряду может закончиться место. Я не уверен в ограничении MySQL, но 8060 - это максимальный размер строки в MS SQL.
Более нормальным значением по умолчанию будет 50 imho, а затем увеличьте там, где это необходимо.
источник
В контексте mysql это может стать важным при работе с индексами для указанных столбцов varchar, поскольку mysql имеет макс. ограничение 767 байтов на строку индекса.
Это означает, что при добавлении индекса для нескольких столбцов varchar 255 вы можете довольно быстро / даже быстрее достичь этого предела для столбцов utf8 или utf8mb4, как указано в ответах выше
источник