Есть ли недостатки при использовании nvarchar (MAX)? - PullRequest
321 голосов
/ 29 сентября 2008

В SQL Server 2005 есть какие-либо недостатки, связанные с тем, что все символьные поля должны быть nvarchar (MAX), вместо того, чтобы явно указывать длину, например, NVARCHAR (255)? (Помимо очевидного, что вы не можете ограничить длину поля на уровне базы данных)

Ответы [ 22 ]

140 голосов
/ 29 сентября 2008

Тот же вопрос задавался на форумах MSDN:

Из исходного поста (гораздо больше информации там):

Когда вы сохраняете данные в столбце VARCHAR (N), значения физически сохраняются таким же образом. Но когда вы сохраняете его в столбце VARCHAR (MAX), за экраном данные обрабатываются как значение TEXT. Таким образом, при работе со значением VARCHAR (MAX) требуется дополнительная обработка. (только если размер превышает 8000)

VARCHAR (MAX) или NVARCHAR (MAX) рассматривается как «тип большого значения». Типы больших значений обычно хранятся вне строки. Это означает, что строка данных будет иметь указатель на другое место, где хранится «большое значение» ...

47 голосов
/ 29 сентября 2008

Это справедливый вопрос, и он утверждал отдельно от очевидного ...

Недостатки могут включать в себя:

Последствия для производительности Оптимизатор запросов использует размер поля для определения наиболее эффективного плана выполнения

"1. Распределение пространства в extends и страницах базы данных является гибким. Таким образом, при добавлении информации в поле с помощью update ваша база данных должна будет создать указатель, если новые данные длиннее предыдущих вставленных. Файлы базы данных станут фрагментированными = снижение производительности практически во всем, от индекса до удаления, обновления и вставки. " http://sqlblogcasts.com/blogs/simons/archive/2006/02/28/Why-use-anything-but-varchar_2800_max_2900_.aspx

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

Здесь есть хорошая статья: http://searchsqlserver.techtarget.com/tip/1,289483,sid87_gci1098157,00.html

28 голосов
/ 08 июня 2009

Иногда вы хотите, чтобы тип данных придавал некоторый смысл данным в нем.

Скажем, например, у вас есть столбец, который на самом деле не должен быть длиннее, скажем, 20 символов. Если вы определите этот столбец как VARCHAR (MAX), какое-то мошенническое приложение может вставить в него длинную строку, и вы никогда не узнаете или не сможете предотвратить это.

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

23 голосов
/ 03 февраля 2016

На основании ссылки, приведенной в принятом ответе, представляется, что:

  1. 100 символов, сохраненных в поле nvarchar(MAX), будут сохранены, не отличаясь от 100 символов в поле nvarchar(100) - данные будут храниться в строке, и у вас не будет накладных расходов на чтение и запись данных. ряда ». Так что не беспокойтесь там.

  2. Если размер больше 4000, данные будут автоматически сохраняться вне строки, что вам и нужно. Так что никаких забот там тоже нет.

Однако ...

  1. Невозможно создать индекс для столбца nvarchar(MAX). Вы можете использовать полнотекстовое индексирование, но не можете создать индекс для столбца, чтобы повысить производительность запросов. Для меня это закрывает дело ... это определенный недостаток - всегда использовать nvarchar (MAX).

Вывод:

Если вам нужна некая «универсальная длина строки» во всей вашей базе данных, которая может быть проиндексирована и которая не будет тратить пространство и время доступа, вы можете использовать nvarchar(4000).

19 голосов
/ 30 сентября 2014

Я проверил несколько статей и нашел полезный тестовый скрипт из этого: http://www.sqlservercentral.com/Forums/Topic1480639-1292-1.aspx Затем изменил его, чтобы сравнить между NVARCHAR (10) и NVARCHAR (4000) против NVARCHAR (MAX), и я не вижу разницы в скорости при использовании указанных чисел, но при использовании MAX. Вы можете проверить самостоятельно. Надеюсь, что это поможет.

SET NOCOUNT ON;

--===== Test Variable Assignment 1,000,000 times using NVARCHAR(10)
DECLARE @SomeString NVARCHAR(10),
        @StartTime DATETIME;
--=====         
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='10', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
--===== Test Variable Assignment 1,000,000 times using NVARCHAR(4000)
DECLARE @SomeString NVARCHAR(4000),
        @StartTime DATETIME;
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='4000', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
--===== Test Variable Assignment 1,000,000 times using NVARCHAR(MAX)
DECLARE @SomeString NVARCHAR(MAX),
        @StartTime DATETIME;
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='MAX', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
12 голосов
/ 08 июня 2009

Думайте об этом как о еще одном уровне безопасности. Вы можете создать свою таблицу без взаимосвязей с внешними ключами - что совершенно правильно - и обеспечить существование связанных сущностей полностью на бизнес-уровне. Однако внешние ключи считаются хорошей практикой проектирования, поскольку они добавляют еще один уровень ограничений на случай, если что-то испортится на бизнес-уровне. То же самое касается ограничения размера поля и без использования varchar MAX.

8 голосов
/ 09 июня 2009

Причина НЕ использовать максимальные или текстовые поля в том, что вы не можете выполнить перестроение индексов в режиме онлайн , т. Е. REBUILD WITH ONLINE = ON даже с SQL Server Enterprise Edition.

4 голосов
/ 09 июня 2009

Задача базы данных - хранить данные, чтобы они могли использоваться предприятием. Частично сделать эти данные полезными, чтобы убедиться, что они значимы. Разрешение кому-либо вводить неограниченное количество символов для своего имени не гарантирует значимые данные.

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

4 голосов
/ 08 июня 2009

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

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

Хотя я понимаю, что есть некоторые поля, которые я бы определенно рассмотрел, используя varchar (max).

Интересно, что Документы MSDN довольно хорошо подводят итог:

Используйте varchar, когда размеры Записи данных столбца значительно различаются. Используйте varchar (max), когда размеры записи данных столбца значительно различаются, и размер может превышать 8000 байт.

Здесь есть интересная дискуссия по этому вопросу .

4 голосов
/ 29 сентября 2008

Единственная проблема, которую я обнаружил, заключалась в том, что мы разрабатываем наши приложения на SQL Server 2005, и в одном случае мы должны поддерживать SQL Server 2000. Я только что узнал, что трудный путь , который не поддерживает SQL Server 2000 не нравится опция MAX для varchar или nvarchar.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...