Существуют ли какие-либо неудобства для использования nvarchar (MAX)?

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

Ответ 1

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

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

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

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

Ответ 2

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

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

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

"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

Ответ 3

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

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

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

Ответ 4

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

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

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

Однако...

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

Вывод:

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

Ответ 5

Я проверил некоторые статьи и нашел полезный тест script из этого: 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

Ответ 6

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

Ответ 7

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

Ответ 8

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

Ответ 9

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

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

Я понимаю, что есть некоторые поля, которые я бы, конечно же, рассмотрел с помощью varchar (max).

Интересно, что MSDN docs подводит итог:

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

Здесь интересное обсуждение здесь.

Ответ 10

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

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

Ответ 11

Одна из проблем заключается в том, что если вам приходится работать с несколькими версиями SQL Server, MAX не всегда будет работать. Поэтому, если вы работаете с устаревшей БД или любой другой ситуацией, которая включает несколько версий, вы должны быть очень осторожны.

Ответ 12

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

Однако существует, по крайней мере, еще один фактор, который следует учитывать при выборе n/varchar (Max) над n/varchar (n). Собираются ли данные индексироваться (например, фамилия)? Поскольку определение MAX считается LOB, то для индексирования недоступно все, что определено как MAX. и без индекса, любой поиск, включающий данные в качестве предиката в предложении WHERE, будет принудительно запущен в сканирование Full Table, что является наихудшей производительностью, которую вы можете получить для поиска данных.

Ответ 13

1) SQL-серверу придется использовать больше ресурсов (выделенная память и время процессора) при работе с nvarchar (max) vs nvarchar (n), где n - число, специфичное для этого поля.

2) Что это означает в отношении производительности?

В SQL Server 2005 я запросил 13 000 строк данных из таблицы с 15 столбцами nvarchar (max). Я много раз менял запросы, а затем менял столбцы на nvarchar (255) или меньше.

Запросы до оптимизации, усредненные в 2,0858 секунд. Запросы после изменения возвращаются в среднем на 1,90 секунды. Это было около 184 миллисекунд улучшения основного запроса select *. Это улучшение на 8,8%.

3) Мои результаты согласуются с несколькими другими статьями, в которых указано, что разница в производительности. В зависимости от вашей базы данных и запроса процент улучшения может отличаться. Если у вас не так много одновременных пользователей или очень много записей, разница в производительности не будет проблемой для вас. Однако разница в производительности будет возрастать по мере увеличения количества записей и одновременных пользователей.

Ответ 14

У меня был udf, который заполнял строки и помещал вывод в varchar (max). Если бы это использовалось напрямую, а не возвращалось к соответствующему размеру для корректируемого столбца, производительность была очень низкой. Я закончил размещение udf произвольной длины с большой записью вместо того, чтобы полагаться на всех вызывающих лиц udf, чтобы перевести строку на меньший размер.

Ответ 15

Интересная ссылка: Зачем использовать VARCHAR, если вы можете использовать TEXT?

Это о PostgreSQL и MySQL, поэтому анализ производительности отличается, но логика "очевидности" по-прежнему сохраняется: зачем заставлять себя всегда беспокоиться о чем-то, что имеет отношение к небольшому проценту времени? Если вы сохранили адрес электронной почты для переменной, вы должны использовать строку "строка", а не "строка, ограниченная 80 символами".

Ответ 16

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

Ответ 17

Если все данные в строке (для всех столбцов) никогда не будут разумно принимать 8000 или менее символов, тогда проект на уровне данных должен обеспечить это.

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

Ответ 18

Мои тесты показали, что при выборе есть различия.

CREATE TABLE t4000 (a NVARCHAR(4000) NULL);

CREATE TABLE tmax (a NVARCHAR(MAX) NULL);

DECLARE @abc4 NVARCHAR(4000) = N'ABC';

INSERT INTO t4000
SELECT TOP 1000000 @abc4
    FROM
    master.sys.all_columns ac1,
    master.sys.all_columns ac2;

