Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
Fungus
Member

Откуда:
Сообщений: 63
Имеет ли смысл при создании таблицы для каждого строкового поля стараться определится с максимальным размером? Всегда есть вероятность ошибиться, как в одну так и в другую стороны. Насколько критично в плане производительности, если, к примеру, для полей Name, Title использовать nvarchar(max) ? Т.е. понятно что для данных полей какое то ограничение по длине существует, но и не угадаешь какое. Название какого нибудь документа может быть весьма длинным.

Хотелось бы узнать у профи мнение как поступать. Стараться, все таки, ограничить размер, или NVarchar(max) вполне терпим. Насколько, к примеру, поле с ошибочным размером (или расчитанным на очень очень редкие длинные случаи) выйдет хуже, чем если бы была бы просто установлена Max длина ? Окупит ли одно длинное название то, что остальные тысячи будут использовать от силы 1/5 заложенной длины ?

Правильно ли я понимаю, что, фактически, установка длины имеет лишь очень редкое предназначение, когда длина абсолютно четко задача для всех значений поля - например для хранение hash или GUID в виде строки?
21 ноя 16, 12:20    [19915437]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
iap
Member

Откуда: Москва
Сообщений: 47052
Fungus
Стараться, все таки, ограничить размер, или NVarchar(max) вполне терпим
стараться.
Использовать VARCHAR(MAX) только при необходимости.
Если укладывается в в 8000 символв (4000 юникода), то лучше простой (N)VARCHAR()
21 ноя 16, 12:25    [19915468]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
Fungus
Member

Откуда:
Сообщений: 63
iap,

Можете больше информации пожалуйста ? Объяснение, разницу в производительности. Чтобы понимать детали, понимать почему. А то даже по вашему предложению "лучше простой (N)VARCHAR()" и то не ясно.
21 ноя 16, 12:33    [19915511]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
Хе-хе )
Guest
(N)VARCHAR(MAX) храниться отдельно от остальных данных таблицы (не в листьях)
Отсюда, например, невозможность переноса этого поля вместе с таблицей в другю ФГ переносом кластерного индекса
21 ноя 16, 12:35    [19915520]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8350
Fungus,

почему редкое, если Вы хотите оптимизировать обновление и утилизацию удаления, то фиксированная длина очень кстати.
21 ноя 16, 12:35    [19915523]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
Konst_One
Member

Откуда:
Сообщений: 11568
varchar(max) индекс не сделать
21 ноя 16, 12:38    [19915540]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
iap
Member

Откуда: Москва
Сообщений: 47052
(N)VARCHAR(MAX) накладывает на использование поля некоторые ограничения.
Например, его нельзя использовать в индексе.
21 ноя 16, 12:39    [19915544]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
Fungus
Member

Откуда:
Сообщений: 63
Хе-хе ),

Зачем мне "переноса этого поля вместе с таблицей в другю ФГ переносом кластерного индекса" ? O.o

Ну хорошо. Есть ли смысл все поля объявлять как "(N)VARCHAR()" или стоит все же мучительно продумывать допустимую длину ? И окупит ли установленная длина в 100 для одного документа, если остальные 99% документов укладываются в 15 символов ?
21 ноя 16, 12:39    [19915545]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
iap
Member

Откуда: Москва
Сообщений: 47052
Fungus,

В скобках для VARCHAR() указывается максимально допустимая длина поля.
При этом данные в разных записях будут занимать только необходимое для них место.
В отличие от CHAR().
21 ноя 16, 12:43    [19915568]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37155
Fungus
Зачем мне "переноса этого поля вместе с таблицей в другю ФГ переносом кластерного индекса" ? O.o
Он может понадобиться тем, кто будет сопровождать ваше творение.

