Есть ли недостатки при использовании nvarchar (MAX)?

342

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

stucampbell
источник
1
Я просто не понимаю, почему вы хотите, чтобы кто-то вводил имя более 8000 символов.
DForck42
2
Та же логика может быть применена к языкам программирования. Почему бы не вернуться к старому варианту VB6 для всех наших данных? Я не думаю, что наличие чеков и противовесов в более чем одном месте обязательно плохо.
Мэтт Спрэдли
1
Проверьте это: stackoverflow.com/questions/2009694/…
Акира Ямамото
10
Ваше обновление должно быть собственным ответом на этот вопрос.
Иоганн
ответ на вопрос перешел к правильному ответу, поскольку первоначальный автор этого не сделал. stackoverflow.com/a/35177895/10245 Я полагаю, 7 лет достаточно времени :-)
Тим Абелл

Ответы:

153

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

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

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

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

Дэвид Крепс
источник
2
Так должен ли вопрос быть, есть ли разница между использованием N / VARCHAR (MAX) и N / TEXT?
Неразрезанный
18
Если я правильно помню, разве они не хранятся вне строки, если размер превышает 8 КБ?
Сэм Шутте
79
Я прочитал ответ как "нет, нет недостатка в использовании N/VARCHAR(MAX)", потому что есть дополнительная обработка ", только если размер превышает 8000". Таким образом, вы несете расходы только при необходимости , и ваша база данных менее ограничительна . Я читаю это неправильно? Похоже, что вы почти всегда хотите, N/VARCHAR(MAX)а не N/VARCHAR(1-8000)...
Кент Boogaart
1
Неработающая ссылка выше - рабочая ссылка на вопрос в MSDN - social.msdn.microsoft.com/Forums/en-US/sqlgetstarted/thread/…
Jagd
68
К сожалению, у этого ответа есть ряд проблем. Это делает границу 8 КБ похожей на магическое число, это не так, значение выталкивается из строки на основе множества факторов, в том числе sp_tableoptions: msdn.microsoft.com/en-us/library/ms173530.aspx . Типы VARCHAR (255) также могут быть вытолкнуты из строки, упомянутые «накладные расходы» могут быть точно такими же для MAX и 255. Он сравнивает типы MAX с типами TEXT, когда они различаются, как это происходит (совершенно другой API для манипулирования, другое хранилище и т. д.). В нем не упоминаются реальные различия: нет индекса, нет онлайн-операций над типами MAX
Remus Rusanu
50

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

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

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

«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

alexmac
источник
4
+1 За интеграцию и безопасность. Это оригинальный угол, который нужно учитывать, когда большинство других ответов говорят о производительности. В связи с последствиями интеграции любые инструменты (такие как составители отчетов или дизайнеры форм), которые используют метаданные для обеспечения разумных размеров элементов управления по умолчанию, потребовали бы гораздо больше работы, если бы использовались все столбцы varchar(max).
Разочарован
Интеграция с базой данных - это самая смешная вещь, которую я знаю. Если это просто импорт, то вы можете проверить данные раньше с помощью функции LEN.
Максим
30

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

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

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

Тем не мение...

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

Вывод:

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

Тим Абелл
источник
1
К вашему сведению, это была правка, добавленная к первоначальному вопросу, который должен был быть опубликован в качестве ответа
Тим Абелл
1
Спасибо, для меня это окончательный ответ. Я спрашивал себя так же - почему бы не использовать nvarchar(max)все время - как stringв C #? - но пункт 3) (вопрос индекса) дает ответ.
Полиция SQL
1
Добавлена ​​правка. В качестве разновидности «универсальной длины строки» вы всегда можете использоватьnvarchar(4000)
SQL Police
@SQLGeorge Посмотрите этот превосходный ответ Мартина Смита о влиянии на производительность запросов объявления столбцов шире, чем когда бы то ни было
billinkc
@billinkc Спасибо, это отличная статья. Итак, размер действительно влияет на производительность. Я буду редактировать ответ снова.
Полиция SQL
28

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

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

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

