Dans SQL Server 2005, y a-t-il des inconvénients à rendre tous les champs de caractères nvarchar (MAX) plutôt que de spécifier une longueur explicitement, par exemple nvarchar (255)? (Mis à part l'évident que vous n'êtes pas en mesure de limiter la longueur du champ au niveau de la base de données)
sql
sql-server
sql-server-2005
stucampbell
la source
la source
Réponses:
La même question a été posée sur les forums MSDN:
De la publication d'origine (beaucoup plus d'informations là-bas):
la source
N/VARCHAR(MAX)
" car il y a un traitement supplémentaire "uniquement si la taille dépasse 8000". Ainsi, vous n'encourez le coût que lorsque cela est nécessaire et votre base de données est moins restrictive . Suis-je en train de mal lire? On dirait que vous voudriez presque toujoursN/VARCHAR(MAX)
plutôt queN/VARCHAR(1-8000)
...sp_tableoptions
: msdn.microsoft.com/en-us/library/ms173530.aspx . Les types VARCHAR (255) peuvent également être b poussés hors de la ligne, le "surcoût" mentionné peut être exactement le même pour MAX et 255. Il compare les types MAX aux types TEXT, lorsqu'ils sont distincts au fur et à mesure (API complètement différente à manipuler, stockage différent, etc.). Il ne mentionne pas les différences réelles: pas d'index, pas d'opérations en ligne sur les types MAXC'est une bonne question et il a déclaré en dehors de l'évidence ...
Les inconvénients pourraient inclure:
Conséquences sur les performances L'optimiseur de requêtes utilise la taille du champ pour déterminer le plan d'exécution le plus efficace
"1. L'allocation d'espace dans les extensions et les pages de la base de données est flexible. Ainsi, lors de l'ajout d'informations au champ à l'aide de la mise à jour, votre base de données devra créer un pointeur si les nouvelles données sont plus longues que les précédentes insérées. devenir fragmenté = baisse des performances dans presque tout, de l'index à la suppression, à la mise à jour et aux insertions. " http://sqlblogcasts.com/blogs/simons/archive/2006/02/28/Why-use-anything-but-varchar_2800_max_2900_.aspx
Implications de l'intégration - difficile pour les autres systèmes de savoir comment s'intégrer à votre base de données Croissance imprévisible des données Problèmes de sécurité possibles, par exemple, vous pourriez planter un système en occupant tout l'espace disque
Il y a un bon article ici: http://searchsqlserver.techtarget.com/tip/1,289483,sid87_gci1098157,00.html
la source
varchar(max)
.Sur la base du lien fourni dans la réponse acceptée, il apparaît que:
100 caractères stockés dans un
nvarchar(MAX)
champ ne seront pas différents de 100 caractères dans unnvarchar(100)
champ - les données seront stockées en ligne et vous n'aurez pas la surcharge de lecture et d'écriture des données `` hors ligne ''. Donc pas de soucis là-bas.Si la taille est supérieure à 4000, les données seront automatiquement stockées «hors ligne», ce que vous souhaitez. Donc pas de soucis non plus.
Toutefois...
nvarchar(MAX)
colonne. Vous pouvez utiliser l'indexation de texte intégral, mais vous ne pouvez pas créer d'index sur la colonne pour améliorer les performances des requêtes. Pour moi, cela scelle l'affaire ... c'est un inconvénient certain de toujours utiliser nvarchar (MAX).Conclusion:
Si vous voulez une sorte de "longueur de chaîne universelle" dans toute votre base de données, qui peut être indexée et qui ne gaspillera pas d'espace et de temps d'accès, alors vous pourriez l'utiliser
nvarchar(4000)
.la source
nvarchar(max)
tout le temps - commestring
en C #? - mais le point 3) (le problème de l'indice) donne la réponse.nvarchar(4000)
Parfois, vous voulez que le type de données applique un certain sens aux données qu'il contient.
Supposons, par exemple, que vous ayez une colonne qui ne devrait pas être plus longue que, disons, 20 caractères. Si vous définissez cette colonne comme VARCHAR (MAX), une application malveillante pourrait y insérer une longue chaîne et vous ne le sauriez jamais, ou vous n'auriez aucun moyen de l'empêcher.
La prochaine fois que votre application utilisera cette chaîne, en supposant que la longueur de la chaîne est modeste et raisonnable pour le domaine qu'elle représente, vous obtiendrez un résultat imprévisible et déroutant.
la source
J'ai vérifié certains articles et trouvé un script de test utile à partir de ceci: http://www.sqlservercentral.com/Forums/Topic1480639-1292-1.aspx Puis je l'ai changé pour comparer entre NVARCHAR (10) vs NVARCHAR (4000) vs NVARCHAR (MAX ) et je ne trouve pas de différence de vitesse lors de l'utilisation de nombres spécifiés mais lors de l'utilisation de MAX. Vous pouvez tester par vous-même. J'espère que cette aide.
la source
Considérez-le comme un autre niveau de sécurité. Vous pouvez concevoir votre table sans relations de clés étrangères - parfaitement valides - et garantir l'existence d'entités associées entièrement sur la couche métier. Cependant, les clés étrangères sont considérées comme de bonnes pratiques de conception car elles ajoutent un autre niveau de contrainte au cas où quelque chose gâcherait sur la couche métier. Il en va de même pour la limitation de la taille du champ et ne pas utiliser varchar MAX.
la source
Une raison de NE PAS utiliser les champs max ou texte est que vous ne pouvez pas effectuer de reconstructions d'index en ligne, c'est-à-dire RECONSTRUIRE AVEC ONLINE = ON même avec SQL Server Enterprise Edition.
la source
Le seul problème que j'ai trouvé est que nous développons nos applications sur SQL Server 2005, et dans un cas, nous devons prendre en charge SQL Server 2000. Je viens d'apprendre, à la dure, que SQL Server 2000 n'aime pas l'option MAX pour varchar ou nvarchar.
la source
Mauvaise idée quand vous savez que le champ sera dans une plage définie - 5 à 10 caractères par exemple. Je pense que je n'utiliserais max que si je n'étais pas sûr de la longueur. Par exemple, un numéro de téléphone ne dépassera jamais un certain nombre de caractères.
Pouvez-vous honnêtement dire que vous n'êtes pas sûr de la longueur approximative requise pour chaque champ de votre table?
Je comprends votre point cependant, il y a certains domaines que j'envisagerais certainement d'utiliser varchar (max).
Fait intéressant, les documents MSDN le résument assez bien:
Il y a une discussion intéressante sur la question ici .
la source
Le travail de la base de données consiste à stocker des données afin qu'elles puissent être utilisées par l'entreprise. Une partie de rendre ces données utiles consiste à s'assurer qu'elles sont significatives. Permettre à quelqu'un d'entrer un nombre illimité de caractères pour son prénom ne garantit pas des données significatives.
Construire ces contraintes dans la couche métier est une bonne idée, mais cela ne garantit pas que la base de données restera intacte. La seule façon de garantir que les règles de données ne sont pas violées est de les appliquer au niveau le plus bas possible dans la base de données.
la source
Un problème est que si vous devez travailler avec plusieurs versions de SQL Server, le MAX ne fonctionnera pas toujours. Donc, si vous travaillez avec des bases de données héritées ou toute autre situation impliquant plusieurs versions, vous feriez mieux d'être très prudent.
la source
Comme cela a été souligné ci-dessus, il s'agit principalement d'un compromis entre stockage et performances. Du moins dans la plupart des cas.
Cependant, il existe au moins un autre facteur à prendre en compte lors du choix de n / varchar (Max) sur n / varchar (n). Les données vont-elles être indexées (comme, par exemple, un nom de famille)? Étant donné que la définition MAX est considérée comme un LOB, tout ce qui est défini comme MAX n'est pas disponible pour l'indexation. et sans index, toute recherche impliquant les données comme prédicat dans une clause WHERE va être forcée dans une analyse de table complète, ce qui est la pire performance que vous puissiez obtenir pour les recherches de données.
la source
1) Le serveur SQL devra utiliser plus de ressources (mémoire allouée et temps processeur) pour traiter nvarchar (max) vs nvarchar (n) où n est un nombre spécifique au champ.
2) Qu'est-ce que cela signifie en termes de performances?
Sur SQL Server 2005, j'ai interrogé 13 000 lignes de données à partir d'une table avec 15 colonnes nvarchar (max). J'ai chronométré les requêtes à plusieurs reprises, puis j'ai changé les colonnes en nvarchar (255) ou moins.
Les requêtes avant l'optimisation étaient en moyenne de 2,0858 secondes. Les requêtes après la modification sont revenues en moyenne de 1,90 seconde. Cela représente environ 184 millisecondes d'amélioration de la requête select * de base. C'est une amélioration de 8,8%.
3) Mes résultats concordent avec quelques autres articles qui indiquaient qu'il y avait une différence de performance. Selon votre base de données et la requête, le pourcentage d'amélioration peut varier. Si vous n'avez pas beaucoup d'utilisateurs simultanés ou très nombreux enregistrements, la différence de performances ne sera pas un problème pour vous. Cependant, la différence de performances augmentera à mesure que davantage d'enregistrements et d'utilisateurs simultanés augmenteront.
la source
J'avais un udf qui rembourrait les chaînes et mettait la sortie sur varchar (max). Si celui-ci était utilisé directement au lieu de revenir à la taille appropriée pour la colonne à ajuster, les performances étaient très médiocres. J'ai fini par mettre l'udf à une longueur arbitraire avec une grosse note au lieu de compter sur tous les appelants de l'udf pour recréer la chaîne à une taille plus petite.
la source
prise en charge du système hérité. Si vous avez un système qui utilise les données et qu'il devrait être d'une certaine longueur, la base de données est un bon endroit pour appliquer la longueur. Ce n'est pas idéal, mais les anciens systèmes ne sont pas toujours idéaux. = P
la source
Si toutes les données d'une ligne (pour toutes les colonnes) ne prennent jamais raisonnablement 8 000 caractères ou moins, la conception de la couche de données doit appliquer cela.
Le moteur de base de données est beaucoup plus efficace en gardant tout hors du stockage d'objets blob. Plus vous pouvez restreindre une rangée, mieux c'est. Plus vous pouvez entasser de lignes dans une page, mieux c'est. La base de données fonctionne simplement mieux lorsqu'elle doit accéder à moins de pages.
la source
Mes tests ont montré qu'il existe des différences lors de la sélection.
la source
Lien intéressant: Pourquoi utiliser un VARCHAR quand vous pouvez utiliser TEXT?
Il s'agit de PostgreSQL et MySQL, donc l'analyse des performances est différente, mais la logique de "l'explicitness" tient toujours: pourquoi vous forcer à toujours vous soucier de quelque chose qui est pertinent un petit pourcentage du temps? Si vous avez enregistré une adresse e-mail dans une variable, vous utiliseriez une «chaîne» et non une «chaîne limitée à 80 caractères».
la source
Le principal inconvénient que je peux voir est que disons que vous avez ceci:
Laquelle vous donne le plus d'informations sur les données nécessaires à l'interface utilisateur?
Ce
Ou ca?
la source
Un inconvénient est que vous concevrez autour d'une variable imprévisible et que vous ignorerez probablement au lieu de tirer parti de la structure de données SQL Server interne, progressivement constituée de lignes, de pages et d'extensions.
Ce qui me fait penser à l'alignement de la structure des données en C, et qu'être conscient de l'alignement est généralement considéré comme une bonne chose (TM). Idée similaire, contexte différent.
Page MSDN pour Pages et extensions
Page MSDN pour les données de dépassement de ligne
la source
J'ai d'abord pensé à cela, mais j'ai réfléchi à nouveau. Il y a des implications en termes de performances, mais cela sert également de forme de documentation pour avoir une idée de la taille réelle des champs. Et il s'applique lorsque cette base de données se trouve dans un écosystème plus vaste. À mon avis, la clé est d'être permissif mais uniquement dans des limites raisonnables.
ok, voici mes sentiments simplement sur la question de la logique métier et de la couche de données. Cela dépend, si votre base de données est une ressource partagée entre des systèmes qui partagent la logique métier, alors bien sûr, cela semble un endroit naturel pour appliquer une telle logique, mais ce n'est pas la MEILLEURE façon de le faire, la MEILLEURE façon est de fournir une API, cela permet l'interaction à tester et maintient la logique métier là où elle appartient, elle maintient les systèmes découplés, elle maintient vos niveaux au sein d'un système découplé. Si toutefois votre base de données est censée ne servir qu'une seule application, laissez réfléchir AGILE, qu'est-ce qui est vrai maintenant? conception pour l'instant. Si et quand un tel accès est nécessaire, fournissez une API à ces données.
bien sûr, ce n'est que l'idéal, si vous travaillez avec un système existant, il est probable que vous devrez le faire différemment au moins à court terme.
la source
Cela entraînera un problème de performances, bien qu'il ne puisse jamais causer de problèmes réels si votre base de données est petite. Chaque enregistrement occupera plus d'espace sur le disque dur et la base de données devra lire plus de secteurs du disque si vous recherchez dans de nombreux enregistrements à la fois. Par exemple, un petit enregistrement peut contenir 50 à un secteur et un grand enregistrement peut en contenir 5. Vous devez lire 10 fois plus de données à partir du disque en utilisant le grand enregistrement.
la source
nvarchar(max)
colonne ne prend pas plus d'espace disque que si elle se trouvait dans unenvarchar(100)
colonne.Cela rendra la conception de l'écran plus difficile, car vous ne pourrez plus prédire la largeur de vos contrôles.
la source