Подтвердить что ты не робот

Какой размер выбрать для столбца (n) varchar?

В обсуждении слегка нагретого обсуждения TDWTF возник вопрос о размере столбцов varchar в БД.

Например, возьмите поле, содержащее имя человека (просто имя, фамилию). Легко видеть, что это будет не очень долго. У большинства людей есть имена с менее чем 10 символами, и немногие из них выше 20. Если вы сделаете свой столбец, скажем, varchar (50), он определенно будет содержать все имена, с которыми вы когда-либо сталкивались.

Однако для большинства СУБД нет никакой разницы в размере или скорости, независимо от того, используете ли вы varchar (50) или varchar (255).

Итак, почему люди пытаются сделать свои столбцы как можно меньше? Я понимаю, что в некоторых случаях вам действительно захочется установить ограничение на длину строки, но в основном это не так. И более широкий запас будет полезен только в случае редкого случая человека с чрезвычайно длинным именем.


Добавлено: Люди хотят ссылаться на утверждение о "без разницы в размере или скорости". ОК. Вот они:

Для MSSQL: http://msdn.microsoft.com/en-us/library/ms176089.aspx

Размер хранилища - это фактическая длина введенных данных + 2 байта.

Для MySQL: http://dev.mysql.com/doc/refman/5.1/en/storage-requirements.html

L + 1 байт, если значения столбца требуют 0 - 255 байт, L + 2 байта, если для значений может потребоваться больше 255 байт.

Я не могу найти документацию для Oracle, и я не работал с другими СУБД. Но у меня нет причин полагать, что там что-то другое.

4b9b3361

Ответ 1

Я могу говорить только за Oracle. VARCHAR2 (50) и VARCHAR2 (255) занимают ровно столько же места и выполняют тождественно, если вы вводите значение "SMITH".

Тем не менее, причина, по которой обычно не рекомендуется обсуждать все ваши текстовые столбцы, поскольку VARCHAR2 (4000) - это то, что длина столбца является, фактически, еще одним ограничением. И ограничения - это реализация бизнес-правил в базе данных, поэтому они определенно должны быть определены на стороне базы данных.

Как пример. Вы определяете ограничение CHECK для столбца, чтобы значения, которые он может принимать, являются только "Y" и "N". Это избавляет ваше приложение от необходимости иметь дело с "y" и "n" или даже "1" и "0". Ограничение проверки гарантирует соответствие ваших данных ожидаемым стандартам. Затем ваш код приложения может сделать допустимые предположения о характере данных, с которыми он должен иметь дело.

Определение длины столбца находится в одной лодке. Вы объявляете что-то VARCHAR2 (10), потому что вы не хотите, чтобы он принимал запись "ABC123ZYX456" (по любой причине!)

В Австралии я определяю столбцы STATE как varchar2 (3), потому что я не хочу, чтобы люди печатали "Новый Южный Уэльс" или "Южную Австралию". Определение столбца в значительной степени заставляет их вводиться как "NSW" и "SA". В этом смысле VARCHAR2 (3) является почти таким же контрольным ограничением, как и фактическое указание ограничений CHECK IN ('NSW', 'SA', 'VIC' и т.д.).

Короче говоря, правильные длины столбцов являются способом кодирования бизнес-правил. Это еще одна форма ограничения. Они приносят все преимущества ограничений (и страдают от многих из тех же недостатков). И они в какой-то степени обеспечивают степень "чистоты данных", с которой тоже помогают "правильные" ограничения.

Я тоже не покупаю аргумент, что лучше всего использовать такие вещи в клиентском приложении, потому что там легче меняться. У вас 20 000 человек, использующих приложение, это 20 000 обновлений. У вас есть одна база данных, одно обновление. Аргумент "проще изменить клиентское приложение", если это правда, потенциально может означать, что база данных просто рассматривается как гигантское ведро бит, причем всякая умная логика обрабатывается в клиентском коде. Это большая дискуссия, но поскольку все RDBMS позволяют определять ограничения и т.д. В самой базе данных, довольно ясно, что, по крайней мере, стоит сделать то, что такая фундаментальная логика принадлежит бэкэнду.

Ответ 2

Я слышал, что оптимизатор запросов делает, принимая во внимание длину varchar, хотя я не могу найти ссылку.

Определение длины varchar помогает сообщать о намерениях. Чем больше ограничений определено, тем более надежными являются данные.

Ответ 3

Итак, почему люди пытаются сделать свои столбцы как можно меньше? Я не верю, что сделаю их настолько маленькими, насколько это возможно, но соответствующим образом определяя их. Некоторые причины создания (n) varchars меньше, чем больше:

1) С большим полем все клиенты, которые используют базу данных, должны иметь возможность обрабатывать полный размер. Например, возьмите систему, которая содержит адрес Соединенных Штатов с 255 символами на каждое поле: (Похоже на TDWTF, на который вы ссылаетесь, я считаю.)

  • Имя
  • Фамилия
  • Адресная строка 1
  • Адресная строка 2
  • Город
  • Состояние
  • Почтовый индекс

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

