Каковы текущие лучшие практики в отношении определения размера varchar в SQL Server?

12

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

Производительность
Из моего исследования, кажетсяэтот varchar (max) следует использовать только в том случае, если он вам действительно нужен; то есть, если столбец должен содержать более 8000 символов, одной из причин является отсутствие индексации (хотя я немного подозрительно отношусь к индексации по полям varchar в целом. Хотя я довольно плохо знаком с принципами БД, так что, возможно, это необоснованно ) и сжатие (больше касается хранения). На самом деле, обычно люди рекомендуют использовать только то, что вам нужно, при выполнении varchar (n) .... слишком большой размер - это плохо, потому что запросы должны учитывать максимально возможный размер. Но также было заявлено, что движок будет использовать половину указанного размера в качестве оценки среднего фактического размера данных. Это означало бы, что из данных следует определить, какой средний размер, удвоить его и использовать в качестве n. Для данных с очень низкой, но ненулевой изменчивостью это подразумевает увеличение размера в 2 раза до максимального размера, что кажется большим, но, возможно, это не так? Выводы будут оценены.

Хранение
После прочтения о том, как работает хранилище между строками и вне строк, и с учетом того, что фактическое хранилище ограничено фактическими данными, мне действительно кажется, что выбор n не имеет большого значения или не имеет никакого отношения к хранилищу (кроме убедившись, что он достаточно большой, чтобы вместить все). Даже использование varchar (max) не должно иметь никакого влияния на хранилище. Вместо этого цель может заключаться в том, чтобы ограничить фактический размер каждой строки данных до ~ 8000 байт, если это возможно. Это точное чтение вещей?

Контекст
Некоторые данные о наших клиентах немного колеблются, поэтому мы обычно делаем столбцы чуть шире, чем нужно, скажем, на 15-20% больше для этих столбцов. Мне было интересно, были ли какие-то другие особые соображения; например, кто-то, с кем я работаю, сказал мне использовать 2 ^ n - 1 размера (хотя я не нашел доказательств, что это правда ....)

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

Вопрос в том, сколько стоит, и есть ли технические рекомендации?

aristotle2600
источник
MongoDB использует 2 ^ n выделения диска для документа. SQL Server не использует эту стратегию.
Майкл Грин

Ответы:

19

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

Вам также не нужно и не нужно указывать длину столбца, превышающую максимальный фактический размер, который будет храниться по разным причинам: выделение памяти для запросов, потенциально заполнение максимального размера строки и отсутствие возможности для добавления столбцов в будущее и т. д.

Истинно, строковые и двоичные столбцы переменной длины не имеют значения хранения, которое имеют типы данных фиксированной длины (строка / двоичный / числовой / дата / и т. Д.) (Хотя некоторые из этих последствий могут быть аннулированы посредством сжатия данных или использования SPARSEопределения столбца опция). Тем не менее, как вы указали, даже если нет непосредственного влияния на хранилище, все равно остается влияние на производительность при переоценке требуемой памяти для запросов.

Будь разумным. Используйте только то, что вам нужно. Соображения могут быть приняты, если есть высокая вероятность того, что длина столбца потребуется увеличить в ближайшем будущем, но имейте в виду, что легче расширить размер столбца, чем уменьшить его. Да, некоторая работа будет задействована, но, поскольку эта работа является просто «потенциальной», в то время как последствия превышения размера для производительности являются «актуальными», часто лучше определять столбцы на основе того, что вам действительно нужно, а не того, что вы, может быть, вроде. Думаю, что вам может понадобиться в будущем. Многие изменения, о которых говорится, никогда не происходят, и часто требуемые изменения не могут быть предусмотрены. Иди с тем, что ты знаешь.

Вместо этого цель может заключаться в том, чтобы ограничить фактический размер каждой строки данных до ~ 8000 байт, если это возможно.

Я не совсем уверен, что вы получаете здесь. SQL Server физически ограничит вас более чем 8000 байтами. Использование типов LOB - VARCHAR(MAX), NVARCHAR(MAX), VARBINARY(MAX), XML, и осуждается TEXT, NTEXTи IMAGEтипы - позволяют выход за пределы этого начального ограничения размера страницы, но это только из - за размещения указателя (16 или более байт, в зависимости от типа, и в зависимости от размер значения, хранящегося вне строки при использовании MAXтипов). Фактический физический предел страницы данных не изменился.

Ваша цель должна состоять в том, чтобы использовать наименьшее количество физического пространства для хранения того, что требуется приложению / бизнесу для хранения, без разбивки или усечения, чтобы неполное значение теряло смысл или вызывало проблемы в нисходящем направлении. Если вам нужно хранить 12 000 символов, используйте его, VARCHAR(MAX)потому что это то, что нужно. Если вы храните номер телефона или почтовый индекс, то его было бы неразумно использовать VARCHAR(100)и безответственно использовать VARCHAR(MAX).

некоторые из наших данных о клиентах немного колеблются, поэтому мы обычно делаем столбцы чуть шире, чем нужно, скажем, на 15-20% больше для этих столбцов. Мне было интересно, были ли какие-то другие особые соображения;

Разве не во всех системах есть хотя бы некоторые данные, которые колеблются? Любая система, которая хранит имя человека, будет соответствовать требованиям, верно? Существует довольно большая разница в длине имен. А потом у вас есть кто-то вроде принца, иди и поменяй его имя на символ, и теперь у тебя совершенно другая проблема, а не длина. Это просто как дела.