Билл Карвин
источник
9
Я согласен с этим и некоторыми другими комментариями, но я по-прежнему утверждаю, что это ответственность бизнес-уровня. К тому времени, когда он достигает уровня базы данных, он должен приветствовать и сохранить значение, независимо от того, как долго это будет смешно. Я думаю, что на самом деле играет здесь, то, что, по моему мнению, примерно в 90% случаев, когда разработчик указывает varchar (255), его намерение на самом деле не 255 символов, а какое-то неуказанное среднее значение длины. И учитывая компромисс между необоснованно большими значениями в моей базе данных и непредвиденными исключениями, я возьму большие значения.
Крис Б. Беренс
4
Если они указывают VARCHAR (255) для указания некоторой неизвестной длины, то это их вина в том, что они неправильно исследовали то, что они проектируют. Решение для разработчика, чтобы сделать свою работу, а не для базы данных, чтобы позволить необоснованные значения.
Том Х
10
не полезно для автора. он явно исключил этот вопрос, на который вы дали ответ.
USR
6
@ Крис Б. Беренс: я не согласен; схема базы данных является частью бизнес-логики. Выбор таблиц, отношений, полей и типов данных - все это бизнес-логика - и стоит использовать СУБД для обеспечения соблюдения правил этой бизнес-логики. По одной причине, очень редко, когда есть только один уровень приложений, обращающийся к базе данных; например, у вас могут быть инструменты импорта и извлечения данных, которые обходят основной бизнес-уровень, а это означает, что вам действительно нужна БД для обеспечения соблюдения правил.
Винс Боудрен
1
Если вы не нуждаетесь в длинных строках или даже не хотите, чтобы они хранились, тогда лучше применить смысл в данных. Например, если вы сохраняете поле PostCode, вы позволите кому-то ввести сотни или тысячи символов, если оно должно быть не более 10, скажем. - максимальный размер должен быть проверен на всех уровнях: клиент, бизнес-уровень и база данных. При использовании подхода Model First, такого как C # и Entity Framework, вы можете определить максимальный размер в модели и применить его к базе данных, бизнес-логике и проверке клиента (с помощью проверки jquery). Используйте только nvarchar (max), если это действительно необходимо
Peter Kerr
21

Я проверил некоторые статьи и нашел полезный тестовый скрипт из этого: 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
Qmaster
источник
4
Это интересно. На моей коробке кажется, что MAX в 4 раза медленнее.
Stucampbell
4
Новые результаты в SQL Server 2012: 10 в два раза медленнее, чем 4k, а MAX в 5,5 раз медленнее, чем 4k.
Кассандрад
1
Большую часть времени составляет неявное приведение от varchar к nvarchar (max). Попробуйте это: DECLARE \ @SomeString NVARCHAR (MAX), \ @abc NVARCHAR (max) = N'ABC ', \ @StartTime DATETIME; SELECT @startTime = GETDATE (); ВЫБЕРИТЕ ТОП 1000000 \ @SomeString = \ @abc FROM master.sys.all_columns ac1, master.sys.all_columns ac2; SELECT testTime = 'MAX', Duration = DATEDIFF (мс, \ @ StartTime, GETDATE ()); Пришлось вставить \ перед переменными, чтобы получить его к публикации.
Кваси
4
SQL Server 2014 на SSD: 150, 156, 716 (10, 4000, MAX).
Максим
2
Спасибо за добавление некоторых реальных чисел в это обсуждение. Мы часто забываем, что создание тестового примера - это самый быстрый способ понять.
Дэвид C
13

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

Alex
источник
8

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

Ник Кавадиас
источник
1
Это же ограничение действует для типа поля TEXT, поэтому вы все равно должны использовать VARCHAR (MAX) вместо TEXT.
Будет ли бритва
из-за этого мы не смогли перестроить наш кластерный индекс. нам потребовалось много дискового пространства, пока мы не смогли извлечь столбец в его собственную таблицу (мы не могли позволить себе блокировать таблицу более 7 секунд)
Choco Smith
4

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

mattruma
источник
2
Так почему бы просто не развивать наименьший общий знаменатель?
Бинки
4

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

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

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

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

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

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

RichardOD
источник
2
Для таких вещей, как телефонные номера, я был бы гораздо более согласен использовать поле char вместо varchar. Пока вы поддерживаете стандарт в своем хранилище и вам не нужно беспокоиться о телефонных номерах из разных стран, вам никогда не понадобится переменное поле для чего-то вроде номера телефона (10 без какого-либо форматирования) или почтового индекса (5 или 9-10, если вы добавите последние четыре цифры) и т. д.
TheTXI
Я имел в виду номера телефонов, которые могут различаться по длине. Возможно, я должен поставить это в ответ. Все, что имеет фиксированную длину, я бы использовал поле char.
RichardOD
Или, возможно, я должен был сказать в своем комментарии nchar или char. :-)
RichardOD
2
Количество символов в телефонном номере в значительной степени является бизнес-требованием. Если вам необходимо хранить код международного стандарта вместе с номером, он может быть больше 10. Или в какой-то части мира может быть более 10 цифр для номера телефона. Представьте себе случай перехода IPV4 в IPV6. Никто не стал бы утверждать, что нам нужно более 12 цифр в старые добрые времена IPV4. Это может не сработать, если IPV6 станет распространенным. Это опять-таки изменение бизнес-правила в течение определенного периода времени. Как говорится, перемены - это единственная постоянная вещь, которую мы можем ожидать :)
Карандашный лист
2
Будьте осторожны, предполагая, что вы знаете, сколько символов может быть в поле телефонного номера или какими они будут. Если система не использует эти данные для фактического набора (в этом случае вы должны быть строгими в отношении форматов), то пользователь может законно поместить туда неожиданно длинные строки, например, «0123 456 78910, попросить прием для расширения 45, а затем передать Джеймсу».
Винс Боудрен
4

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

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