Fungus
Ну хорошо. Есть ли смысл все поля объявлять как "(N)VARCHAR()" или стоит все же мучительно продумывать допустимую длину ? И окупит ли установленная длина в 100 для одного документа, если остальные 99% документов укладываются в 15 символов ?
За лень придется плптить накладными расходами сервера на манипуляцию блоб-данными.
21 ноя 16, 12:43    [19915569]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
Хе-хе )
Guest
До varchar(8000), nvarchar(4000) безобразницы длинна
А (n)varchar(max) c разницей которую описали уже
21 ноя 16, 12:46    [19915575]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
Fungus
Member

Откуда:
Сообщений: 63
Как понимаю нету принципиальной разницы между 100 и 3500, т.к. "занимать будут ровно столько сколько занимают". Соответственно возникает вопрос есть ли смысл нащупывать нижнюю границу ? Продумывая "100 или 200 тут хватит ?" или разницы не будет чем если использовать просто 3500 везде? Опять же учитывайте, что нужно все таки хранить и граничные случаи - когда название действительно длинное. Не запрещать же сохранять документ с длинным название только потому, что мы решили для всех документов указать меньшую длину.
21 ноя 16, 12:50    [19915593]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
Konst_One
Member

Откуда:
Сообщений: 11568
ТС,
вы про 3-ю нормальную форму что-нибудь знаете? почитайте.
21 ноя 16, 12:52    [19915609]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
Sybex
Member

Откуда: Moscow
Сообщений: 117
В SQL Server размер страницы 8 килобайт, поэтому поля до nvarchar(4000) или varchar(8000) хранятся вместе с остальными данным, а (n)varchar(MAX) уже хранится отдельно от основных данных.
Максимальный общий размер всех столбцов, входящих в индекс не должен превышать 900 байт. То есть если вы сделаете для полей Фамилия, Имя, Отчество столбцы nvarchar(250), то получится, что создать индекс по этим трём полям сразу уже не выйдет, так как их суммарный объём составит 250*2*3=1500 байт!
Выбирать размер поля нужно конечно же из соображений того, что там будет хранится. Нет смысла делать для поля ИНН длину в 50 символов, но с другой стороны, если у вас есть название документа в 1000 символов, и вам нужно его хранить, хотя там такое длинное название встречается один раз на миллион, то конечно же нужно делать поле в 1000 символов. Ведь его хранение требует бизнес-логика! А если по этому полю нужен индекс для поисков, то придётся как-то изворачиваться.
В общем, нужно выбирать такую длину столбца, чтобы туда вмещались все ваши данные, но при этом стараться всё же не задавать слишком уж избыточную длину.
21 ноя 16, 12:53    [19915613]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
Fungus
Member

Откуда:
Сообщений: 63
Konst_One,

Это причем тут ? O.o
"Переменная отношения R находится в 3NF тогда и только тогда, когда выполняются следующие условия:
R находится во второй нормальной форме.
ни один неключевой атрибут R не находится в транзитивной функциональной зависимости от потенциального ключа R."

