J'essaie de comprendre la meilleure façon de décider de la taille des colonnes varchar, à la fois du point de vue du stockage et des performances.
Performance
D'après mes recherches, il semble que varchar (max) ne devrait être utilisé que si vous en avez vraiment besoin; c'est-à-dire, si la colonne doit contenir plus de 8000 caractères, une raison étant le manque d'indexation (bien que je sois un peu méfiant à propos de l'indexation sur les champs varchar en général. ) et la compression (plus un problème de stockage). En fait, en général, les gens semblent recommander d'utiliser uniquement ce dont vous avez besoin, lorsque vous faites varchar (n) .... le surdimensionnement est mauvais, car les requêtes doivent prendre en compte la taille maximale possible. Mais il a également été déclaré que le moteur utiliserait la moitié de la taille indiquée comme estimation de la taille réelle moyenne des données. Cela impliquerait que l'on devrait déterminer, à partir des données, quelle est la taille moyenne, la doubler et l'utiliser comme n. Pour les données avec une variabilité très faible mais non nulle, cela implique jusqu'à un surdimensionnement 2x sur la taille maximale, ce qui semble beaucoup, mais peut-être pas? Des informations seraient appréciées.
Stockage
Après avoir lu comment fonctionne le stockage en ligne ou hors ligne, et en gardant à l'esprit que le stockage réel est limité aux données réelles, il me semble en fait que le choix de n a peu ou pas d'incidence sur le stockage (en plus de s'assurer qu'il est assez grand pour tout contenir). Même l'utilisation de varchar (max) ne devrait pas avoir d'impact sur le stockage. Au lieu de cela, un objectif peut être de limiter la taille réelle de chaque ligne de données à ~ 8 000 octets si possible. Est-ce une lecture précise des choses?
Contexte
Certaines de nos données clients fluctuent un peu, donc nous faisons généralement des colonnes juste un peu plus larges que nécessaire, disons 15-20% plus grandes, pour ces colonnes. Je me demandais s'il y avait d'autres considérations spéciales; par exemple, quelqu'un avec qui je travaille m'a dit d'utiliser 2 ^ n - 1 tailles (je n'ai cependant trouvé aucune preuve que ce soit une chose ....)
Je parle de la création de table initiale. Un client nous dira qu'il va commencer à nous envoyer une nouvelle table, et envoyer des échantillons de données (ou tout simplement le premier ensemble de données de production), que nous examinons et créer un tableau de notre côté pour contenir les données. Nous voulons faire le tableau de notre côté pour gérer les importations futures ainsi que ce qui est dans l'échantillon. Mais, certaines lignes sont appelées à s'allonger, nous les remplissons donc.
La question est de savoir combien et existe-t-il des directives techniques?
Quel que soit le type de données spécifique, vous devez pouvoir stocker toutes les demandes d'application à stocker. Vous ne pouvez pas spécifier quelque chose de plus petit que la taille maximale de ce qui sera réellement enregistré.
Vous n'avez pas non plus besoin, ni ne souhaitez, de spécifier une longueur de colonne supérieure à la taille réelle maximale qui sera stockée pour diverses raisons: allocation de mémoire de requête, remplissant potentiellement la taille de ligne maximale et ne laissant aucune place pour l'ajout de colonnes dans l'avenir, etc.
Vrai, la chaîne de longueur variable et les colonnes binaires n'ont pas l'implication de stockage que les types de données de longueur fixe (chaîne/binaire/numérique/date/etc) font (bien que certaines de ces implications puissent être annulées via la compression des données ou l'utilisation du SPARSE
option de définition de colonne). Cependant, comme vous l'avez souligné, même s'il n'y a pas d'implication directe de stockage, il existe toujours une implication de performance de surestimation de la mémoire requise pour les requêtes.
Soyez raisonnable. N'utilisez que ce dont vous avez besoin. Des considérations peuvent être prises en compte s'il existe une forte probabilité que la longueur de la colonne doive augmenter dans un avenir proche, mais gardez à l'esprit qu'il est plus facile d'agrandir la taille d'une colonne que de réduire la taille. Oui, certains travaux seront impliqués, mais comme ce travail est simplement "potentiel", alors que les implications de surdimensionnement sont "réelles", il est souvent préférable de définir des colonnes en fonction de ce dont vous avez réellement besoin, pas de ce que vous avez peut-être un peu -sorta pense que vous pourriez avoir besoin à l'avenir. De nombreux changements dont il est question ne se produisent jamais, et souvent les changements nécessaires ne sont pas prévisibles. Allez avec ce que vous savez.
Au lieu de cela, un objectif peut être de limiter la taille réelle de chaque ligne de données à ~ 8 000 octets si possible.
Je ne sais pas exactement où vous voulez en venir. SQL Server vous limitera physiquement à un peu plus de 8 000 octets. Utilisation des types de LOB - VARCHAR(MAX)
, NVARCHAR(MAX)
, VARBINARY(MAX)
, XML
et les obsolètes TEXT
, NTEXT
et IMAGE
types - permettent d'aller au-delà de cette limite de taille de page initiale, mais cela est uniquement dû au placement d'un pointeur (16 octets ou plus, selon le type et selon la taille de la valeur étant stocké hors ligne lors de l'utilisation des types MAX
). La limite physique réelle de la page de données n'a pas changé.
Votre objectif doit être d'utiliser le moins d'espace physique pour stocker ce que l'application/l'entreprise doit stocker sans casser ou tronquer, de sorte que la valeur incomplète perd son sens ou cause des problèmes en aval. Si vous avez besoin de stocker un truc de 12 000 caractères, utilisez VARCHAR(MAX)
car c'est ce qui est nécessaire. Si vous stockez un numéro de téléphone ou un code postal/Zip, il serait imprudent d'utiliser VARCHAR(100)
, et irresponsable d'utiliser VARCHAR(MAX)
.
certaines de nos données clients fluctuent un peu, donc nous faisons généralement des colonnes juste un peu plus larges que nécessaire, disons 15-20% plus grandes, pour ces colonnes. Je me demandais s'il y avait d'autres considérations spéciales;
Tous les systèmes n'ont-ils pas au moins certaines données qui fluctuent? Tout système qui enregistre le nom d'une personne serait admissible, non? Il y a un écart assez important dans la longueur des noms. Et puis vous avez quelqu'un comme Prince aller changer son nom en symbole et maintenant vous avez un problème entièrement différent qui n'est pas de longueur. C'est comme ça que les choses sont.
Mais, pour jouer l'avocat du diable pendant un moment: comment la valeur "15-20% plus grande que ce qui est nécessaire" ne peut-elle pas être la valeur réelle nécessaire? Supposons qu'il y ait une discussion sur l'ajout d'une nouvelle colonne, et que quelqu'un suggère 50 caractères, puis quelqu'un d'autre dit: "Eh bien, 20% de plus, c'est 60 alors faisons 60 parce que quelqu'un pourrait en avoir 60". S'il est vrai qu'un client peut en avoir 60, alors 60 est, et a toujours été, la valeur nécessaire réelle, et 50 était erronée tout le temps.
Bien sûr, cela aiderait s'il y avait une indication quant à la source des données car:
VARCHAR
et que vous vous plaignez qu'il gâche les caractères Unicode qui sont maintenant autorisés dans les noms de domaine, alors il devait être NVARCHAR
), maisProductSKU
il vaut mieux être assez grand pour contenir toutes les références du client.Je parle de la création de table initiale. Un client nous dira qu'il va commencer à nous envoyer une nouvelle table, et envoyer des échantillons de données (ou tout simplement le premier jeu de données de production), que nous examinons et créer un tableau de notre côté pour contenir les données. Nous voulons faire le tableau de notre côté pour gérer les importations futures ainsi que ce qui est dans l'échantillon. Mais, certaines lignes sont appelées à s'allonger, nous les remplissons donc. La question est de savoir combien et existe-t-il des directives techniques?
Vous faites beaucoup d'hypothèses ici. Bien sûr, certains champs pourraient s'agrandir. Mais là encore, ils pourraient ne pas. Ou, certains pourraient devenir plus petits. Certains peuvent passer de non-Unicode à être Unicode (une fois qu'ils se rendent compte que le monde devient plus petit et on ne peut pas supposer que les noms de famille n'auront que des caractères de base ASCII/US English caractères). Ou , ils pourraient arrêter d'envoyer un champ. Ou ils pourraient ajouter un ou plusieurs champs à l'avenir. N'importe quelle combinaison de cela et d'autres choses. Alors pourquoi se concentrer uniquement sur les colonnes VARCHAR
? Et si elles envoient actuellement un INT
valeur et dans un an ou deux, ils atteignent la valeur maximale et commencent à envoyer un BIGINT
? Et s'ils ont un champ "status" avec des valeurs de 0 à 5. Allez-vous simplement supposer INT
qui est "rembourré" car il permet la croissance, mais devrait probablement être TINYINT
?
La seule chose que vous pouvez prédire en toute sécurité est qu'essayer de prédire comment les données de vos clients vont changer sera plus souvent erroné que correct. Et être correct est une question de chance/coïncidence (sinon la chance, alors allez jouer à la loterie;).
La ligne directrice est donc:
Vous avez déjà des exemples de données, parfait. Mais n'oubliez pas que vous disposez également des coordonnées de votre client: téléphone et/ou email. Contactez-les! Demandez-leur leurs spécifications de données (tout comme votre système, les données actuellement dans leur système peuvent avoir une longueur maximale de 35, mais leur système l'a définie comme VARCHAR(50)
, et leur système acceptera jusqu'à cette longueur , auquel cas vous devez utiliser 50). Et demandez-leur s'ils ont des plans à court terme pour changer et de ces types de données (type et/ou taille).