Y a-t-il des inconvénients à toujours utiliser nvarchar (MAX)?

342

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)

stucampbell
la source
1
Je ne comprends pas pourquoi vous voudriez laisser quelqu'un entrer un nom de 8 000+ caractères.
DForck42
2
La même logique peut être appliquée aux langages de programmation. Pourquoi ne pas revenir à l'ancienne variante VB6 pour toutes nos données? Je ne pense pas que d'avoir des freins et contrepoids à plus d'un endroit soit nécessairement mauvais.
Matt Spradley
1
Vérifiez ceci: stackoverflow.com/questions/2009694/…
Akira Yamamoto
10
Votre mise à jour devrait être sa propre réponse à cette question.
Johann
la réponse à la question est passée à la bonne réponse, car l'auteur d'origine ne l'a pas fait. stackoverflow.com/a/35177895/10245 Je pense que 7 ans, c'est assez de temps :-)
Tim Abell

Réponses:

153

La même question a été posée sur les forums MSDN:

De la publication d'origine (beaucoup plus d'informations là-bas):

Lorsque vous stockez des données dans une colonne VARCHAR (N), les valeurs sont physiquement stockées de la même manière. Mais lorsque vous le stockez dans une colonne VARCHAR (MAX), derrière l'écran, les données sont traitées comme une valeur TEXT. Il y a donc un traitement supplémentaire nécessaire lors du traitement d'une valeur VARCHAR (MAX). (uniquement si la taille dépasse 8000)

VARCHAR (MAX) ou NVARCHAR (MAX) est considéré comme un «type de grande valeur». Les types de grande valeur sont généralement stockés «hors ligne». Cela signifie que la ligne de données aura un pointeur vers un autre emplacement où la `` grande valeur '' est stockée ...

David Kreps
la source
2
Alors, si la question est, y a-t-il une différence entre l'utilisation de N / VARCHAR (MAX) et N / TEXT?
non découpés
18
Si je me souviens bien, ne sont-ils pas stockés uniquement hors ligne si la taille dépasse 8k?
Sam Schutte
79
J'ai lu la réponse comme "non, il n'y a aucun inconvénient à utiliser 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 toujours N/VARCHAR(MAX)plutôt que N/VARCHAR(1-8000)...
Kent Boogaart
1
Lien mort ci-dessus - le lien de travail pour la question sur MSDN est social.msdn.microsoft.com/Forums/en-US/sqlgetstarted/thread/…
Jagd
68
Malheureusement, cette réponse pose un certain nombre de problèmes. Cela fait que la limite de 8k ressemble à un nombre magique, ce n'est pas vrai, la valeur est poussée hors de la ligne en fonction de plusieurs facteurs, notamment 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 MAX
Remus Rusanu
50

C'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

alexmac
la source
4
+1 Pour les implications d'intégration et de sécurité. Il s'agit d'un angle original à considérer lorsque la plupart des autres réponses parlent de performances. En ce qui concerne les implications d'intégration, tous les outils (tels que les rédacteurs de rapports ou les concepteurs de formulaires) qui utilisent des métadonnées pour fournir des tailles de contrôle par défaut raisonnables nécessiteraient beaucoup plus de travail à utiliser si toutes les colonnes l'étaient varchar(max).
Désillusionné le
L'intégration par base de données est la chose la plus ridicule que je sache. Si c'est juste importé une fois que vous pouvez vérifier les données avant par la fonction LEN.
Maxim
30

Sur la base du lien fourni dans la réponse acceptée, il apparaît que:

  1. 100 caractères stockés dans un nvarchar(MAX)champ ne seront pas différents de 100 caractères dans un nvarchar(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.

  2. 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...

  1. Vous ne pouvez pas créer d'index sur une 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).

Tim Abell
la source
1
fyi il s'agit d'une modification ajoutée à la question d'origine qui aurait dû être publiée comme réponse
Tim Abell
1
Merci, pour moi, c'est la réponse finale. Je me suis posé la même question - pourquoi ne pas utiliser nvarchar(max)tout le temps - comme stringen C #? - mais le point 3) (le problème de l'indice) donne la réponse.
SQL Police
1
Ajout d'une modification. Comme une sorte de "longueur de chaîne universelle", vous pouvez toujours utilisernvarchar(4000)
SQL Police
@SQLGeorge Voir cette excellente réponse de Martin Smith sur l'impact sur les performances des requêtes de déclaration de colonnes plus larges qu'elles ne le seront jamais
billinkc
@billinkc Merci, c'est un excellent article. OK, donc la taille affecte en effet la performance. Je modifierai à nouveau la réponse.
SQL Police
28

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.

