Використання тексту MAX або більш конкретного, меншого типу


22

Хтось переглядав мій код DDL для створення таблиць і запропонував, коли побачив, що я бачу використання VARCHAR(256)полів для тексту, я очікую, що він буде досить маленьким, як ім’я чи що завгодно, що я завжди повинен просто використовувати VARCHAR(MAX)та пов’язати Навіщо використовувати що-небудь, крім varchar (макс ) . Я прочитав його, але, здавалося, датується, оскільки він зосереджувався на 2005 році, і, здається, не пропонує жодного реального обґрунтування виділення потенційно до 2 ГБ на рядок у всіх текстових полях.

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

Відповіді:


31

Чи слід завжди використовувати (n)varchar(max)для текстових стовпців?

Ні.

Для SQL Server maxтипи даних слід визначати лише тоді, коли немає альтернативи. Натомість слід вибрати правильний базовий тип ( varcharабо nvarchar) та вказати явну максимальну довжину, відповідну даним для зберігання.

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

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

Вичерпний список, мабуть, не практичний, але, серед іншого, maxстовпці:

Особливості

  • Потрібно окреме обмеження для забезпечення максимальної довжини
  • Не може бути ключем в індексі (тому немає і унікальних обмежень)
  • Може запобігти онлайн-DDL (включаючи відновлення індексу та додавання нового ненульового стовпця)
  • Як правило, не підтримуються новіші функції, наприклад, стовпчик
  • Детальніші функції та обмеження див. У документації на виріб. Загальна закономірність полягає в тому, що навколо maxтипів даних існують незручні обмеження та обмеження . Не всі обмеження та побічні ефекти документовані.

Продуктивність

  • Потрібна спеціальна керованість у двигуні виконання, щоб врахувати потенційно дуже великий розмір. Зазвичай це передбачає використання менш ефективного кодового шляху з потоковим інтерфейсом
  • Можуть мати подібні непередбачувані наслідки для зовнішнього коду (та інших компонентів SQL Server, таких як SSIS), який також повинен бути готовий для обробки даних розміром до 2 ГБ.
  • Передбачається, що ширина 4000 байт у розрахунках грант пам'яті. Це, ймовірно, призведе до надмірного резервування пам’яті, що обмежує паралельність, і витісняє цінні сторінки індексу та даних із кеш-пам’яті
  • Вимкніть кілька важливих оптимізацій продуктивності
  • Може продовжити тривалість блокування
  • Може перешкодити оптимізатору вибрати (нединамічний) план пошуку
  • Запобігайте заштовхуванню фільтрів і шукає залишки
  • Може збільшувати тиск та суперечки tempdb (залежно від версії), оскільки змінні та параметри також можуть бути набрані відповідно maxдо визначень стовпців

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

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

Подальше читання:


8

Це буде читатись як відповідь параноїда, але існують не лише міркування щодо зберігання та продуктивності.

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

Я б не знав, як саме це зробити, але, зробивши всі текстові поля varchar(max), якщо у клієнта є проблеми з таблицями Bobby та / або параметри ваших збережених процедур varchar(max), ви полегшите зловмиснику придумати дійсне, але розумно зле значення параметра, яке може робити те, чого клієнти не повинні робити - як би там не було.

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


Те, що це називається, ймовірно, "ін'єкція" ("SQL инжекция", точніше).
Андрій М

@AndriyM Так, я чомусь думав про атаки врізання SQL (MS, здається, зняв посилання, яке я заклав у закладки), але це, в основному, експлуатуючі varchar(not-max)параметри, тому я якось засунув ногу в рот тут. Але так, тут застосовується інжекція SQL. Можливо, я повинен трохи перефразувати цю відповідь.
Матьє Гіндон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.