DECLARE @abc NVARCHAR(MAX) = N'ABC';

INSERT INTO tmax
SELECT TOP 1000000 @abc
    FROM
    master.sys.all_columns ac1,
    master.sys.all_columns ac2;

SET STATISTICS TIME ON;
SET STATISTICS IO ON;

SELECT * FROM dbo.t4000;
SELECT * FROM dbo.tmax;

Ответ 19

Главный недостаток, который я вижу, - это сказать, что у вас есть это:

Какой из них дает вам наибольшую информацию о данных, необходимых для пользовательского интерфейса?

Это

            CREATE TABLE [dbo].[BusData](
                [ID] [int] IDENTITY(1,1) NOT NULL,
                [RecordId] [nvarchar](MAX) NULL,
                [CompanyName] [nvarchar](MAX) NOT NULL,
                [FirstName] [nvarchar](MAX) NOT NULL,
                [LastName] [nvarchar](MAX) NOT NULL,
                [ADDRESS] [nvarchar](MAX) NOT NULL,
                [CITY] [nvarchar](MAX) NOT NULL,
                [County] [nvarchar](MAX) NOT NULL,
                [STATE] [nvarchar](MAX) NOT NULL,
                [ZIP] [nvarchar](MAX) NOT NULL,
                [PHONE] [nvarchar](MAX) NOT NULL,
                [COUNTRY] [nvarchar](MAX) NOT NULL,
                [NPA] [nvarchar](MAX) NULL,
                [NXX] [nvarchar](MAX) NULL,
                [XXXX] [nvarchar](MAX) NULL,
                [CurrentRecord] [nvarchar](MAX) NULL,
                [TotalCount] [nvarchar](MAX) NULL,
                [Status] [int] NOT NULL,
                [ChangeDate] [datetime] NOT NULL
            ) ON [PRIMARY]

Или это?

            CREATE TABLE [dbo].[BusData](
                [ID] [int] IDENTITY(1,1) NOT NULL,
                [RecordId] [nvarchar](50) NULL,
                [CompanyName] [nvarchar](50) NOT NULL,
                [FirstName] [nvarchar](50) NOT NULL,
                [LastName] [nvarchar](50) NOT NULL,
                [ADDRESS] [nvarchar](50) NOT NULL,
                [CITY] [nvarchar](50) NOT NULL,
                [County] [nvarchar](50) NOT NULL,
                [STATE] [nvarchar](2) NOT NULL,
                [ZIP] [nvarchar](16) NOT NULL,
                [PHONE] [nvarchar](18) NOT NULL,
                [COUNTRY] [nvarchar](50) NOT NULL,
                [NPA] [nvarchar](3) NULL,
                [NXX] [nvarchar](3) NULL,
                [XXXX] [nvarchar](4) NULL,
                [CurrentRecord] [nvarchar](50) NULL,
                [TotalCount] [nvarchar](50) NULL,
                [Status] [int] NOT NULL,
                [ChangeDate] [datetime] NOT NULL
            ) ON [PRIMARY]

Ответ 20

Один из недостатков заключается в том, что вы будете разрабатывать вокруг непредсказуемой переменной, и вы, вероятно, проигнорируете вместо того, чтобы использовать внутреннюю структуру данных SQL Server, постепенно составляемую из строк, страниц и экстентов (Extent) с).

Что заставляет меня думать о выравнивании структуры данных в C, и что осознание выравнивания обычно считается хорошей вещью (TM). Подобная идея, другой контекст.

Страница MSDN для Страницы и экстенты

Страница MSDN для Данные переполнения строк

Ответ 21

Это вызовет проблему с производительностью, хотя она может никогда не вызвать никаких проблем, если ваша база данных невелика. Каждая запись занимает больше места на жестком диске, и в базе данных потребуется прочитать больше секторов диска, если вы просматриваете сразу множество записей. Например, небольшая запись может соответствовать 50 секторам, а большая запись может соответствовать 5. Вам нужно будет прочитать в 10 раз больше данных с диска, используя большую запись.

Ответ 22

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