Если вы видите связь между этим и моим вопросом, то не могли бы вы объяснить Я ее не вижу :(
21 ноя 16, 12:56    [19915627]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
Fungus
Member

Откуда:
Сообщений: 63
Sybex,

Спасибо за разъяснение. Начинаю понимать логику. Особенно про связь с ограничением на 900 байт в записи индекса.
Получается, что если индекс не делаем по текстовому полю, то там можно без опаски всегда ставить какое нибудь nvarchar(3900), ведь разницы с nvarchar(300) не будет ? Если же поле будет индексироваться, то уже придется как-то изворачиваться и стараться уменьшить. Особенно если индекс будет составным.

Раз затронули этот вопрос про ограничение в 900, объясните пожалуйста. В такой ситуации же нет смысла ограничивать длину столбцов, чтобы их сумма была строго 900 (например установив каждому по 300). Ведь одно и тоже поле может войти в разные индексы - и все равно не получится задать строго размер же (чтобы он и там и там не вышел за 900 байт).Тогда снова получается, что выгодно задать им всем nvarchar(3900). Если их общая длина превысит 900 байт, то пользователь получит ошибку и вынужден будет что-то уменьшить.
21 ноя 16, 13:08    [19915693]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
Sybex
Member

Откуда: Moscow
Сообщений: 117
С ограничением длины индекса не всё так просто. Фактически можно создать индекс и по столбцам, которые в сумме дадут максимальную длину больше 900 байт. SQL Server при этом просто выкинет предупреждение. И работать это всё будет зашибись, до тех пор, пока реальное наполнение этих столбцов не выйдет за предел в 900 байт. Вот тогда уже вывалиться ошибка и данные вставлены не будут. Таких ситуаций лучше не допускать, ограничивая длину столбцов таким образом, чтобы и в теории по составному индексу данные не вышли за эти 900 байт.
21 ноя 16, 13:17    [19915743]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
Fungus
Member

Откуда:
Сообщений: 63
Sybex,

Да я знаю про предупреждение. Но все равно ведь не выйдет угадать с размером, если поле состоит в нескольких индексах же. Так что либо остается устанавливать размер наименьший/защитный из возможных, чтобы сумма ВСЕХ индексов,куда входит поле, не вышла за 900 (а еще нужно заложится на возможное добавление полей и новых индексов !), либо делать везде Nvarchar(3900) и уже на клиенте обрабатывать ошибку превышения размера индекса вставке.
Мне видится второй вариант более перспективным.
21 ноя 16, 13:28    [19915809]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
Konst_One
Member

Откуда:
Сообщений: 11568
Fungus
Konst_One,

Это причем тут ? O.o
"Переменная отношения R находится в 3NF тогда и только тогда, когда выполняются следующие условия:
R находится во второй нормальной форме.
ни один неключевой атрибут R не находится в транзитивной функциональной зависимости от потенциального ключа R."

Если вы видите связь между этим и моим вопросом, то не могли бы вы объяснить Я ее не вижу :(


вы всё время намекаете на несколько строковых полей с max в одной таблице, может у вас что-то не так с проектированием базы? если не знаете какие данные должны быть , то проведите аудит для начала.
21 ноя 16, 13:52    [19915969]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
Sybex
Member

Откуда: Moscow
Сообщений: 117
Fungus
либо делать везде Nvarchar(3900) и уже на клиенте обрабатывать ошибку превышения размера индекса вставке.


Нет! Больше чем Nvarchar(450) поле делать смысла не имеет, если по нему есть индекс, так как вставить в него строку, превышающую эту длину, всё равно не выйдет - получите ошибку.

Fungus
Мне видится второй вариант более перспективным.

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

Проектирование индексов - это отдельная тема для разговора. Ведь индекс - это благо для SELECT, но беда для INSERT/UPDATE/DELETE. Поэтому индексы должны быть созданы правильно, на основе потребностей в запросах. И чем меньше размеры строковых данных, тем больше манёвров при создании индексов.

Кстати, помимо индексов есть и другие минусы. Вот, например, нужно будет выгрузить данные из вашей БД в какую-то другую систему. Там посмотрят, что в вашей таблице поле с наименованием документа может содержать до 3900 символов. И что? Разработчики той системы уже у себя должны будут предусмотреть это поле такой же длины, так как иначе они могут потерять данные. То есть вы невольно ограничите их своим "перспективным" подходом.

Разработка - это всегда поиск компромиссов. И помните, что на переделывание чего-либо времени всегда уходит больше (иногда в разы), чем на то, чтобы изначально сделать всё "как надо".
21 ноя 16, 13:59    [19916028]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
Fungus
Member

Откуда:
Сообщений: 63
Sybex,
Аналитика постановщиков задач бывает и подводит. Так, что ограничение в 200 символов для Title может сломаться о жестокую реальность через год эксплуатации системы. И последствия могут быть высоки (невозможность дальнейшей поддержки индекса, необходимость переделывать модель данных). Да искать компромисы наверное нужно, но и вероятность ошибок при проектировании высока.

Насчет выгрузки в другие системы. Это отдельная задача с отдельной аналитикой и отдельными же компомисами. Сторонние разработчики должны бы заметить, что nvarchar(3900) используется ВЕЗДЕ, и поймут, что может быть им не стоит бездумно повторять это в своей бд - в идеале должны бы уточнить у меня/нас, или прочитать в документации об этом моменте. Возможно к тому времени в БД будет достаточно большой объем реальных данных, чтобы можно было оценить существующие длины полей и уже применить эти знания в своей системе.

В любом случае, спасибо всем за объяснение сути. Пока понял, что Nvarchar(3900) это вполне рабочее решение :) Даже с индексами не будет проблем, если обрабатывать возможную ошибку.
21 ноя 16, 14:20    [19916188]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
Fungus
Sybex,

В любом случае, спасибо всем за объяснение сути. Пока понял, что Nvarchar(3900) это вполне рабочее решение :) Даже с индексами не будет проблем, если обрабатывать возможную ошибку.

