Вопрос

В слегка бурная дискуссия по 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 и не работал с другими СУБД.Но у меня нет оснований полагать, что там иначе.

Это было полезно?

Решение

Я могу говорить только за 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 обновлений.У вас одна база данных, это одно обновление.Аргумент «проще изменить клиентское приложение», если он верен, потенциально может означать, что база данных рассматривается как гигантская битовая корзина, в которой вся умная логика обрабатывается в клиентском коде.Это большая дискуссия, но поскольку все СУБД позволяют определять ограничения и т. д. в самой базе данных, совершенно очевидно, что есть, по крайней мере, веские основания полагать, что такая фундаментальная логика принадлежит серверной части.

Другие советы

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

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

Так почему же люди стараются сделать свои колонки как можно меньше? Я не верю в то, что их нужно делать как можно меньше, а в том, чтобы подобрать соответствующий размер.Некоторые причины делать (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 для моего адреса, и меня расстраивают веб-сайты, которые не позволяют вводить полный адрес.

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

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

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

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

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

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

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

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

Все что касается MS SQ-Server.

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

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

Если вы допускаете длину данных более 255 и кто-то ссылается на данные через MS Access, данные нельзя использовать для объединения таблиц (поставляются в виде поля памятки).Если данные экспортируются в Excel, их длина будет ограничена 255 символами в каждом поле.При создании наборов данных следует учитывать совместимость с другими программами.
Контроль качества данных — это контроль данных, поступающих в вашу среду.Что вам нужно для хранения данных длиной более 255 символов?Бывают случаи, когда длина данных должна превышать 255 символов, но их должно быть мало, и их следует использовать в качестве вспомогательной дополнительной информации для поля, которое можно использовать для анализа.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top