Но мне не нужна проблема форматирования адреса для конверта, который может содержать 255 символов для каждого из этих полей или только для любого из этих полей. Собираетесь ли вы усечь, если поле слишком длинное, чтобы соответствовать? У большого кого-то есть Адресная линия 1 "Номер дома Номер Стойки... бла-бла-бла... Номер квартиры 111." И вы удалите важный номер квартиры. Вы собираетесь обернуть? Сколько? Что делать, если вы просто не можете поместить его в маленькую коробку пространства на конверте? Поднимите исключение и попросите кого-нибудь передать его?

2) В то время как 10 символов данных, хранящихся в varchar (50) по сравнению с varchar (255), не влияют на размер или скорость, позволяя использовать 255 символов для большего количества пространства. И если все поля такие большие, вы можете столкнуться с ограничениями по размеру в SQL Server 2000. (Я не читал в 2005 и 2008 годах, чтобы увидеть, могут ли они обрабатывать строки, большие, чем одна страница.) И с Oracle вы больше размеров допускаете строку цепочка произойдет, если кто-то действительно использует все доступные символы.

3) Индексы имеют более строгие ограничения по размеру, чем листовые страницы. Вы можете исключить индексы, особенно составные индексы, если вы создаете слишком большие ваши varchars.


С другой стороны, у меня есть длинная строка 1 для моего адреса, и я разочарован веб-сайтами, которые не позволяют набирать полную информацию.

Ответ 4

Одно важное различие заключается в определении произвольно большого предела (например, VARCHAR(2000)] и используя тип данных, который не требует ограничения (например, VARCHAR(MAX) или TEXT].

PostgreSQL основывает свою фиксированную длину VARCHAR на своем неограниченном типе TEXT и динамически принимает решение о том, как сохранить значение, в том числе хранить его вне страницы. Спецификатор длины в этом случае действительно является просто ограничением, и его использование фактически обескуражено. (ref)

Другие СУБД требуют от пользователя выбора, если они требуют "неограниченного", внестраничного хранилища, обычно с соответствующей стоимостью по удобству и/или производительности.

Если есть преимущество при использовании VARCHAR(<n>) over VARCHAR(MAX) или TEXT, то при проектировании ваших таблиц вы должны выбрать значение <n>. Предполагая, что существует некоторая максимальная ширина строки таблицы или записи индекса, должны применяться следующие ограничения:

  • <n> должен быть меньше или равен <max width>
  • if <n> = <max width>, таблица /index может иметь только 1 столбец
  • в целом, таблица/индекс может иметь только столбцы <x>, где (в среднем) <n> = <max width> / <x>

Поэтому не случай, когда значение <n> действует только как ограничение, а выбор <n> должен быть частью дизайна. (Даже если в вашей СУБД нет жесткого ограничения, вполне возможно, что существуют ограничения производительности для ограничения ширины в пределах определенного предела.)

Вы можете использовать приведенные выше правила для назначения максимального значения <n> на основе ожидаемой архитектуры вашей таблицы (с учетом влияния будущих изменений). Однако имеет смысл определить минимальное значение <n>, основанное на ожидаемых данных в каждом столбце. Скорее всего, вы перейдете на ближайшее "круглое число" - например, вы всегда будете использовать либо VARCHAR(10), VARCHAR(50), VARCHAR(200), либо VARCHAR(1000), в зависимости от того, что лучше всего подходит.

Ответ 5

Простым ответом на это, на мой взгляд, является тот факт, что вы не можете использовать этот столбец как индексный ключ, если вам требуется какая-либо индексация, вы в основном вынуждены использовать полный текст... это касается использования varchar (max) колонка. В любом случае столбцы "правильной калибровки" имеют большой смысл, когда вы [можете] захотеть применить любую индексацию; обновление столбцов переменной длины может быть дорогостоящим маневром, поскольку они не выполняются на месте и могут/будут вызывать некоторое количество фрагментации.

Все в отношении MS SQ-Server.

Ответ 6

Я отвечу на ваш вопрос вопросом: если нет никакой разницы между СУБД между varchar (50) и varchar (255), почему бы СУБД позволить вам сделать различие? Почему бы СУБД просто не сказать "использовать varchar для символов до xxx, а также текст/clob/и т.д. Для чего-либо над этим". Несомненно, возможно, Microsoft/Oracle/IBM может содержать определение длины по историческим причинам, но как насчет СУБД, например MySQL, который имеет несколько серверов хранения данных - почему каждый из них реализует определяемые длины столбцов символов?

Ответ 7

Если вы собираетесь печатать ярлыки, вы обычно хотите, чтобы строка не превышала 35 символов. Вот почему вам нужен какой-то контроль над размером Varchar, который вы собираетесь использовать для принятия строки, которые будут использоваться для печати меток.