Том Х
источник
6
IMO, ограничения длины данных основаны исключительно на бизнес-правилах, которые могут меняться с течением времени по мере роста приложения. Изменить бизнес-правила в бизнес-логике проще, чем на уровне БД. Итак, я думаю, что база данных должна быть достаточно гибкой и не должна быть привязана к бизнес-правилам, таким как максимально допустимая длина имени, которая очень сильно зависит от той части мира, в которой вы живете.
Карандашный лист
3

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

TheTXI
источник
Я думаю, что невысказанное предположение со стороны ОП состоит в том, что он полностью имеет дело с экземплярами 2005+ и что его приложениям не нужно будет работать в 2000 (или, более ранних) версиях. Я полностью согласен с вами, если есть необходимость поддерживать более старые версии, хотя!
Джон Руди
Джон Руди: Я полагаю, что это так, я просто знаю, что сам столкнулся с этими препятствиями, когда я не думал, что собираюсь.
TheTXI
На самом деле это распространенная проблема, связанная с современными технологиями, из-за SQL CE 4, который не поддерживает типы столбцов MAX, поэтому совместимость становится проблемой.
JohnC
3

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

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

Гарри Купер
источник
2

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

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

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

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

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

WWC
источник
1

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

Кейд Ру
источник
1

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

Тони
источник
1

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

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

Мэтт Спрэдли
источник
1

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

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;
Kvasi
источник
0

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

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

orip
источник
1
Это похоже на то, что вы не должны иметь проверочных ограничений, чтобы гарантировать, что возраст человека не является отрицательным числом.
Джонатан Аллен
Я вижу разницу между правильностью данных и оптимизацией производительности.
orip
0

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

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

это

            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]
Карлос Мартини
источник
3
Я бы предпочел, чтобы бизнес-логика говорила, что название компании может содержать не более 50 символов, а не полагаться на таблицу базы данных для этой информации.
Хан
Я согласен с Джеффом. Я не думаю, что магазин постоянства - правильное место для определения ваших бизнес-правил. А в многоуровневой архитектуре ваш пользовательский интерфейс даже не знает о слое постоянства.
Stucampbell
Если, конечно, вы не используете значение, ограниченное конкретным размером, например, код ISO для страны.
Бен
2
Какое это имеет отношение к таблице def? Вы все еще можете иметь бизнес-логику. Я думаю, что ваша точка зрения не имеет смысла в том, что касается дизайна таблицы. Если вы все еще хотите создать какое-то определение в своем бизнес-уровне, пусть будет так. Хотя то, что имеет больше смысла, в любом случае использует хранимый процесс на бизнес-уровне; не таблица определения ??
Карлос Мартини
1
Это кажется непопулярным, но я согласен с Карлосом: если БД устанавливает максимальный размер, тогда вы можете чувствовать себя комфортно во всех слоях, которые вы строите поверх него, с чем вам, вероятно, придется иметь дело. Это особенно важно, если у вас есть несколько систем записи в вашу базу данных.
Тим Абелл
0

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

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

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

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

tsundoku
источник
0

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

хорошо, вот мои чувства просто по вопросу бизнеса и логики уровня данных. Это зависит от того, если ваша БД является общим ресурсом между системами, которые разделяют бизнес-логику, то, конечно, кажется естественным местом для применения такой логики, но это НЕ ЛУЧШИЙ способ сделать это, ЛУЧШИЙ способ - предоставить API, это позволяет проверяемое взаимодействие и сохраняющее бизнес-логику там, где оно принадлежит, оно разъединяет системы, оно разъединяет ваши уровни внутри системы. Однако, если предполагается, что ваша база данных обслуживает только одно приложение, тогда давайте рассудимся, что же это сейчас? дизайн на данный момент. Если и когда такой доступ необходим, предоставьте API для этих данных.

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

Стивен Уипп
источник
-1

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

Дэн Гольдштейн
источник
5
-1. Строка длиной 100, хранящаяся в nvarchar(max)столбце, занимает не больше места на диске, чем в nvarchar(100)столбце.
Мартин Смит
То, что вы описываете, правильно, если размер хранимых данных больше, но этот вопрос касается того, влияет ли тип данных на производительность или другие соображения.
-2

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

pappes
источник