Используя МАКС. Текст или более конкретный, мелкий шрифт

22

Кто-то просматривал мой DDL-код для создания таблиц и предложил, когда они увидели, что я вижу использование VARCHAR(256)полей для текста, я ожидаю, что оно будет довольно маленьким, например, имя или что-то еще, что я всегда должен просто использовать VARCHAR(MAX)и связывать. Зачем использовать что-либо, кроме varchar (max ) . Я читал его, но он казался устаревшим, поскольку он был ориентирован на 2005 год, и, похоже, не дал никакого реального оправдания для выделения потенциально до 2 ГБ на строку во всех текстовых полях.

С точки зрения производительности, хранилища и т. Д. Как следует решить, использовать VARCHAR(MAX)ли более современный тип или более конкретный тип для современных версий SQL Server? (например, 2008, 2012, 2014)

Phrancis
источник

Ответы:

31

Должен ли я всегда использовать (n)varchar(max)для текстовых столбцов?

Нет.

Для SQL Server maxтипы данных следует указывать только тогда, когда альтернативы нет. Вместо этого следует выбрать правильный базовый тип ( varcharили nvarchar) и указать явную максимальную длину, соответствующую данным, которые будут сохранены.

Физическое хранилище идентично, независимо от того, указан столбец как varchar(n)или varchar(max), так что это не проблема.

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

Исчерпывающий список, вероятно, не практичен, но, помимо прочего, maxстолбцы:

особенности

  • Требовать отдельное ограничение для обеспечения максимальной длины
  • Не может быть ключом в индексе (поэтому также нет уникальных ограничений)
  • Может предотвратить онлайн DDL (включая перестроение индекса и добавление нового ненулевого столбца)
  • Как правило, не поддерживаются для более новых функций, например columnstore
  • См. Документацию по продукту для более специфических функций и ограничений. Общая закономерность заключается в том, что существуют неудобные ограничения и ограничения в отношении maxтипов данных. Не все ограничения и побочные эффекты задокументированы.

Спектакль

  • Требовать специальной обработки в исполнительном механизме, чтобы учесть потенциально очень большой размер. Как правило, это предполагает использование менее эффективного пути кода с интерфейсом потоковой передачи
  • Может иметь аналогичные непредвиденные последствия для внешнего кода (и других компонентов SQL Server, таких как SSIS), который также должен быть подготовлен для обработки данных размером до 2 ГБ.
  • Предполагается, что он имеет 4000 байтов в расчете на выделение памяти. Это может привести к чрезмерному резервированию памяти, что ограничивает параллелизм и вытесняет ценные индексы и страницы данных из кеш-памяти
  • Отключить несколько важных оптимизаций производительности
  • Может продлить продолжительность блокировки
  • Может помешать оптимизатору выбрать (не динамический) план поиска
  • Предотвращение вставки фильтров в сканирование и поиск в качестве остатка
  • Может увеличить давление и конкуренцию в базе данных tempdb (зависит от версии), поскольку переменные и параметры также могут быть напечатаны так, maxчтобы соответствовать определениям столбцов

Таким образом, существует так много тонких (и нежелательных) побочных эффектов ненужного использования maxспецификатора, что нет смысла делать это. Незначительное «удобство» использования одной декларации не является компенсацией.

Оцените каждый тип в контексте, используйте правильный базовый тип ( varcharили nvarchar) и разумную явную длину.

Дальнейшее чтение:

Пол Уайт говорит, что GoFundMonica
источник
8

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

Сама база данных не контролирует своих клиентов, и нельзя предполагать, что клиенты всегда будут безопасно вставлять пользовательский ввод - даже если база данных предназначена для использования только с приложением .net, которое использует Entity Framework для инкапсуляции транзакций и обеспечения параметризованных запросов. систематически используются, вы не можете знать, что это всегда будет так.

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

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

Матье Гиндон
источник
Вероятно, это называется «инъекция» (точнее, «инъекция SQL»).
Андрей М
@AndriyM да, по какой-то причине я думал об атаках с усечением SQL (MS, похоже, удалил ссылку, которую я добавил в закладки), но это в основном использует varchar(not-max)параметры, так что я как-то засунул рот себе в рот. Но да, SQL-инъекция будет применима здесь. Возможно, мне следует немного перефразировать этот ответ.
Матье Гиндон