Bill Karwin
la source
9
Je suis d'accord avec cela, et certains des autres commentaires, mais je maintiens toujours que cela relève de la responsabilité des entreprises. Au moment où il atteint le niveau de la base de données, il devrait claquer un salut et stocker la valeur, quelle que soit sa longueur ridicule. Je pense que ce qui est vraiment en jeu ici, c'est que je pense que 90% du temps lorsqu'un développeur spécifie varchar (255), son intention n'est pas vraiment 255 caractères, mais une valeur de longueur intermédiaire non spécifiée. Et étant donné le compromis entre des valeurs déraisonnablement grandes dans ma base de données et des exceptions imprévues, je prendrai les grandes valeurs.
Chris B. Behrens
4
S'ils spécifient VARCHAR (255) pour indiquer une longueur inconnue, c'est leur faute s'ils ne recherchent pas correctement ce qu'ils conçoivent. La solution est que le développeur fasse son travail, pas que la base de données autorise des valeurs déraisonnables.
Tom H
10
pas utile à l'auteur. il a explicitement exclu cette question à laquelle vous avez répondu.
usr
6
@ Chris B Behrens: je ne suis pas d'accord; le schéma de base de données fait partie de la logique métier. Le choix des tables, des relations, des champs et des types de données relève de la logique métier - et cela vaut la peine d'utiliser le SGBDR pour appliquer les règles de cette logique métier. Pour une raison, il est très rare qu'un seul niveau d'application accède à la base de données; par exemple, vous pourriez avoir des outils d'importation et d'extraction de données qui contournent le niveau métier principal, ce qui signifie que vous avez vraiment besoin de la base de données pour appliquer les règles.
Vince Bowdren
1
Si vous n'avez pas besoin ou souhaitez que de longues chaînes soient stockées, il est préférable de renforcer le sens des données. Par exemple, si vous stockez un champ PostCode, laissez-vous quelqu'un entrer des centaines ou des milliers de caractères alors qu'il devrait être au maximum de 10, par exemple - la taille maximale doit être validée à tous les niveaux, client, niveau métier ET base de données. Si vous utilisez une approche Model First, comme avec C # et Entity Framework, vous pouvez définir votre taille maximale au niveau du modèle et l'appliquer à la base de données, à la logique métier et à la validation client (avec la validation jquery, par exemple). N'utilisez nvarchar (max) que si c'est vraiment nécessaire
Peter Kerr
21

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.

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
la source
4
C'est intéressant. Sur ma boîte, il semble que le MAX soit 4 fois plus lent.
stucampbell
4
Nouveaux résultats sur SQL Server 2012: 10 est deux fois plus lent que 4k et MAX est 5,5 fois plus lent que 4k.
cassandrad
1
La majorité du temps est la conversion implicite de varchar en nvarchar (max). Essayez celui-ci: DECLARE \ @SomeString NVARCHAR (MAX), \ @abc NVARCHAR (max) = N'ABC ', \ @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 ()); J'ai dû insérer des variables \ avant pour le publier.
Kvasi
4
SQL Server 2014 sur SSD: 150, 156, 716 (10, 4000, MAX).
Maxim
2
Merci d'avoir ajouté de vrais chiffres à cette discussion. Nous oublions souvent que la création d'un scénario de test est le moyen le plus rapide de comprendre.
David C
13

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.

Alex
la source
8

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.

Nick Kavadias
la source
1
Cette même restriction est en place pour le type de champ TEXT, vous devez donc toujours utiliser VARCHAR (MAX) au lieu de TEXT.
Will Shaver
nous n'avons pas pu reconstruire notre index cluster pour cette raison. cela nous a coûté beaucoup d'espace disque jusqu'à ce que nous puissions extraire la colonne dans sa propre table (nous ne pouvions pas nous permettre de verrouiller la table pendant plus de 7 secondes)
Choco Smith
4

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.

mattruma
la source
2
Alors pourquoi ne pas simplement développer sur le plus petit dénominateur commun?
binki
4

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:

Utilisez varchar lorsque les tailles des entrées de données de colonne varient considérablement. Utilisez varchar (max) lorsque les tailles des entrées de données de colonne varient considérablement et que la taille peut dépasser 8 000 octets.

Il y a une discussion intéressante sur la question ici .

