web-dev-qa-db-fra.com

Utilisation de texte max ou plus spécifique, de type plus petit

Quelqu'un examinait mon code DDL pour créer des tables et suggéré, quand ils ont vu que j'ai vu à l'aide de VARCHAR(256) champs pour le texte, je m'attends à être assez petit, comme un prénom ou autre que je devrais Toujours Utilisez simplement VARCHAR(MAX) et liée Pourquoi utiliser quelque chose que VARCHAR (max) . Je l'ai lu mais cela semblait être daté, car il se concentrait sur 2005 et ne semblait pas offrir une justification réelle pour allouer potentiellement jusqu'à 2 Go par rangée sur tous les champs de texte.

À partir d'une performance, de stockage, etc. Standard, comment se dérouler peut-être de décider d'utiliser s'il faut utiliser VARCHAR(MAX) ou un type plus petit plus spécifique pour les versions modernes de SQL Server? (E.G., 2008, 2012, 2014)

22
Phrancis

Devrais-je toujours utiliser (n)varchar(max) Pour les colonnes de texte?

no.

Pour SQL Server, les types de données max ne doivent être spécifiés qu'en cas d'alternative. On devrait plutôt choisir le type de base correct (varchar ou nvarchar) et spécifier une longueur maximale explicite qui convient aux données à stocker.

Le stockage physique est identique à savoir si la colonne est saisie comme varchar(n) ou varchar(max), donc ce n'est pas la préoccupation.

Les raisons de non choisissent (n)varchar(max) Partout tournez autour des fonctionnalités, de planifier la qualité et des performances.

Une liste exhaustive n'est probablement pas pratique, mais entre autres, max colonnes:

Caractéristiques

  • Exiger une contrainte distincte pour appliquer une longueur maximale
  • Ne peut pas être une clé dans un index (donc pas de contraintes uniques non plus)
  • Peut empêcher la DDL en ligne (y compris les reconstructions de l'index et l'ajout d'une nouvelle colonne non nulle)
  • Ne sont généralement pas pris en charge pour les caractéristiques "plus récentes" par exemple colonne
  • Voir la documentation du produit pour des fonctionnalités et des limitations plus spécifiques. Le modèle général est qu'il existe des limitations et des restrictions gênantes autour des types de données max. Toutes les limitations et toutes les effets secondaires ne sont pas documentées.

Performance

  • Nécessitent une manipulation spéciale dans le moteur d'exécution, pour rendre compte de la taille potentiellement grande. En règle générale, cela implique d'utiliser un chemin de code moins efficace, avec une interface de streaming
  • Peut avoir des conséquences similaires imprévues pour le code externe (et d'autres composants SQL Server tels que SSIS), qui doivent également être préparé Pour gérer les données jusqu'à 2 Go de taille maximale
  • Sont supposés être 4000 octets de vastes calculs de subventions à la mémoire. Ceci est susceptible de conduire à une réservation de mémoire excessive, qui limite la concurrence et pousse des index de valeur et des pages de données hors de la mémoire cache
  • Désactiver plusieurs optimisations importantes de performance
  • Peut prolonger la durée de verrouillage
  • Peut empêcher l'optimiseur de choisir un plan (non dynamique) de recherche
  • Empêcher les filtres enfoncés dans des analyses et cherche comme un résidu
  • Peut augmenter la pression et la conflit de TEMPDB (la version dépendante), car les variables et les paramètres sont également susceptibles d'être saisis comme max pour correspondre aux définitions de la colonne.

En résumé, il y a tant d'effets secondaires subtils (et indésirables) d'utilisation inutilement utilisant le spécificateur max qu'il n'a aucun sens de le faire. La "commodité" mineure d'utiliser une seule déclaration n'est pas une sorte de compensation.

Évaluez chaque type dans le contexte, utilisez le type de base correct (varchar ou nvarchar) et une longueur explicite sensible.

En plus de lecture:

31
Paul White 9

Cela va lire comme une réponse d'une paranoïde, mais il n'y a pas seulement Considérations de stockage et de performance.

La base de données elle-même ne contrôle pas ses clients et les clients ne peuvent pas être supposés à insérer toujours en toute sécurité l'entrée de l'utilisateur - même si une base de données est conçue pour être utilisée uniquement avec une application .NET qui utilise une application d'entité pour encapsuler des transactions et assurer des requêtes paramétrées. sont systématiquement utilisés, vous ne pouvez pas SAVOIR que cela va toujours être le cas.

Je ne saurais pas exactement comment faire cela, mais en faisant tous les champs de texte varchar(max), si un client a tables de bobby Problèmes et/ou vos paramètres de procédures stockées sont également varchar(max), alors vous permettez à un attaquant de trouver une valeur de paramètre valide mais intelligemment pervers qui peut faire des choses que les clients ne sont pas censés faire - quoi que ce soit.

En limitant la longueur à ce que vous en fait besoin, vous n'êtes pas blindage vous-même de ces attaques intelligentes (je ne suis même pas sûre de ce qu'on appelle en fait, je me souviens juste de lire à ce sujet un moment de retour), mais vous ne dites pas "Allez-y, essayez de me donner un script de 2 Go à courir" non plus.

8
Mathieu Guindon