это просто ппц а не вывод...
21 ноя 16, 14:32    [19916293]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
Fungus
Member

Откуда:
Сообщений: 63
TaPaK,

Вижу только следующие варианты:
1. Кропотливо высчитывать размеры полей. С учетом вхождения в разные индексы, учитывая граничные случаи. Решать "так 100 или 1000 букв хватит для Title".
2. Nvarchar(max)
3. nvarchar(3900)

Первый вариант пожалуй самый правильный и эффективный. Но в нем нужно учесть множество деталей, которые сам разработчик может не знать. Нужно хорошо трясти заказчика аналитиков и все равно учитывать вероятность их ошибки. Второй вариант действительно плох, как я понял из объяснения, для обычных строковых полей, которые и близко не приблизятся к огромному размеру.
Ну а третий вариант считаю самым оптимальным ввиду того, что принципиальной разницы между ограничением в 200 и 3900 символов не вижу, ведь все равно место будет занято лишь для размера конкретных данных. Так зачем ограничивать ? Что касается индекса и ограничения в 900 байт, то я объяснил, что в подавляющем большинстве случаев эту проблему не увидим. Если делать индексы по полям, примерно понимая какой длины они могут быть. Либо на клиенте обрабатывать соответствующую ошибку.

Таковы мои выводы после прочтения данной темы. Полагаю, что третий вариант самый безопасный в плане разработки. Да может не самый идеальный в плане производительности, но работоспособный. Возможно я не правильно понял то, что до меня пытались донести :( Я хочу понять как правильно! Жаль, если выводы на самом деле другие, но ведь никто не формулирует их - только я предлагаю варианты и выводы.
Может есть статейка с разъяснением вопроса ?
21 ноя 16, 14:48    [19916409]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
Konst_One
Member

Откуда:
Сообщений: 11568
https://technet.microsoft.com/ru-ru/library/ms191241(v=sql.105).aspx

Если столбец таблицы принадлежит к типу данных Юникода, например nchar или nvarchar, отображаемая длина столбца представляет собой величину, необходимую для хранения его символов. Она в два раза превышает число символов, указанных в инструкции CREATE TABLE. В предыдущем примере столбец City определен как принадлежащий типу данных nvarchar(30); поэтому длина, необходимая для хранения символов столбца, равна 60 байт.
21 ноя 16, 14:53    [19916432]     Ответить | Цитировать Сообщить модератору
 Re: При создании новой таблицы, как определится с размером строки, и стоит ли ?  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
Fungus,
действительно, предлагаю и числовые поля не парится, а сразу в текст писать
по хорошему:
Определяете типы полей: код, название, описание и тп и длину для каждого из них, стандартизируете их под свою модель и рисуете архитектуру основанную на этих бизнес правилах, и если код ВДРУГ сдал длиннее чем заложено бизнес логикой, то логика у вас ни к чёрту и не должно быть что бы поле код стало романом ФМ Достоевского и про 3ю форму задумайтесь, а то попахивает всё это :)

автор
Да может не самый идеальный в плане производительности, но работоспособный.

может вам и не sql вовсе нужен?
21 ноя 16, 15:05    [19916492]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить