Какой размер выбрать для столбца varchar (n)?
на слегка жаркое обсуждение 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 и я не работал с другими СУБД. Но у меня нет причин полагать, что там все по-другому.
8 ответов
Я могу говорить только за Oracle. VARCHAR2(50) и VARCHAR2 (255) занимают ровно столько же места и выполняют одинаково, если ввести значение 'SMITH'.
однако причина, по которой обычно не рекомендуется объявлять все ваши текстовые столбцы как VARCHAR2(4000), заключается в том, что длина столбца является, по сути, еще одним ограничением. И ограничения-это реализация бизнес-правил в базе данных, поэтому они определенно должны быть определены на база данных сторона вещей.
в качестве примера. Вы определяете контрольное ограничение для столбца, чтобы значения, которые он может принять, были только " Y " и "N". Это избавляет ваше приложение от необходимости иметь дело с " y " и " n "или даже" 1 " и "0". Ограничение Check гарантирует, что ваши данные соответствуют ожидаемым стандартам. Затем код приложения может сделать допустимые предположения о природе данных, с которыми он имеет дело.
определение длины столбца находится в той же лодке. Вы заявляете что - то должно быть VARCHAR2(10), потому что вы не хотите, чтобы он принимал запись "ABC123ZYX456" (по какой-либо причине!)
в Австралии я определяю столбцы Штатов как varchar2 (3), потому что я не хочу, чтобы люди печатали "Новый Южный Уэльс" или "Южная Австралия". Определение столбца в значительной степени заставляет их вводить как " NSW " и "SA". В этом смысле VARCHAR2 (3) является почти таким же ограничением проверки, как и фактическое указание регистрации ("NSW", "SA", " VIC " и т. д) ограничение.
короче говоря, правильные длины столбцов-это способ кодирования бизнес-правил. Это еще одна форма принуждения. Они приносят все преимущества ограничений (и страдают от многих из тех же недостатков). И они обеспечивают, в небольшой степени, степень "чистоты данных", с которой также помогают" правильные " ограничения.
Я тоже не покупаю аргумент, что лучше всего вставлять такие вещи в клиентское приложение, потому что там легче изменить. У вас есть 20,000 человек используют приложение, это 20,000 обновлений. У вас одна база данных, это одно обновление. Аргумент "легче изменить клиентское приложение", если true, потенциально означает, что база данных просто обрабатывается как гигантское битное ведро со всей умной логикой, обрабатываемой в клиентском коде. Это большая дискуссия, но поскольку все RDBMSes позволяют вам определять ограничения и так далее в самой базе данных, довольно ясно, что есть, по крайней мере, стоящий случай, чтобы такая фундаментальная логика принадлежит в backend.
Я слышал, оптимизатор запросов тут примите во внимание длину varchar, хотя я не могу найти ссылку.
определение длины varchar помогает сообщить намерение. Чем больше противопоказаний, тем надежнее данные.
Так почему же люди пытаются сделать свои столбцы как можно меньше? Я не верю в то, чтобы сделать их как можно меньше, но правильно их оценить. Некоторые причины для того, чтобы сделать (n)varchars меньше, а не больше:
1) с большим полем все клиенты, использующие базу данных, должны иметь возможность обрабатывать полный размер. Например, возьмите систему, содержащую адрес Соединенных Штатов с 255 символами на каждое поле: (аналогично TDWTF, на который вы ссылаетесь, I верить.)
- Имя
- Фамилия
- Адресная Строка 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 основывает все свои фиксированные длины VARCHAR
s на своем unlimitted TEXT
введите и динамически решает на как сохранить значение, включая хранение его вне страницы. Спецификатор длины в этом случае действительно является ограничением, и его использование фактически не рекомендуется. (ref)
другие СУБД требуют, чтобы пользователь выбирал, требуют ли они "неограниченного", вне страницы, хранения, обычно с соответствующей стоимостью в удобстве и/или производительности.
если есть преимущество в использовании VARCHAR(<n>)
над VARCHAR(MAX)
или TEXT
, из этого следует, что вы должны выбрать значение для <n>
при проектировании таблиц. Предполагая, что существует некоторая максимальная ширина строки таблицы или записи индекса, следующие ограничения должны применить:
-
<n>
должно быть меньше или равно<max width>
- если
<n> = <max width>
индекс таблица может иметь только 1 столбец - в общем, таблица / индекс может иметь только
<x>
столбцы, где (в среднем)<n> = <max width> / <x>
поэтому не дело в том, что значение <n>
действует только как ограничение, и выбор <n>
должно быть частью конструкции. (Даже если в вашей СУБД нет жесткого ограничения, вполне могут быть причины производительности, чтобы сохранить ширину в пределах определенного предела.)
вы можете использовать вышеуказанные правила для назначения максимум стоимостью <n>
, на основе ожидаемой архитектуры вашей таблицы (с учетом влияния будущих изменений). Тем не менее, имеет смысл определить минимум стоимостью <n>
, основываясь на ожидаемом сведения в каждом столбце. Скорее всего, вы расширитесь до ближайшего " круглого номера" - например, вы всегда будете использовать либо VARCHAR(10)
, VARCHAR(50)
, VARCHAR(200)
или VARCHAR(1000)
, в зависимости от того, что лучше всего подходит.
простой ответ на это, на мой взгляд, заключается в том, что вы не можете использовать этот столбец в качестве ключа индекса, если вам требуется индексирование, вы в основном вынуждены использовать fulltext... это касается использования столбца varchar(max). В любом случае столбцы "правого размера" имеют большой смысл, когда вы [можете] применить любую индексацию; обновление столбцов переменной длины может быть дорогостоящим маневром, поскольку они не выполняются на месте и могут/вызовут некоторую фрагментацию.
все с что касается MS SQ-Server.
Я отвечу на ваш вопрос вопросом: Если для СУБД нет разницы между varchar(50) и varchar(255), почему СУБД позволяют вам проводить различие? Почему бы СУБД просто не сказать: "используйте varchar для символов xxx и text/clob/etc. за что за что."Конечно, возможно, Microsoft / Oracle/IBM может сохранить определение длины по историческим причинам, но как насчет СУБД, таких как MySQL, которая имеет несколько бэкэндов хранения - почему каждый из них реализует definable длина столбца символов?
Если вы собираетесь печатать метки, вы обычно хотите, чтобы строка была не длиннее 35 символов. Вот почему вам нужен некоторый контроль над размером Varchar, который вы собираетесь использовать, чтобы принять линии, которые будут использоваться для печати этикеток.
Если вы разрешаете длину данных более 255 и кто-то ссылается на данные через MS Access, данные не могут быть использованы для объединения таблиц (входит в качестве поля заметки). Если данные экспортируются в excel, они будут ограничены 255 символами на поле. При создании наборов данных следует учитывать совместимость с другими программами.
Контроль качества данных - это контроль данных, поступающих в вашу среду. Что нужно хранить, что составляет более 255 символов? Есть раз, что данные должны быть более 255 символов, но они должны быть далеко и мало Между и должны использоваться в качестве вспомогательной дополнительной информации для поля, которое может быть использовано для анализа