RichardOD
la source
2
Pour des choses comme les numéros de téléphone, je serais beaucoup plus disposé à utiliser un champ char au lieu de varchar. Tant que vous maintenez une norme dans votre stockage et que vous n'avez pas à vous soucier des numéros de téléphone de différents pays, vous ne devriez jamais avoir besoin d'un champ variable pour quelque chose comme un numéro de téléphone (10 sans formatage) ou un code postal (5 ou 9-10 si vous ajoutez les quatre derniers chiffres), etc.
TheTXI
Je parlais de numéros de téléphone dont la longueur peut varier. Je devrais peut-être mettre cela dans la réponse. Tout ce qui est de longueur fixe, j'utiliserais un champ char.
RichardOD
Ou peut-être devrais-je dire dans mon commentaire nchar ou char. :-)
RichardOD
2
Le nombre de caractères dans un numéro de téléphone est à peu près une exigence commerciale. Si vous deviez stocker le code standard international avec le numéro, il pourrait être supérieur à 10. Ou, une partie du monde pourrait avoir plus de 10 chiffres pour un numéro de téléphone. Imaginez le cas de la transition IPV4 à IPV6. Personne n'aurait soutenu que nous avions besoin de plus de 12 chiffres au cours des bons vieux jours IPV4. Il peut ne pas tenir bon si IPV6 devient répandu. Il s'agit là encore d'un changement de règle métier sur une période de temps. Comme il est dit, le changement est la seule chose constante à laquelle nous pouvons nous attendre :)
pencilslate
2
Soyez prudent en supposant que vous savez combien de caractères peuvent être dans un champ de numéro de téléphone, ou quel genre de caractères ils seront. À moins que le système n'utilise ces données pour composer (dans ce cas, vous devez être strict sur les formats), l'utilisateur peut légitimement y insérer des chaînes de manière inattendue, par exemple "0123 456 78910, demandez la réception de l'extension 45 puis transférez-la à James".
Vince Bowdren
4

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.

Tom H
la source
6
OMI, les limitations de longueur des données sont purement basées sur les règles métier, qui peuvent changer au fil du temps, à mesure que l'application se développe. La modification des règles métier au niveau de la logique métier est plus facile qu'au niveau DB. Donc, je pense que la base de données devrait être suffisamment flexible et ne devrait pas être liée à des règles commerciales telles que la longueur maximale autorisée du prénom, qui dépend beaucoup de la partie du monde dans laquelle vous
résidez
3

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.

TheTXI
la source
Je pense que l'hypothèse tacite de la part de l'OP est qu'il traite entièrement les instances 2005+ et que ses applications n'auront pas besoin de fonctionner sur les versions 2000 (ou, ack, inférieures). Je suis tout à fait d'accord avec vous s'il est nécessaire de prendre en charge les anciennes versions!
John Rudy
John Rudy: J'imagine que c'est le cas, je sais juste que j'ai rencontré moi-même ces obstacles quand je ne pensais pas que j'allais le faire.
TheTXI
En fait, c'est un problème répandu toujours avec des choses modernes en raison de SQL CE 4 qui ne prend pas en charge les types de colonnes MAX, donc l'interopérabilité est un problème.
JohnC
3

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.

Harry Cooper
la source
2

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.

WWC
la source
1

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.

Cade Roux
la source
1

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

Tony
la source
1

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.

Matt Spradley
la source
1

Mes tests ont montré qu'il existe des différences lors de la sélection.

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
la source
0

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».

orip
la source
1
Cela revient à dire que vous ne devriez pas avoir de contraintes de vérification pour vous assurer que l'âge d'une personne n'est pas un nombre négatif.
Jonathan Allen
Je vois une différence entre l'exactitude des données et l'optimisation des performances.
orip
0

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

            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]

Ou ca?

            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]
carlos martini
la source
3
Je préférerais que la logique métier me dise qu'un nom de société peut contenir au maximum 50 caractères plutôt que de se fier à une table de base de données pour ces informations.
Khan
Je suis d'accord avec Jeff. Je ne pense pas que le magasin de persistance soit le bon endroit pour définir vos règles commerciales. Et dans une architecture en couches, votre interface utilisateur ne connaîtrait même pas la couche de persistance.
stucampbell
À moins bien sûr que vous n'utilisiez une valeur limitée à une taille spécifique, par exemple le code ISO pour le pays.
Ben
2
Qu'est-ce que cela a à voir avec une table def? Vous pouvez toujours avoir une logique métier. Je pense que votre argument n'a aucun sens en ce qui concerne la conception d'une table. Si vous souhaitez toujours concevoir une sorte de définition dans votre couche métier, qu'il en soit ainsi. Bien que ce qui serait plus logique, c'est quand même d'utiliser un proc stocké dans la couche métier; pas une table def ??
carlos martini
1
Cela semble impopulaire, mais je suis d'accord avec Carlos, si la base de données définit une taille maximale, vous pouvez être à l'aise dans toutes les couches que vous construisez au-dessus de ce que vous devrez probablement gérer. Ceci est particulièrement important si plusieurs systèmes écrivent dans votre base de données.
Tim Abell
0

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

tsundoku
la source
0

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.

Stephen Whipp
la source
-1

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.

Dan Goldstein
la source
5
-1. Une chaîne de longueur 100 stockée dans une nvarchar(max)colonne ne prend pas plus d'espace disque que si elle se trouvait dans une nvarchar(100)colonne.
Martin Smith
Ce que vous décrivez est correct si la taille des données stockées est supérieure, mais cette question est de savoir si le type de données a des implications en termes de performances ou d'autres considérations.
-2

Cela rendra la conception de l'écran plus difficile, car vous ne pourrez plus prédire la largeur de vos contrôles.

pappes
la source