Но, чтобы играть адвокат дьявола на минуту: как может « на 15-20% больше , чем то , что нужно» значение не может быть фактическим Нужным значением? Допустим, есть обсуждение о добавлении нового столбца, и кто-то предлагает 50 символов, затем кто-то говорит: «Ну, на 20% больше - это 60, поэтому давайте сделаем 60, потому что у кого-то может быть 60». Если это правда, что у клиента может быть 60, то 60 всегда было и всегда было фактическим необходимым значением, а 50 всегда ошибалось .

Конечно, было бы полезно, если бы были какие-то указания относительно источника данных, потому что:

  1. если вы делаете «URL» 1024, а кому-то нужно 1060, то оно должно быть 1060 (аналогично, если вы делаете URL-адрес VARCHARи получаете жалобы на то, что он портит символы Юникода, которые теперь разрешены в доменных именах, тогда это должно быть NVARCHAR), но
  2. если кто-то хочет добавить 1000 символов в поле комментария с ограничением в 500 символов, тогда ему все равно нужно только 500. Люди могут быть менее подробными в комментариях (для меня ProductSKUэто большая проблема ;-), но лучше быть достаточно большими, чтобы вместить все из SKU клиента.

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

Вы делаете много предположений здесь. Конечно, некоторые поля могут стать больше. Но опять же, они не могут. Или некоторые могут стать меньше. Некоторые могут измениться от не-Unicode к Unicode (как только они поймут, что мир становится меньше, и нельзя предположить, что фамилии будут когда-либо иметь только основные английские символы ASCII / US). Или они могут прекратить отправку поля. Или они могут добавить одно или несколько полей в будущем. Любая комбинация этого и других вещей. Так почему бы сосредоточиться только на VARCHARстолбцах? Что если они в настоящее время отправляют INTзначение и через год или два достигают максимального значения и начинают отправку BIGINT? Что, если у них есть поле «статус» со значениями 0 - 5. Вы только собираетесь предполагатьINTкоторый "дополнен", поскольку он учитывает рост, но, вероятно, должен быть TINYINT?

Единственное, что вы можете с уверенностью предсказать, это то, что попытка предсказать, как изменятся данные ваших клиентов, будет чаще ошибочной, чем правильной. И быть правильным - это вопрос удачи / совпадения (если не удача, то просто играй в лотерею;).

Таким образом, руководство:

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

У вас уже есть пример данных, отлично. Но, пожалуйста, не забывайте, что у вас также есть контактная информация вашего клиента: телефон и / или электронная почта. Свяжитесь с ними! Спросите их об их спецификациях данных (как и в вашей системе, максимальная длина данных, которые в настоящее время находятся в их системе, может составлять 35, но их система определена как VARCHAR(50), и их система будет принимать до этой длины, и в этом случае вам следует использовать 50). И спросите их, есть ли у них какие-либо планы на ближайшую перспективу и какие типы данных (тип и / или размер).

Соломон Руцкий
источник
1
Я согласен с Соломоном, @ Aristotle2600 - однако, возможно, вы захотите взглянуть на мой ответ на вопрос о различиях между a varchar(255)и a varchar(256)для некоторых дальнейших рассуждений
Макс Вернон,
Спасибо, у меня сложилось впечатление, что это будет что-то вроде этого, и «использовать только то, что вам нужно» - это просто хорошая практика управления ресурсами. Но некоторые данные о наших клиентах немного колеблются, поэтому мы обычно делаем столбцы чуть шире, чем нужно, скажем, на 15-20% больше для этих столбцов. Мне было интересно, были ли какие-то другие особые соображения; например, кто-то, с кем я работаю, сказал мне использовать 2 ^ n - 1 размера (хотя я не нашел доказательств того, что это правда ....). Но, похоже, нет ничего, кроме как сделать вещи как можно меньше.
aristotle2600
1
@ aristotle2600 Не уверен, как применить «2 ^ n - 1», но я все еще должен спросить: возможно ли даже теоретически сделать что-то большее, чем должно быть? Не был , что на 15-20% больше размера будет размером , что нужно , чтобы быть не сломаться? ;-). Я уверен, что это помогло бы, если бы вы были более явными в источнике данных, потому что а) если вы делаете «URL» 1024, а кому-то нужно 1060, то это должно быть 1060, но б) если кто-то хочет добавить 1000 chars в поле комментария с ограничением в 500 символов, тогда все равно нужно только 500. Люди могут вводить меньше в комментариях, но SKU продукта лучше быть достаточно большим.
Соломон Руцки
@ aristotle2600 Я только что добавил некоторые ваши комментарии здесь в вопрос, поскольку они обеспечивают хороший контекст. Я также добавил материал в конец моего ответа :)
Соломон Руцки
Большое спасибо за ваш ответ! Да, имена и адреса колеблются. Что касается постоянно увеличивающегося 20% -ного парадокса, я понимаю, что вы имеете в виду, но я говорю о первоначальном создании таблицы. Клиент скажет нам, что он собирается начать посылать нам новую таблицу и отправлять образцы данных (или только первый производственный набор данных), которые мы рассмотрим, и создадим таблицу с нашей стороны для хранения данных. Мы хотим создать таблицу с нашей стороны для обработки будущего импорта, а также того, что в образце. Но некоторые строки должны становиться длиннее, поэтому мы дополняем их. Вопрос в том, сколько стоит, и есть ли технические рекомендации?
aristotle2600